Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions src/Microsoft.AspNetCore.Http.Abstractions/CookieBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Microsoft.AspNetCore.Http
{
/// <summary>
/// Defines settings used to create a cookie.
/// </summary>
public class CookieBuilder
{
/// <summary>
/// The name of the cookie.
/// </summary>
public virtual string Name { get; set; }

/// <summary>
/// The cookie path.
/// </summary>
/// <remarks>
/// Determines the value that will set on <seealso cref="CookieOptions.Path"/>.
/// </remarks>
public virtual string Path { get; set; }

/// <summary>
/// The domain to associate the cookie with.
/// </summary>
/// <remarks>
/// Determines the value that will set on <seealso cref="CookieOptions.Domain"/>.
/// </remarks>
public virtual string Domain { get; set; }

/// <summary>
/// Indicates whether a cookie is accessible by client-side script.
/// </summary>
/// <remarks>
/// Determines the value that will set on <seealso cref="CookieOptions.HttpOnly"/>.
/// </remarks>
public virtual bool HttpOnly { get; set; }

/// <summary>
/// The SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
/// </summary>
/// <remarks>
/// Determines the value that will set on <seealso cref="CookieOptions.SameSite"/>.
/// </remarks>
public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.Lax;

/// <summary>
/// The policy that will be used to determine <seealso cref="CookieOptions.Secure"/>.
/// This is determined from the <see cref="HttpContext"/> passed to <see cref="Build(HttpContext)"/>.
/// </summary>
public virtual CookieSecurePolicy SecurePolicy { get; set; }


/// <summary>
/// Gets or sets the lifespan of a cookie.
/// </summary>
public virtual TimeSpan? Expiration { get; set; }

/// <summary>
/// Creates the cookie options from the given <paramref name="context"/>.
/// </summary>
/// <param name="context">The <see cref="HttpContext"/>.</param>
/// <returns>The cookie options.</returns>
public virtual CookieOptions Build(HttpContext context) => Build(context, DateTimeOffset.Now);

/// <summary>
/// Creates the cookie options from the given <paramref name="context"/> with an expiration based on <paramref name="expiresFrom"/> and <see cref="Expiration"/>.
/// </summary>
/// <param name="context">The <see cref="HttpContext"/>.</param>
/// <param name="expiresFrom">The time to use as the base for computing <seealso cref="CookieOptions.Expires" />.</param>
/// <returns>The cookie options.</returns>
public virtual CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

return new CookieOptions
{
Path = Path ?? "/",
SameSite = SameSite,
HttpOnly = HttpOnly,
Domain = Domain,
Secure = SecurePolicy == CookieSecurePolicy.Always || (SecurePolicy == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
Expires = Expiration.HasValue ? expiresFrom.Add(Expiration.Value) : default(DateTimeOffset?)
};
}
}
}
1 change: 0 additions & 1 deletion src/Microsoft.AspNetCore.Http.Features/CookieOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public CookieOptions()
/// <returns>true to transmit the cookie only over an SSL connection (HTTPS); otherwise, false.</returns>
public bool Secure { get; set; }


/// <summary>
/// Gets or sets the value for the SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Lax"/>
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Xunit;

namespace Microsoft.AspNetCore.Http.Abstractions.Tests
{
public class CookieBuilderTests
{
[Theory]
[InlineData(CookieSecurePolicy.Always, false, true)]
[InlineData(CookieSecurePolicy.Always, true, true)]
[InlineData(CookieSecurePolicy.SameAsRequest, true, true)]
[InlineData(CookieSecurePolicy.SameAsRequest, false, false)]
[InlineData(CookieSecurePolicy.None, true, false)]
[InlineData(CookieSecurePolicy.None, false, false)]
public void ConfiguresSecurePolicy(CookieSecurePolicy policy, bool requestIsHttps, bool secure)
{
var builder = new CookieBuilder
{
SecurePolicy = policy
};
var context = new DefaultHttpContext();
context.Request.IsHttps = requestIsHttps;
var options = builder.Build(context);

Assert.Equal(secure, options.Secure);
}

[Fact]
public void ComputesExpiration()
{
Assert.Null(new CookieBuilder().Build(new DefaultHttpContext()).Expires);

var now = DateTimeOffset.Now;
var options = new CookieBuilder { Expiration = TimeSpan.FromHours(1) }.Build(new DefaultHttpContext(), now);
Assert.Equal(now.AddHours(1), options.Expires);
}

[Fact]
public void CookieBuilderPreservesDefaultPath()
{
Assert.Equal(new CookieOptions().Path, new CookieBuilder().Build(new DefaultHttpContext()).Path);
}
}
}