|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.AspNetCore.Http.Abstractions;
namespace Microsoft.AspNetCore.Http;
/// <summary>
/// Defines settings used to create a cookie.
/// </summary>
public class CookieBuilder
{
private string? _name;
private List<string>? _extensions;
/// <summary>
/// The name of the cookie.
/// </summary>
public virtual string? Name
{
get => _name;
set => _name = !string.IsNullOrEmpty(value)
? value
: throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(value));
}
/// <summary>
/// The cookie path.
/// </summary>
/// <remarks>
/// Determines the value that will be set for <see 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 be set for <see cref="CookieOptions.Domain"/>.
/// </remarks>
public virtual string? Domain { get; set; }
/// <summary>
/// Indicates whether a cookie is inaccessible by client-side script. The default value is <c>false</c>
/// but specific components may use a different value.
/// </summary>
/// <remarks>
/// Determines the value that will be set on <see cref="CookieOptions.HttpOnly"/>.
/// </remarks>
public virtual bool HttpOnly { get; set; }
/// <summary>
/// The SameSite attribute of the cookie. The default value is <see cref="SameSiteMode.Unspecified"/>
/// but specific components may use a different value.
/// </summary>
/// <remarks>
/// Determines the value that will be set for <see cref="CookieOptions.SameSite"/>.
/// </remarks>
public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.Unspecified;
/// <summary>
/// The policy that will be used to determine <see cref="CookieOptions.Secure"/>.
/// This is determined from the <see cref="HttpContext"/> passed to <see cref="Build(HttpContext, DateTimeOffset)"/>.
/// </summary>
public virtual CookieSecurePolicy SecurePolicy { get; set; }
/// <summary>
/// Gets or sets the lifespan of a cookie.
/// </summary>
public virtual TimeSpan? Expiration { get; set; }
/// <summary>
/// Gets or sets the max-age for the cookie.
/// </summary>
public virtual TimeSpan? MaxAge { get; set; }
/// <summary>
/// Indicates if this cookie is essential for the application to function correctly. If true then
/// consent policy checks may be bypassed. The default value is <c>false</c>
/// but specific components may use a different value.
/// </summary>
public virtual bool IsEssential { get; set; }
/// <summary>
/// Gets a collection of additional values to append to the cookie.
/// </summary>
public IList<string> Extensions
{
get => _extensions ??= new List<string>();
}
/// <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 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 <see cref="CookieOptions.Expires" />.</param>
/// <returns>The cookie options.</returns>
public virtual CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
{
ArgumentNullException.ThrowIfNull(context);
var options = new CookieOptions
{
Path = Path ?? "/",
SameSite = SameSite,
HttpOnly = HttpOnly,
MaxAge = MaxAge,
Domain = Domain,
IsEssential = IsEssential,
Secure = SecurePolicy == CookieSecurePolicy.Always || (SecurePolicy == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
Expires = Expiration.HasValue ? expiresFrom.Add(Expiration.GetValueOrDefault()) : default(DateTimeOffset?)
};
if (_extensions?.Count > 0)
{
foreach (var extension in _extensions)
{
options.Extensions.Add(extension);
}
}
return options;
}
}
|