Skip to content

Commit

Permalink
Add SameSite support for NancyCookies
Browse files Browse the repository at this point in the history
SameSite property will accept Lax, Strict and None values.

Fix NancyFx#3002
  • Loading branch information
Ali Bahrami committed Mar 10, 2020
1 parent 11ac0fe commit 60e7596
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
7 changes: 6 additions & 1 deletion src/Nancy/Cookies/INancyCookie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,10 @@ public interface INancyCookie
/// Whether the cookie is secure (i.e. HTTPS only)
/// </summary>
bool Secure { get; }

/// <summary>
/// Wheather the cookie is same site
/// </summary>
SameSite? SameSite { get; }
}
}
}
22 changes: 17 additions & 5 deletions src/Nancy/Cookies/NancyCookie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public NancyCookie(string name, string value)
/// <param name="value">The value of the cookie.</param>
/// <param name="expires">The expiration date of the cookie. Can be <see langword="null" /> if it should expire at the end of the session.</param>
public NancyCookie(string name, string value, DateTime expires)
: this(name, value, false, false, expires)
: this(name, value, false, false, expires, null)
{
}

Expand All @@ -42,7 +42,7 @@ public NancyCookie(string name, string value, DateTime expires)
/// <param name="value">The value of the cookie.</param>
/// <param name="httpOnly">Whether the cookie is http only.</param>
public NancyCookie(string name, string value, bool httpOnly)
: this(name, value, httpOnly, false, null)
: this(name, value, httpOnly, false, null, null)
{
}

Expand All @@ -55,7 +55,7 @@ public NancyCookie(string name, string value, bool httpOnly)
/// <param name="httpOnly">Whether the cookie is http only.</param>
/// <param name="secure">Whether the cookie is secure (i.e. HTTPS only).</param>
public NancyCookie(string name, string value, bool httpOnly, bool secure)
: this(name, value, httpOnly, secure, null)
: this(name, value, httpOnly, secure, null, null)
{
}

Expand All @@ -68,13 +68,15 @@ public NancyCookie(string name, string value, bool httpOnly, bool secure)
/// <param name="httpOnly">Whether the cookie is http only.</param>
/// <param name="secure">Whether the cookie is secure (i.e. HTTPS only).</param>
/// <param name="expires">The expiration date of the cookie. Can be <see langword="null" /> if it should expire at the end of the session.</param>
public NancyCookie(string name, string value, bool httpOnly, bool secure, DateTime? expires)
/// <param name="sameSite">The same site attribute of the cookie. Can be <see langword="null" />.</param>
public NancyCookie(string name, string value, bool httpOnly, bool secure, DateTime? expires, SameSite? sameSite = null)
{
this.Name = name;
this.Value = value;
this.HttpOnly = httpOnly;
this.Secure = secure;
this.Expires = expires;
this.SameSite = sameSite;
}

/// <summary>
Expand Down Expand Up @@ -135,6 +137,11 @@ public string EncodedValue
/// </summary>
public bool Secure { get; private set; }

/// <summary>
/// Wheather the cookie is same site
/// </summary>
public SameSite? SameSite { get; set; }

/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
Expand Down Expand Up @@ -169,7 +176,12 @@ public override string ToString()
sb.Append("; HttpOnly");
}

if(SameSite.HasValue)
{
sb.Append("; samesite=").Append(SameSite.ToString());
}

return sb.ToString();
}
}
}
}
29 changes: 29 additions & 0 deletions src/Nancy/Cookies/SameSite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Nancy.Cookies
{
/// <summary>
/// Represents the SameSite for NancyCookie
/// </summary>
public enum SameSite
{
/// <summary>
/// If the value is invalid, the cookie will only be sent along with
/// "same-site" requests. If the value is "Lax", the cookie will be
/// sent with "same-site" requests, and with "cross-site" top-level navigations
/// </summary>
Lax = 0,

/// <summary>
/// If you set SameSite to Strict, your cookie will only be sent in a
/// first-party context. In user terms, the cookie will only be sent
/// if the site for the cookie matches the site currently shown in
/// the browser's URL bar.
/// </summary>
Strict,

/// <summary>
/// Cookies with SameSite=None must also specify Secure,
/// meaning they require a secure context.
/// </summary>
None
}
}
12 changes: 11 additions & 1 deletion test/Nancy.Tests/Unit/NancyCookieFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ public void Should_encode_value_if_necessary()
result.ShouldEqual("Value+with+spaces");
}

[Fact]
public void Should_add_same_site_if_set()
{
// When
var cookie = new NancyCookie("leto", "worm") { SameSite = SameSite.Lax }.ToString();

// Then
cookie.ShouldEqual("leto=worm; path=/; samesite=Lax");
}

public static string GetInvariantAbbreviatedMonthName(DateTime dateTime)
{
return CultureInfo.InvariantCulture.DateTimeFormat.AbbreviatedMonthNames[dateTime.Month - 1];
Expand All @@ -173,4 +183,4 @@ public static string GetInvariantAbbreviatedWeekdayName(DateTime dateTime)
}

}
}
}

0 comments on commit 60e7596

Please sign in to comment.