From 1eb7f9e03215fb2fd3e361881b20ecee205f50f1 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Wed, 5 Jul 2017 10:19:13 -0700 Subject: [PATCH] Add CookieBuilder to CookieTempDataProviderOptions and obsolete duplicate API (#6472) --- .../CookieTempDataProviderOptions.cs | 49 ++++++++++++++++++- .../ViewFeatures/CookieTempDataProvider.cs | 20 +++----- .../CookieTempDataProviderTest.cs | 17 +++++-- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/CookieTempDataProviderOptions.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/CookieTempDataProviderOptions.cs index 281c10e0d7..f6140e4212 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/CookieTempDataProviderOptions.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/CookieTempDataProviderOptions.cs @@ -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; @@ -11,21 +12,65 @@ namespace Microsoft.AspNetCore.Mvc /// public class CookieTempDataProviderOptions { + private CookieBuilder _cookieBuilder = new CookieBuilder + { + Name = CookieTempDataProvider.CookieName, + HttpOnly = true, + SameSite = SameSiteMode.Strict, + SecurePolicy = CookieSecurePolicy.SameAsRequest, + }; + /// + /// + /// Determines the settings used to create the cookie in . + /// + /// + /// defaults to . + /// defaults to . + /// defaults to true + /// + /// + public CookieBuilder Cookie + { + get => _cookieBuilder; + set => _cookieBuilder = value ?? throw new ArgumentNullException(nameof(value)); + } + + #region Obsolete API + /// + /// + /// This property is obsolete and will be removed in a future version. The recommended alternative is on . + /// + /// /// The path set on the cookie. If set to null, the "path" attribute on the cookie is set to the current /// request's value. If the value of is /// null or empty, then the "path" attribute is set to the value of . + /// /// - 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; } /// + /// + /// This property is obsolete and will be removed in a future version. The recommended alternative is on . + /// + /// /// The domain set on a cookie. Defaults to null. + /// /// - 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; } /// + /// + /// This property is obsolete and will be removed in a future version. The recommended alternative is on . + /// + /// /// The name of the cookie which stores TempData. Defaults to . + /// /// + [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 } } diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/CookieTempDataProvider.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/CookieTempDataProvider.cs index 4221e94014..726b6bd83c 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/CookieTempDataProvider.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/CookieTempDataProvider.cs @@ -39,9 +39,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures 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); @@ -60,13 +60,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures 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); @@ -75,19 +69,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures 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 { diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/CookieTempDataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/CookieTempDataProviderTest.cs index 902c17da28..dc9ad123cf 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/CookieTempDataProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewFeatures/CookieTempDataProviderTest.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public void SaveTempData_UsesCookieName_FromOptions() { // Arrange - var exepectedCookieName = "TestCookieName"; + var expectedCookieName = "TestCookieName"; var values = new Dictionary(); values.Add("int", 10); @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures var expectedDataInCookie = Base64UrlTextEncoder.Encode(expectedDataToProtect); var tempDataProvider = GetProvider(dataProtector: null, options: new CookieTempDataProviderOptions() { - CookieName = exepectedCookieName + Cookie = { Name = expectedCookieName } }); var responseCookies = new MockResponseCookieCollection(); @@ -46,8 +46,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures 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); } @@ -230,7 +230,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures 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