public async Task GetRequestTokens_HeaderTokenTakensPriority_OverFormToken()
    {
        // Arrange
        var httpContext = GetHttpContext("cookie-name", "cookie-value");

        httpContext.Request.ContentType = "application/x-www-form-urlencoded";
        httpContext.Request.Form        = new FormCollection(new Dictionary <string, StringValues>
        {
            { "form-field-name", "form-value" },
        });     // header value has priority.
        httpContext.Request.Headers.Add("header-name", "header-value");

        var options = new AntiforgeryOptions
        {
            Cookie        = { Name = "cookie-name" },
            FormFieldName = "form-field-name",
            HeaderName    = "header-name",
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var tokens = await tokenStore.GetRequestTokensAsync(httpContext);

        // Assert
        Assert.Equal("cookie-value", tokens.CookieToken);
        Assert.Equal("header-value", tokens.RequestToken);
    }
    public async Task GetRequestTokens_NoHeaderToken_NonFormContentType_ReturnsNullToken()
    {
        // Arrange
        var httpContext = GetHttpContext("cookie-name", "cookie-value");

        httpContext.Request.ContentType = "application/json";

        // Will not be accessed
        httpContext.Request.Form = null !;

        var options = new AntiforgeryOptions
        {
            Cookie        = { Name = "cookie-name" },
            FormFieldName = "form-field-name",
            HeaderName    = "header-name",
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

        // Assert
        Assert.Equal("cookie-value", tokenSet.CookieToken);
        Assert.Null(tokenSet.RequestToken);
    }
    public void SaveCookieToken_SetsCookieWithApproriatePathBase(string requestPathBase, string expectedCookiePath)
    {
        // Arrange
        var token       = "serialized-value";
        var cookies     = new MockResponseCookieCollection();
        var httpContext = new Mock <HttpContext>();

        httpContext
        .Setup(hc => hc.Response.Cookies)
        .Returns(cookies);
        httpContext
        .SetupGet(hc => hc.Request.PathBase)
        .Returns(requestPathBase);
        httpContext
        .SetupGet(hc => hc.Request.Path)
        .Returns("/index.html");
        var options = new AntiforgeryOptions
        {
            Cookie = { Name = _cookieName }
        };
        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        tokenStore.SaveCookieToken(httpContext.Object, token);

        // Assert
        Assert.Equal(1, cookies.Count);
        Assert.NotNull(cookies);
        Assert.Equal(_cookieName, cookies.Key);
        Assert.Equal("serialized-value", cookies.Value);
        Assert.True(cookies.Options !.HttpOnly);
        Assert.Equal(expectedCookiePath, cookies.Options.Path);
    }
        public void GetCookieToken_CookieIsEmpty_ReturnsNull()
        {
            // Arrange
            var httpContext = GetHttpContext(_cookieName, string.Empty);
            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var token = tokenStore.GetCookieToken(httpContext);

            // Assert
            Assert.Null(token);
        }
        public void GetCookieToken_CookieDoesNotExist_ReturnsNull()
        {
            // Arrange
            var httpContext = GetHttpContext(new RequestCookieCollection());
            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var token = tokenStore.GetCookieToken(httpContext);

            // Assert
            Assert.Null(token);
        }
    public void GetCookieToken_CookieIsEmpty_ReturnsNull()
    {
        // Arrange
        var httpContext = GetHttpContext(_cookieName, string.Empty);
        var options     = new AntiforgeryOptions
        {
            Cookie = { Name = _cookieName }
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var token = tokenStore.GetCookieToken(httpContext);

        // Assert
        Assert.Null(token);
    }
    public void SaveCookieToken_HonorsCookieSecurePolicy_OnOptions(
        bool isRequestSecure,
        CookieSecurePolicy policy,
        bool?expectedCookieSecureFlag)
    {
        // Arrange
        var  token = "serialized-value";
        bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor
        var  cookies = new MockResponseCookieCollection();

        var httpContext = new Mock <HttpContext>();

        httpContext
        .Setup(hc => hc.Request.IsHttps)
        .Returns(isRequestSecure);
        httpContext
        .Setup(o => o.Response.Cookies)
        .Returns(cookies);
        httpContext
        .SetupGet(hc => hc.Request.PathBase)
        .Returns("/");

        var options = new AntiforgeryOptions()
        {
            Cookie =
            {
                Name         = _cookieName,
                SecurePolicy = policy
            },
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        tokenStore.SaveCookieToken(httpContext.Object, token);

        // Assert
        Assert.Equal(1, cookies.Count);
        Assert.NotNull(cookies);
        Assert.Equal(_cookieName, cookies.Key);
        Assert.Equal("serialized-value", cookies.Value);
        Assert.True(cookies.Options !.HttpOnly);
        Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
    }
        public void GetCookieToken_CookieIsNotEmpty_ReturnsToken()
        {
            // Arrange
            var expectedToken = "valid-value";
            var httpContext = GetHttpContext(_cookieName, expectedToken);

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var token = tokenStore.GetCookieToken(httpContext);

            // Assert
            Assert.Equal(expectedToken, token);
        }
    public void GetCookieToken_CookieIsNotEmpty_ReturnsToken()
    {
        // Arrange
        var expectedToken = "valid-value";
        var httpContext   = GetHttpContext(_cookieName, expectedToken);

        var options = new AntiforgeryOptions
        {
            Cookie = { Name = _cookieName }
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var token = tokenStore.GetCookieToken(httpContext);

        // Assert
        Assert.Equal(expectedToken, token);
    }
    public async Task GetRequestTokens_CookieIsEmpty_ReturnsNullTokens()
    {
        // Arrange
        var httpContext = GetHttpContext();

        httpContext.Request.Form = FormCollection.Empty;

        var options = new AntiforgeryOptions
        {
            Cookie        = { Name = "cookie-name" },
            FormFieldName = "form-field-name",
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

        // Assert
        Assert.Null(tokenSet.CookieToken);
        Assert.Null(tokenSet.RequestToken);
    }
    public void SaveCookieToken_NonNullAntiforgeryOptionsConfigureCookieOptionsDomain_UsesCookieOptionsDomain()
    {
        // Arrange
        var expectedCookieDomain = "microsoft.com";
        var token       = "serialized-value";
        var cookies     = new MockResponseCookieCollection();
        var httpContext = new Mock <HttpContext>();

        httpContext
        .Setup(hc => hc.Response.Cookies)
        .Returns(cookies);
        httpContext
        .SetupGet(hc => hc.Request.PathBase)
        .Returns("/vdir1");
        httpContext
        .SetupGet(hc => hc.Request.Path)
        .Returns("/index.html");
        var options = new AntiforgeryOptions
        {
            Cookie =
            {
                Name   = _cookieName,
                Domain = expectedCookieDomain
            }
        };
        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        tokenStore.SaveCookieToken(httpContext.Object, token);

        // Assert
        Assert.Equal(1, cookies.Count);
        Assert.NotNull(cookies);
        Assert.Equal(_cookieName, cookies.Key);
        Assert.Equal("serialized-value", cookies.Value);
        Assert.True(cookies.Options !.HttpOnly);
        Assert.Equal("/vdir1", cookies.Options.Path);
        Assert.Equal(expectedCookieDomain, cookies.Options.Domain);
    }
    public async Task GetRequestTokens_BothHeaderValueAndFormFieldsEmpty_ReturnsNullTokens()
    {
        // Arrange
        var httpContext = GetHttpContext("cookie-name", "cookie-value");

        httpContext.Request.ContentType = "application/x-www-form-urlencoded";
        httpContext.Request.Form        = FormCollection.Empty;

        var options = new AntiforgeryOptions
        {
            Cookie        = { Name = "cookie-name" },
            FormFieldName = "form-field-name",
            HeaderName    = "header-name",
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act
        var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

        // Assert
        Assert.Equal("cookie-value", tokenSet.CookieToken);
        Assert.Null(tokenSet.RequestToken);
    }
    public async Task GetRequestTokens_ReadFormAsyncThrowsInvalidDataException_ThrowsAntiforgeryValidationException()
    {
        // Arrange
        var exception   = new InvalidDataException();
        var httpContext = new Mock <HttpContext>();

        httpContext.Setup(r => r.Request.Cookies).Returns(Mock.Of <IRequestCookieCollection>());
        httpContext.SetupGet(r => r.Request.HasFormContentType).Returns(true);
        httpContext.Setup(r => r.Request.ReadFormAsync(It.IsAny <CancellationToken>())).Throws(exception);

        var options = new AntiforgeryOptions
        {
            Cookie        = { Name = "cookie-name" },
            FormFieldName = "form-field-name",
            HeaderName    = null,
        };

        var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

        // Act & Assert
        var ex = await Assert.ThrowsAsync <AntiforgeryValidationException>(() => tokenStore.GetRequestTokensAsync(httpContext.Object));

        Assert.Same(exception, ex.InnerException);
    }
        public async Task GetRequestTokens_CookieIsEmpty_ReturnsNullTokens()
        {
            // Arrange
            var httpContext = GetHttpContext(new RequestCookieCollection());
            httpContext.Request.Form = FormCollection.Empty;

            var options = new AntiforgeryOptions()
            {
                CookieName = "cookie-name",
                FormFieldName = "form-field-name",
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

            // Assert
            Assert.Null(tokenSet.CookieToken);
            Assert.Null(tokenSet.RequestToken);
        }
        public void SaveCookieToken(bool requireSsl, bool? expectedCookieSecureFlag)
        {
            // Arrange
            var token = "serialized-value";
            bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor
            var cookies = new MockResponseCookieCollection();

            var mockHttpContext = new Mock<HttpContext>();
            mockHttpContext
                .Setup(o => o.Response.Cookies)
                .Returns(cookies);

            var options = new AntiforgeryOptions()
            {
                CookieName = _cookieName,
                RequireSsl = requireSsl
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            tokenStore.SaveCookieToken(mockHttpContext.Object, token);

            // Assert
            Assert.Equal(1, cookies.Count);
            Assert.NotNull(cookies);
            Assert.Equal(_cookieName, cookies.Key);
            Assert.Equal("serialized-value", cookies.Value);
            Assert.True(cookies.Options.HttpOnly);
            Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
        }
        public async Task GetFormToken_FormFieldIsValid_ReturnsToken()
        {
            // Arrange
            var httpContext = GetHttpContext("cookie-name", "cookie-value");
            httpContext.Request.ContentType = "application/x-www-form-urlencoded";
            httpContext.Request.Form = new FormCollection(new Dictionary<string, StringValues>
            {
                { "form-field-name", "form-value" },
            });
            httpContext.Request.Headers.Add("header-name", "header-value"); // form value has priority.

            var options = new AntiforgeryOptions()
            {
                CookieName = "cookie-name",
                FormFieldName = "form-field-name",
                HeaderName = "header-name",
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var tokens = await tokenStore.GetRequestTokensAsync(httpContext);

            // Assert
            Assert.Equal("cookie-value", tokens.CookieToken);
            Assert.Equal("form-value", tokens.RequestToken);
        }
        public async Task GetRequestTokens_BothFieldsEmpty_ReturnsNullTokens()
        {
            // Arrange
            var httpContext = GetHttpContext("cookie-name", "cookie-value");
            httpContext.Request.ContentType = "application/x-www-form-urlencoded";
            httpContext.Request.Form = FormCollection.Empty;

            var options = new AntiforgeryOptions()
            {
                CookieName = "cookie-name",
                FormFieldName = "form-field-name",
                HeaderName = "header-name",
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

            // Assert
            Assert.Equal("cookie-value", tokenSet.CookieToken);
            Assert.Null(tokenSet.RequestToken);
        }
        public async Task GetRequestTokens_NonFormContentType_NoHeaderToken_ReturnsNullToken()
        {
            // Arrange
            var httpContext = GetHttpContext("cookie-name", "cookie-value");
            httpContext.Request.ContentType = "application/json";

            // Will not be accessed
            httpContext.Request.Form = null;

            var options = new AntiforgeryOptions()
            {
                CookieName = "cookie-name",
                FormFieldName = "form-field-name",
                HeaderName = "header-name",
            };

            var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options));

            // Act
            var tokenSet = await tokenStore.GetRequestTokensAsync(httpContext);

            // Assert
            Assert.Equal("cookie-value", tokenSet.CookieToken);
            Assert.Null(tokenSet.RequestToken);
        }