From 517dc3c86015415c9efe64395c49b90fa2ec909b Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Wed, 16 Nov 2016 18:25:15 -0800 Subject: [PATCH] Added tests for logging --- .../Infrastructure/CorsService.cs | 22 +++++- .../CorsServiceTests.cs | 76 +++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs index b52e000fa8..72e17d5365 100644 --- a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs @@ -97,26 +97,40 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public virtual void EvaluateRequest(HttpContext context, CorsPolicy policy, CorsResult result) { var origin = context.Request.Headers[CorsConstants.Origin]; - if (StringValues.IsNullOrEmpty(origin) || !policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) + if (StringValues.IsNullOrEmpty(origin)) { return; } + if (!policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) + { + _logger?.RequestHasOriginHeader(); + _logger.PolicyFailure($"Request origin {origin} does not have permission to access the resource."); + return; + } + _logger?.RequestHasOriginHeader(); AddOriginToResult(origin, policy, result); result.SupportsCredentials = policy.SupportsCredentials; - _logger?.PolicySuccess(); AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders); + _logger?.PolicySuccess(); } public virtual void EvaluatePreflightRequest(HttpContext context, CorsPolicy policy, CorsResult result) { var origin = context.Request.Headers[CorsConstants.Origin]; - if (StringValues.IsNullOrEmpty(origin) || !policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) + if (StringValues.IsNullOrEmpty(origin)) { return; } + if (!policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) + { + _logger?.RequestHasOriginHeader(); + _logger.PolicyFailure($"Request origin {origin} does not have permission to access the resource."); + return; + } + _logger?.RequestHasOriginHeader(); var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod]; if (StringValues.IsNullOrEmpty(accessControlRequestMethod)) @@ -160,8 +174,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure result.SupportsCredentials = policy.SupportsCredentials; result.PreflightMaxAge = policy.PreflightMaxAge; result.AllowedMethods.Add(accessControlRequestMethod); + AddHeaderValues(result.AllowedHeaders, requestHeaders); _logger?.PolicySuccess(); - AddHeaderValues(result.AllowedHeaders, requestHeaders); } /// diff --git a/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs b/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs index b3a92a8d68..617155ea43 100644 --- a/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs +++ b/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs @@ -4,6 +4,7 @@ using System; using Microsoft.AspNetCore.Http; using Xunit; +using Microsoft.Extensions.Logging.Testing; namespace Microsoft.AspNetCore.Cors.Infrastructure { @@ -227,6 +228,81 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.Contains("PUT", result.AllowedMethods); } + public static TheoryData LoggingData + { + get + { + return new TheoryData + { + { + "http://example.com", + "PUT", + null, + "Policy execution failed. Request origin http://example.com does not have permission to access the resource." + }, + { + "http://allowedexample.com", + "DELETE", + null, + "Policy execution failed. Request method DELETE not allowed in CORS policy." + }, + { + "http://allowedexample.com", + "PUT", + new[] { "test" }, + "Policy execution failed. One or more request header(s) not allowed in CORS policy." + }, + { + "http://allowedexample.com", + "PUT", + null, + "Policy execution successful." + }, + }; + } + } + + [Theory] + [MemberData(nameof(LoggingData))] + public void EvaluatePolicy_LoggingForPreflightRequests(string origin, string method, string[] headers, string logMessage) + { + var sink = new TestSink(); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); + + var corsService = new CorsService(new TestCorsOptions(), loggerFactory); + var requestContext = GetHttpContext(method: "OPTIONS", origin: origin, accessControlRequestMethod: method, accessControlRequestHeaders: headers); + var policy = new CorsPolicy(); + policy.Origins.Add("http://allowedexample.com"); + policy.Methods.Add("PUT"); + + // Act + var result = corsService.EvaluatePolicy(requestContext, policy); + + Assert.Equal("The request is preflight.", sink.Writes[0].State.ToString()); + Assert.Equal("The request has an origin header.", sink.Writes[1].State.ToString()); + Assert.Equal(logMessage, sink.Writes[2].State.ToString()); + } + + [Theory] + [InlineData("http://allowedexample.com", "Policy execution successful.")] + [InlineData("http://example.com", "Policy execution failed. Request origin http://example.com does not have permission to access the resource.")] + public void EvaluatePolicy_LoggingForRequests(string origin, string logMessage) + { + var sink = new TestSink(); + var loggerFactory = new TestLoggerFactory(sink, enabled: true); + + var corsService = new CorsService(new TestCorsOptions(), loggerFactory); + var requestContext = GetHttpContext(origin: origin); + var policy = new CorsPolicy(); + policy.Origins.Add("http://allowedexample.com"); + + // Act + var result = corsService.EvaluatePolicy(requestContext, policy); + + Assert.Equal("The request has an origin header.", sink.Writes[0].State.ToString()); + Assert.Equal(logMessage, sink.Writes[1].State.ToString()); + } + [Theory] [InlineData("OpTions")] [InlineData("OPTIONS")]