Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit f9e0439

Browse files
author
Nate McMaster
committed
Add CookieBuilder
1 parent 9bf94d3 commit f9e0439

File tree

3 files changed

+140
-1
lines changed

3 files changed

+140
-1
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace Microsoft.AspNetCore.Http
7+
{
8+
/// <summary>
9+
/// Defines settings used to create a cookie.
10+
/// </summary>
11+
public class CookieBuilder
12+
{
13+
/// <summary>
14+
/// The name of the cookie.
15+
/// </summary>
16+
public virtual string Name { get; set; }
17+
18+
/// <summary>
19+
/// The cookie path.
20+
/// </summary>
21+
/// <remarks>
22+
/// Determines the value that will set on <seealso cref="CookieOptions.Path"/>.
23+
/// </remarks>
24+
public virtual string Path { get; set; }
25+
26+
/// <summary>
27+
/// The domain to associate the cookie with.
28+
/// </summary>
29+
/// <remarks>
30+
/// Determines the value that will set on <seealso cref="CookieOptions.Domain"/>.
31+
/// </remarks>
32+
public virtual string Domain { get; set; }
33+
34+
/// <summary>
35+
/// Indicates whether a cookie is accessible by client-side script.
36+
/// </summary>
37+
/// <remarks>
38+
/// Determines the value that will set on <seealso cref="CookieOptions.HttpOnly"/>.
39+
/// </remarks>
40+
public virtual bool HttpOnly { get; set; }
41+
42+
/// <summary>
43+
/// The SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
44+
/// </summary>
45+
/// <remarks>
46+
/// Determines the value that will set on <seealso cref="CookieOptions.SameSite"/>.
47+
/// </remarks>
48+
public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.Lax;
49+
50+
/// <summary>
51+
/// The policy that will be used to determine <seealso cref="CookieOptions.Secure"/>.
52+
/// This is determined from the <see cref="HttpContext"/> passed to <see cref="Build(HttpContext)"/>.
53+
/// </summary>
54+
public virtual CookieSecurePolicy SecurePolicy { get; set; }
55+
56+
57+
/// <summary>
58+
/// Gets or sets the lifespan of a cookie.
59+
/// </summary>
60+
public virtual TimeSpan? Expiration { get; set; }
61+
62+
/// <summary>
63+
/// Creates the cookie options from the given <paramref name="context"/>.
64+
/// </summary>
65+
/// <param name="context">The <see cref="HttpContext"/>.</param>
66+
/// <returns>The cookie options.</returns>
67+
public virtual CookieOptions Build(HttpContext context) => Build(context, DateTimeOffset.Now);
68+
69+
/// <summary>
70+
/// Creates the cookie options from the given <paramref name="context"/> with an expiration based on <paramref name="expiresFrom"/> and <see cref="Expiration"/>.
71+
/// </summary>
72+
/// <param name="context">The <see cref="HttpContext"/>.</param>
73+
/// <param name="expiresFrom">The time to use as the base for computing <seealso cref="CookieOptions.Expires" />.</param>
74+
/// <returns>The cookie options.</returns>
75+
public virtual CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
76+
{
77+
if (context == null)
78+
{
79+
throw new ArgumentNullException(nameof(context));
80+
}
81+
82+
return new CookieOptions
83+
{
84+
Path = Path ?? "/",
85+
SameSite = SameSite,
86+
HttpOnly = HttpOnly,
87+
Domain = Domain,
88+
Secure = SecurePolicy == CookieSecurePolicy.Always || (SecurePolicy == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
89+
Expires = Expiration.HasValue ? expiresFrom.Add(Expiration.Value) : default(DateTimeOffset?)
90+
};
91+
}
92+
}
93+
}

src/Microsoft.AspNetCore.Http.Features/CookieOptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public CookieOptions()
4242
/// <returns>true to transmit the cookie only over an SSL connection (HTTPS); otherwise, false.</returns>
4343
public bool Secure { get; set; }
4444

45-
4645
/// <summary>
4746
/// Gets or sets the value for the SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
4847
/// </summary>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Xunit;
6+
7+
namespace Microsoft.AspNetCore.Http.Abstractions.Tests
8+
{
9+
public class CookieBuilderTests
10+
{
11+
[Theory]
12+
[InlineData(CookieSecurePolicy.Always, false, true)]
13+
[InlineData(CookieSecurePolicy.Always, true, true)]
14+
[InlineData(CookieSecurePolicy.SameAsRequest, true, true)]
15+
[InlineData(CookieSecurePolicy.SameAsRequest, false, false)]
16+
[InlineData(CookieSecurePolicy.None, true, false)]
17+
[InlineData(CookieSecurePolicy.None, false, false)]
18+
public void ConfiguresSecurePolicy(CookieSecurePolicy policy, bool requestIsHttps, bool secure)
19+
{
20+
var builder = new CookieBuilder
21+
{
22+
SecurePolicy = policy
23+
};
24+
var context = new DefaultHttpContext();
25+
context.Request.IsHttps = requestIsHttps;
26+
var options = builder.Build(context);
27+
28+
Assert.Equal(secure, options.Secure);
29+
}
30+
31+
[Fact]
32+
public void ComputesExpiration()
33+
{
34+
Assert.Null(new CookieBuilder().Build(new DefaultHttpContext()).Expires);
35+
36+
var now = DateTimeOffset.Now;
37+
var options = new CookieBuilder { Expiration = TimeSpan.FromHours(1) }.Build(new DefaultHttpContext(), now);
38+
Assert.Equal(now.AddHours(1), options.Expires);
39+
}
40+
41+
[Fact]
42+
public void CookieBuilderPreservesDefaultPath()
43+
{
44+
Assert.Equal(new CookieOptions().Path, new CookieBuilder().Build(new DefaultHttpContext()).Path);
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)