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

Add CookieBuilder to CookieTempDataProviderOptions and obsolete duplicate API #6472

Merged
merged 1 commit into from
Jul 5, 2017
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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 Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ViewFeatures;

Expand All @@ -11,21 +12,65 @@ namespace Microsoft.AspNetCore.Mvc
/// </summary>
public class CookieTempDataProviderOptions
{
private CookieBuilder _cookieBuilder = new CookieBuilder
{
Name = CookieTempDataProvider.CookieName,
HttpOnly = true,
SameSite = SameSiteMode.Strict,
SecurePolicy = CookieSecurePolicy.SameAsRequest,
};

/// <summary>
/// <para>
/// Determines the settings used to create the cookie in <see cref="CookieTempDataProvider"/>.
/// </para>
/// <para>
/// <see cref="CookieBuilder.SameSite"/> defaults to <see cref="SameSiteMode.Strict"/>.
/// <see cref="CookieBuilder.SecurePolicy"/> defaults to <see cref="CookieSecurePolicy.SameAsRequest" />.
/// <see cref="CookieBuilder.HttpOnly"/> defaults to <c>true</c>
/// </para>
/// </summary>
public CookieBuilder Cookie
{
get => _cookieBuilder;
set => _cookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
}

#region Obsolete API
/// <summary>
/// <para>
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Path"/> on <see cref="Cookie"/>.
/// </para>
/// <para>
/// The path set on the cookie. If set to <c>null</c>, the "path" attribute on the cookie is set to the current
/// request's <see cref="HttpRequest.PathBase"/> value. If the value of <see cref="HttpRequest.PathBase"/> is
/// <c>null</c> or empty, then the "path" attribute is set to the value of <see cref="CookieOptions.Path"/>.
/// </para>
/// </summary>
public string Path { get; set; }
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Path) + ".")]
public string Path { get => Cookie.Path; set => Cookie.Path = value; }

/// <summary>
/// <para>
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Domain"/> on <see cref="Cookie"/>.
/// </para>
/// <para>
/// The domain set on a cookie. Defaults to <c>null</c>.
/// </para>
/// </summary>
public string Domain { get; set; }
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Domain) + ".")]
public string Domain { get => Cookie.Domain; set => Cookie.Domain = value; }

/// <summary>
/// <para>
/// This property is obsolete and will be removed in a future version. The recommended alternative is <seealso cref="CookieBuilder.Name"/> on <see cref="Cookie"/>.
/// </para>
/// <para>
/// The name of the cookie which stores TempData. Defaults to <see cref="CookieTempDataProvider.CookieName"/>.
/// </para>
/// </summary>
[Obsolete("This property is obsolete and will be removed in a future version. The recommended alternative is " + nameof(Cookie) + "." + nameof(CookieBuilder.Name) + ".")]
public string CookieName { get; set; } = CookieTempDataProvider.CookieName;
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public IDictionary<string, object> LoadTempData(HttpContext context)
throw new ArgumentNullException(nameof(context));
}

if (context.Request.Cookies.ContainsKey(_options.CookieName))
if (context.Request.Cookies.ContainsKey(_options.Cookie.Name))
{
var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.CookieName);
var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.Cookie.Name);
if (!string.IsNullOrEmpty(encodedValue))
{
var protectedData = Base64UrlTextEncoder.Decode(encodedValue);
Expand All @@ -60,13 +60,7 @@ public void SaveTempData(HttpContext context, IDictionary<string, object> values
throw new ArgumentNullException(nameof(context));
}

var cookieOptions = new CookieOptions()
{
Domain = string.IsNullOrEmpty(_options.Domain) ? null : _options.Domain,
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = context.Request.IsHttps,
};
var cookieOptions = _options.Cookie.Build(context);
SetCookiePath(context, cookieOptions);

var hasValues = (values != null && values.Count > 0);
Expand All @@ -75,19 +69,19 @@ public void SaveTempData(HttpContext context, IDictionary<string, object> values
var bytes = _tempDataSerializer.Serialize(values);
bytes = _dataProtector.Protect(bytes);
var encodedValue = Base64UrlTextEncoder.Encode(bytes);
_chunkingCookieManager.AppendResponseCookie(context, _options.CookieName, encodedValue, cookieOptions);
_chunkingCookieManager.AppendResponseCookie(context, _options.Cookie.Name, encodedValue, cookieOptions);
}
else
{
_chunkingCookieManager.DeleteCookie(context, _options.CookieName, cookieOptions);
_chunkingCookieManager.DeleteCookie(context, _options.Cookie.Name, cookieOptions);
}
}

private void SetCookiePath(HttpContext httpContext, CookieOptions cookieOptions)
{
if (!string.IsNullOrEmpty(_options.Path))
if (!string.IsNullOrEmpty(_options.Cookie.Path))
{
cookieOptions.Path = _options.Path;
cookieOptions.Path = _options.Cookie.Path;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class CookieTempDataProviderTest
public void SaveTempData_UsesCookieName_FromOptions()
{
// Arrange
var exepectedCookieName = "TestCookieName";
var expectedCookieName = "TestCookieName";
var values = new Dictionary<string, object>();
values.Add("int", 10);

Expand All @@ -30,7 +30,7 @@ public void SaveTempData_UsesCookieName_FromOptions()
var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect);
var tempDataProvider = GetProvider(dataProtector: null, options: new CookieTempDataProviderOptions()
{
CookieName = exepectedCookieName
Cookie = { Name = expectedCookieName }
});

var responseCookies = new MockResponseCookieCollection();
Expand All @@ -46,8 +46,8 @@ public void SaveTempData_UsesCookieName_FromOptions()
tempDataProvider.SaveTempData(httpContext.Object, values);

// Assert
Assert.Contains(responseCookies, (cookie) => cookie.Key == exepectedCookieName);
var cookieInfo = responseCookies[exepectedCookieName];
Assert.Contains(responseCookies, (cookie) => cookie.Key == expectedCookieName);
var cookieInfo = responseCookies[expectedCookieName];
Assert.Equal(expectedDataInCookie, cookieInfo.Value);
Assert.Equal("/", cookieInfo.Options.Path);
}
Expand Down Expand Up @@ -230,7 +230,14 @@ public void SaveTempData_CustomProviderOptions_SetsCookie_WithAppropriateCookieO
var dataProtector = new PassThroughDataProtector();
var tempDataProvider = GetProvider(
dataProtector,
new CookieTempDataProviderOptions() { Path = optionsPath, Domain = optionsDomain });
new CookieTempDataProviderOptions
{
Cookie =
{
Path = optionsPath,
Domain = optionsDomain
}
});
var responseCookies = new MockResponseCookieCollection();
var httpContext = new Mock<HttpContext>();
httpContext
Expand Down