diff --git a/LICENSE b/LICENSE index 02c8f7c..8f55b35 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2020 Castle Intelligence, Inc. +Copyright (c) 2021 Castle Intelligence, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index 101b608..f2e02d4 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,8 @@ For events where you don't require a response. ```csharp castleClient.Track(new ActionRequest() { - Event = Castle.Events.LogoutSucceeded, + Event = "$logout", + Status = "$succeeded", UserId = user.Id, UserTraits = new Dictionary() { @@ -130,19 +131,17 @@ For events where you require a response. It is used in the same way as `Track`, ```csharp var verdict = await castleClient.Authenticate(new ActionRequest() { - Event = Castle.Events.LogoutSucceeded, + Event = "$logout", + Status = "$succeeded", UserId = user.Id, UserTraits = new Dictionary() { ["email"] = user.Email, ["registered_at"] = user.RegisteredAt }, - Context = new RequestContext() - { - Ip = Request.HttpContext.Connection.RemoteIpAddress.ToString(), - ClientId = Request.Cookies["__cid"], - Headers = Request.Headers.ToDictionary(x => x.Key, y => y.Value.FirstOrDefault()); - } + Ip = Request.HttpContext.Connection.RemoteIpAddress.ToString(), + Fingerprint = Request.Cookies["__cid"], + Headers = Request.Headers.ToDictionary(x => x.Key, y => y.Value.FirstOrDefault()) }); ``` @@ -166,7 +165,7 @@ If no failover strategy is set (i.e. `None`), a `Castle.Infrastructure.Exception | Option | Description | --- | --- -| Event | The event generated by the user. It can be either an event from the SDK constants in `Castle.Events` or a custom one. +| Event | The event generated by the user. List of Recognized Events can be found in the [docs](https://docs.castle.io/api_reference/#list-of-recognized-events). | UserId | Your internal ID for the end user. | UserTraits | An optional, recommended, dictionary of user information, such as `email` and `registered_at`. | Properties | An optional dictionary of custom information. @@ -174,7 +173,7 @@ If no failover strategy is set (i.e. `None`), a `Castle.Infrastructure.Exception | DeviceToken | The optional device token, used for mitigating or escalating. | Context | The request context information. See information below. -#### Request context +#### Request options | Option | Description | --- | --- @@ -182,7 +181,7 @@ If no failover strategy is set (i.e. `None`), a `Castle.Infrastructure.Exception | ClientId | The client ID, generated by the `c.js` integration on the front end. Commonly found in the `__cid` cookie in `Request.Cookies`, or in some cases the `X-CASTLE-CLIENT-ID` header. | Headers | Headers mapped from the the original request (most likely `Request.Headers`). -You can call `Castle.Context.FromHttpRequest(request)` to get a ready-made `RequestContext` instance from your current request. +You can call `Castle.Options.FromHttpRequest(request)` to get a ready-made `RequestOptions` instance from your current request. ##### ASP.NET MVC 5 ```csharp @@ -192,7 +191,7 @@ public class HomeController : Controller { var actionRequest = new ActionRequest() { - Context = Castle.Context.FromHttpRequest(Request) + Options = Castle.Options.FromHttpRequest(Request) ... ``` @@ -204,7 +203,7 @@ public class IndexModel : PageModel { var actionRequest = new ActionRequest() { - Context = Castle.Context.FromHttpRequest(Request) + Options = Castle.Options.FromHttpRequest(Request) ... ``` diff --git a/src/Castle.Sdk/Castle.Sdk.csproj b/src/Castle.Sdk/Castle.Sdk.csproj index 4bf5ea4..a99bbca 100644 --- a/src/Castle.Sdk/Castle.Sdk.csproj +++ b/src/Castle.Sdk/Castle.Sdk.csproj @@ -5,7 +5,7 @@ false https://github.com/castle/castle-dotnet Castle - 1.5.0 + 1.5.2 Castle Castle .NET SDK Castle SDK for C# / .NET diff --git a/src/Castle.Sdk/Castle.Sdk.xml b/src/Castle.Sdk/Castle.Sdk.xml index 2077d72..d35bcc1 100644 --- a/src/Castle.Sdk/Castle.Sdk.xml +++ b/src/Castle.Sdk/Castle.Sdk.xml @@ -111,11 +111,6 @@ Configuration access from within the SDK - - - Castle tracking event constants - - Recommended request context headers diff --git a/src/Castle.Sdk/Events.cs b/src/Castle.Sdk/Events.cs deleted file mode 100644 index 82d53df..0000000 --- a/src/Castle.Sdk/Events.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Castle -{ - /// - /// Castle tracking event constants - /// - public static class Events - { - public const string LoginSucceeded = "$login.succeeded"; - public const string LoginFailed = "$login.failed"; - public const string LogoutSucceeded = "$logout.succeeded"; - public const string ProfileUpdateSucceeded = "$profile_update.succeeded"; - public const string ProfileUpdateFailed = "$profile_update.failed"; - public const string RegistrationSucceeded = "$registration.succeeded"; - public const string RegistrationFailed = "$registration.failed"; - public const string PasswordResetSucceeded = "$password_reset.succeeded"; - public const string PasswordResetFailed = "$password_reset.failed"; - public const string PasswordResetRequestSucceeded = "$password_reset_request.succeeded"; - public const string PasswordResetRequestFailed = "$password_reset_request.failed"; - public const string IncidentMitigated = "$incident.mitigated"; - public const string ReviewEscalated = "$review.escalated"; - public const string ReviewResolved = "$review.resolved"; - public const string ChallengeRequested = "$challenge.requested"; - public const string ChallengeSucceeded = "$challenge.succeeded"; - public const string ChallengeFailed = "$challenge.failed"; - } -} diff --git a/src/Castle.Sdk/Messages/Requests/ActionRequest.cs b/src/Castle.Sdk/Messages/Requests/ActionRequest.cs index 91f43f4..50ce9c7 100644 --- a/src/Castle.Sdk/Messages/Requests/ActionRequest.cs +++ b/src/Castle.Sdk/Messages/Requests/ActionRequest.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; using Castle.Infrastructure; +using Castle.Infrastructure.Json; + using Newtonsoft.Json; + namespace Castle.Messages.Requests { public class ActionRequest @@ -16,24 +19,45 @@ public class ActionRequest public string Event { get; set; } + public string Status { get; set; } + + public string Email { get; set; } + public string UserId { get; set; } + [JsonConverter(typeof(EmptyStringToFalseConverter))] + public string Fingerprint { get; set; } + + public string Ip { get; set; } + + [JsonProperty(ItemConverterType = typeof(StringScrubConverter))] + public IDictionary Headers { get; set; } = new Dictionary(); + public IDictionary UserTraits { get; set; } = new Dictionary(); public IDictionary Properties { get; set; } = new Dictionary(); public RequestContext Context { get; set; } = new RequestContext(); + [JsonIgnore] + public RequestOptions Options { get; set; } = new RequestOptions(); + internal ActionRequest PrepareApiCopy(string[] allowList, string[] denyList) { var copy = (ActionRequest) MemberwiseClone(); - var scrubbed = HeaderScrubber.Scrub(Context.Headers, allowList, denyList); - copy.Context = Context.WithHeaders(scrubbed); - - copy.SentAt = DateTime.Now; + var scrubbed = HeaderScrubber.Scrub(Options.Headers, allowList, denyList); + var opts = Options.WithHeaders(scrubbed); + // Assign Fingerprint, IP and Headers from options // Newtonsoft.Json doesn't apply custom converter to null values, so this must be empty instead - copy.Context.ClientId = copy.Context.ClientId ?? ""; + var newFingerprint = opts.Fingerprint ?? ""; + copy.Fingerprint = copy.Fingerprint ?? newFingerprint; + copy.Ip = opts.Ip; + copy.Headers = opts.Headers; + + copy.Context = Context.WithLibrary(); + + copy.SentAt = DateTime.Now; return copy; } diff --git a/src/Castle.Sdk/Messages/Requests/RequestContext.cs b/src/Castle.Sdk/Messages/Requests/RequestContext.cs index 81fdcb8..255a4c0 100644 --- a/src/Castle.Sdk/Messages/Requests/RequestContext.cs +++ b/src/Castle.Sdk/Messages/Requests/RequestContext.cs @@ -6,25 +6,14 @@ namespace Castle.Messages.Requests { public class RequestContext { - [JsonConverter(typeof(EmptyStringToFalseConverter))] - public string ClientId { get; set; } - - public string Ip { get; set; } - - [JsonProperty(ItemConverterType = typeof(StringScrubConverter))] - public IDictionary Headers { get; set; } = new Dictionary(); - [JsonProperty] internal LibraryInfo Library { get; set; } = new LibraryInfo(); - internal RequestContext WithHeaders(IDictionary headers) + internal RequestContext WithLibrary() { return new RequestContext() { - ClientId = ClientId, - Ip = Ip, - Library = Library, - Headers = headers + Library = Library }; } } diff --git a/src/Castle.Sdk/Messages/Requests/RequestOptions.cs b/src/Castle.Sdk/Messages/Requests/RequestOptions.cs new file mode 100644 index 0000000..efd4b09 --- /dev/null +++ b/src/Castle.Sdk/Messages/Requests/RequestOptions.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using Castle.Infrastructure.Json; +using Newtonsoft.Json; + +namespace Castle.Messages.Requests +{ + public class RequestOptions + { + [JsonConverter(typeof(EmptyStringToFalseConverter))] + public string Fingerprint { get; set; } + + public string Ip { get; set; } + + [JsonProperty(ItemConverterType = typeof(StringScrubConverter))] + public IDictionary Headers { get; set; } = new Dictionary(); + + internal RequestOptions WithHeaders(IDictionary headers) + { + return new RequestOptions() + { + Fingerprint = Fingerprint, + Ip = Ip, + Headers = headers + }; + } + } +} \ No newline at end of file diff --git a/src/Castle.Sdk/Context.cs b/src/Castle.Sdk/Options.cs similarity index 91% rename from src/Castle.Sdk/Context.cs rename to src/Castle.Sdk/Options.cs index 6f8d153..01716db 100644 --- a/src/Castle.Sdk/Context.cs +++ b/src/Castle.Sdk/Options.cs @@ -10,10 +10,10 @@ namespace Castle { - public static class Context + public static class Options { #if NET461 || NET48 - public static RequestContext FromHttpRequest(System.Web.HttpRequestBase request, string[] ipHeaders = null) + public static RequestOptions FromHttpRequest(System.Web.HttpRequestBase request, string[] ipHeaders = null) { var headers = new Dictionary(); foreach (string key in request.Headers.Keys) @@ -21,22 +21,22 @@ public static RequestContext FromHttpRequest(System.Web.HttpRequestBase request, headers.Add(key, request.Headers[key]); } - var clientId = GetClientIdForFramework(request.Headers, name => request.Cookies[name]?.Value); + var fingerprint = GetFingerprintForFramework(request.Headers, name => request.Cookies[name]?.Value); var ip = GetIpForFramework(request.Headers, ipHeaders, () => request.UserHostAddress, () => CastleConfiguration.Configuration); - return new RequestContext() + return new RequestOptions() { - ClientId = clientId, + Fingerprint = fingerprint, Headers = headers, Ip = ip }; } #endif - internal static string GetClientIdForFramework(NameValueCollection headers, Func getCookieValue) + internal static string GetFingerprintForFramework(NameValueCollection headers, Func getCookieValue) { return headers.AllKeys.Contains("X-Castle-Client-ID", StringComparer.OrdinalIgnoreCase) ? headers["X-Castle-Client-ID"] @@ -118,11 +118,11 @@ string RemoveProxies(string[] ips) } #if NETSTANDARD2_0 || NETCOREAPP - public static RequestContext FromHttpRequest(Microsoft.AspNetCore.Http.HttpRequest request, string[] ipHeaders = null) + public static RequestOptions FromHttpRequest(Microsoft.AspNetCore.Http.HttpRequest request, string[] ipHeaders = null) { - return new RequestContext() + return new RequestOptions() { - ClientId = GetClientIdForCore(request.Headers, request.Cookies), + Fingerprint = GetFingerprintForCore(request.Headers, request.Cookies), Headers = request.Headers.ToDictionary(x => x.Key, y => y.Value.FirstOrDefault()), Ip = GetIpForCore(request.Headers, ipHeaders, () => request.HttpContext.Connection.RemoteIpAddress?.ToString(), @@ -130,7 +130,7 @@ public static RequestContext FromHttpRequest(Microsoft.AspNetCore.Http.HttpReque }; } - internal static string GetClientIdForCore( + internal static string GetFingerprintForCore( IDictionary headers, Microsoft.AspNetCore.Http.IRequestCookieCollection cookies) { diff --git a/src/Tests/Actions/When_preparing_request.cs b/src/Tests/Actions/When_preparing_request.cs index cc0ec6a..bd01347 100644 --- a/src/Tests/Actions/When_preparing_request.cs +++ b/src/Tests/Actions/When_preparing_request.cs @@ -14,7 +14,7 @@ public void Should_scrub_headers(ActionRequest request, CastleConfiguration opti { var result = request.PrepareApiCopy(options.AllowList, options.DenyList); - result.Context.Headers.Should().NotBeSameAs(request.Context.Headers); + result.Headers.Should().NotBeSameAs(request.Headers); } [Theory, AutoFakeData] @@ -26,21 +26,21 @@ public void Should_set_sent_date(ActionRequest request, CastleConfiguration opti } [Theory, AutoFakeData] - public void Should_set_null_clientid_to_empty(ActionRequest request, CastleConfiguration options) + public void Should_set_null_fingerprint_to_default(ActionRequest request, CastleConfiguration options) { - request.Context.ClientId = null; + request.Fingerprint = null; var result = request.PrepareApiCopy(options.AllowList, options.DenyList); - result.Context.ClientId.Should().Be(""); + result.Fingerprint.Should().NotBe(null); } [Theory, AutoFakeData] - public void Should_preserve_valid_clientid(ActionRequest request, CastleConfiguration options) + public void Should_preserve_valid_fingerprint(ActionRequest request, CastleConfiguration options) { var result = request.PrepareApiCopy(options.AllowList, options.DenyList); - result.Context.ClientId.Should().Be(request.Context.ClientId); + result.Fingerprint.Should().Be(request.Fingerprint); } } } diff --git a/src/Tests/Json/When_serializing_special_properties.cs b/src/Tests/Json/When_serializing_special_properties.cs index 583665e..ab54e4e 100644 --- a/src/Tests/Json/When_serializing_special_properties.cs +++ b/src/Tests/Json/When_serializing_special_properties.cs @@ -12,11 +12,11 @@ public class When_serializing_special_properties { // Null values are skipped by Newtonsoft.Json, so we don't test those [Theory] - [InlineData("non-empty", "\"client_id\":\"non-empty\"")] - [InlineData("", "\"client_id\":false")] - public void Should_serialize_client_id_to_false_if_empty(string value, string expected) + [InlineData("non-empty", "\"fingerprint\":\"non-empty\"")] + [InlineData("", "\"fingerprint\":false")] + public void Should_serialize_fingerprint_to_false_if_empty(string value, string expected) { - var obj = new RequestContext() { ClientId = value }; + var obj = new RequestOptions() { Fingerprint = value }; var result = JsonForCastle.SerializeObject(obj); @@ -51,7 +51,7 @@ public void Should_only_convert_strings_for_for_empty_string() string value, string expected) { - var obj = new RequestContext() + var obj = new RequestOptions() { Headers = new Dictionary() { diff --git a/src/Tests/Messages/When_creating_request_context_for_Core.cs b/src/Tests/Messages/When_creating_request_object_for_Core.cs similarity index 87% rename from src/Tests/Messages/When_creating_request_context_for_Core.cs rename to src/Tests/Messages/When_creating_request_object_for_Core.cs index caf64f7..d3281da 100644 --- a/src/Tests/Messages/When_creating_request_context_for_Core.cs +++ b/src/Tests/Messages/When_creating_request_object_for_Core.cs @@ -1,8 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Castle; using Castle.Config; -using Castle.Messages.Requests; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Internal; @@ -12,7 +10,7 @@ namespace Tests.Messages { - public class When_creating_request_context_for_Core + public class When_creating_request_object_for_Core { [Theory, AutoFakeData] public void Should_get_client_id_from_castle_header_if_present( @@ -29,7 +27,7 @@ public class When_creating_request_context_for_Core ["__cid"] = cookieValue }); - var result = Context.GetClientIdForCore(headers, cookies); + var result = Options.GetFingerprintForCore(headers, cookies); result.Should().Be(castleHeaderValue); } @@ -50,7 +48,7 @@ public class When_creating_request_context_for_Core ["__cid"] = cookieValue }); - var result = Context.GetClientIdForCore(headers, cookies); + var result = Options.GetFingerprintForCore(headers, cookies); result.Should().Be(cookieValue); } @@ -72,7 +70,7 @@ public class When_creating_request_context_for_Core [otherCookie] = otherCookieValue }); - var result = Context.GetClientIdForCore(headers, cookies); + var result = Options.GetFingerprintForCore(headers, cookies); result.Should().Be(""); } @@ -95,7 +93,7 @@ public class When_creating_request_context_for_Core [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForCore(headers, new[] {ipHeader, secondaryIpHeader}, () => httpContextIp, () => cfg); + var result = Options.GetIpForCore(headers, new[] {ipHeader, secondaryIpHeader}, () => httpContextIp, () => cfg); result.Should().Be(ip); } @@ -116,7 +114,7 @@ public class When_creating_request_context_for_Core [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForCore(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); + var result = Options.GetIpForCore(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); result.Should().Be(secondaryIp); } @@ -136,7 +134,7 @@ public class When_creating_request_context_for_Core [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForCore(headers, null, () => httpContextIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => httpContextIp, () => cfg); result.Should().Be(httpContextIp); } @@ -153,7 +151,7 @@ string ip [ipHeader] = ip, }; - var result = Context.GetIpForCore(headers, null, () => ip, () => cfg); + var result = Options.GetIpForCore(headers, null, () => ip, () => cfg); result.Should().Be(ip); } @@ -169,7 +167,7 @@ public void Should_get_other_ip_header(CastleConfiguration cfg, string cfConnect var ipHeaders = new[] {"Cf-Connecting-Ip", "X-Forwarded-For"}; - var result = Context.GetIpForCore(headers, ipHeaders, () => cfConnectiongIp, () => cfg); + var result = Options.GetIpForCore(headers, ipHeaders, () => cfConnectiongIp, () => cfg); result.Should().Be(cfConnectiongIp); } @@ -183,7 +181,7 @@ public void Should_get_first_available_with_all_trusted_proxies(CastleConfigurat ["X-Forwarded-For"] = "127.0.0.1,10.0.0.1,172.31.0.1,192.168.0.1" }; - var result = Context.GetIpForCore(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => defaultIp, () => cfg); result.Should().Be("127.0.0.1"); } @@ -198,7 +196,7 @@ public void Should_get_first_available_with_trust_proxy_chain(CastleConfiguratio cfg.TrustProxyChain = true; - var result = Context.GetIpForCore(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => defaultIp, () => cfg); result.Should().Be("6.6.6.6"); } @@ -211,7 +209,7 @@ public void Should_get_remote_addr_if_others_internal(CastleConfiguration cfg, s ["X-Forwarded-For"] = "127.0.0.1,10.0.0.1,172.31.0.1,192.168.0.1" }; - var result = Context.GetIpForCore(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => defaultIp, () => cfg); result.Should().Be("6.5.4.3"); } @@ -226,7 +224,7 @@ public void Should_get_equivalent_to_trusted_proxy_depth_1(CastleConfiguration c cfg.TrustedProxyDepth = 1; - var result = Context.GetIpForCore(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => defaultIp, () => cfg); result.Should().Be("2.2.2.3"); } @@ -242,7 +240,7 @@ public void Should_get_equivalent_to_trusted_proxy_depth_2_ip_headers(CastleConf cfg.TrustedProxyDepth = 2; cfg.IpHeaders = new[] {"X-Forwarded-For", "Remote-Addr"}; - var result = Context.GetIpForCore(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForCore(headers, null, () => defaultIp, () => cfg); result.Should().Be("2.2.2.3"); } @@ -251,7 +249,7 @@ public void Should_get_default_from_http_request(HttpRequest request, CastleConf { CastleConfiguration.SetConfiguration(cfg); - var result = Context.FromHttpRequest(request); + var result = Options.FromHttpRequest(request); result.Should().NotBe(null); } diff --git a/src/Tests/Messages/When_creating_request_context_for_Framework.cs b/src/Tests/Messages/When_creating_request_object_for_Framework.cs similarity index 87% rename from src/Tests/Messages/When_creating_request_context_for_Framework.cs rename to src/Tests/Messages/When_creating_request_object_for_Framework.cs index 51e9646..5619ac0 100644 --- a/src/Tests/Messages/When_creating_request_context_for_Framework.cs +++ b/src/Tests/Messages/When_creating_request_object_for_Framework.cs @@ -10,7 +10,7 @@ namespace Tests.Messages { - public class When_creating_request_context_for_Framework + public class When_creating_request_object_for_Framework { [Theory, AutoFakeData] public void Should_get_client_id_from_castle_header_if_present( @@ -24,7 +24,7 @@ public class When_creating_request_context_for_Framework string GetCookie(string name) => name == "__cid" ? cookieValue : null; - var result = Context.GetClientIdForFramework(headers, GetCookie); + var result = Options.GetFingerprintForFramework(headers, GetCookie); result.Should().Be(castleHeaderValue); } @@ -42,7 +42,7 @@ public class When_creating_request_context_for_Framework string GetCookie(string name) => name == "__cid" ? cookieValue : null; - var result = Context.GetClientIdForFramework(headers, GetCookie); + var result = Options.GetFingerprintForFramework(headers, GetCookie); result.Should().Be(cookieValue); } @@ -61,7 +61,7 @@ public class When_creating_request_context_for_Framework string GetCookie(string name) => name == otherCookie ? otherCookieValue : null; - var result = Context.GetClientIdForFramework(headers, GetCookie); + var result = Options.GetFingerprintForFramework(headers, GetCookie); result.Should().Be(""); } @@ -84,7 +84,7 @@ public class When_creating_request_context_for_Framework [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForFramework(headers, new [] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); + var result = Options.GetIpForFramework(headers, new [] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); result.Should().Be(ip); } @@ -105,7 +105,7 @@ public class When_creating_request_context_for_Framework [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForFramework(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); + var result = Options.GetIpForFramework(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp, () => cfg); result.Should().Be(secondaryIp); } @@ -125,7 +125,7 @@ public class When_creating_request_context_for_Framework [otherHeader] = otherHeaderValue }; - var result = Context.GetIpForFramework(headers, null, () => httpContextIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => httpContextIp, () => cfg); result.Should().Be(httpContextIp); } @@ -142,7 +142,7 @@ string ip [ipHeader] = ip, }; - var result = Context.GetIpForFramework(headers, null, () => ip, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => ip, () => cfg); result.Should().Be(ip); } @@ -158,7 +158,7 @@ public void Should_get_other_ip_header(CastleConfiguration cfg, string cfConnect var ipHeaders = new[] {"Cf-Connecting-Ip", "X-Forwarded-For"}; - var result = Context.GetIpForFramework(headers, ipHeaders, () => cfConnectiongIp, () => cfg); + var result = Options.GetIpForFramework(headers, ipHeaders, () => cfConnectiongIp, () => cfg); result.Should().Be(cfConnectiongIp); } @@ -172,7 +172,7 @@ public void Should_get_first_available_with_all_trusted_proxies(CastleConfigurat ["X-Forwarded-For"] = "127.0.0.1,10.0.0.1,172.31.0.1,192.168.0.1" }; - var result = Context.GetIpForFramework(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => defaultIp, () => cfg); result.Should().Be("127.0.0.1"); } @@ -187,7 +187,7 @@ public void Should_get_first_available_with_trust_proxy_chain(CastleConfiguratio cfg.TrustProxyChain = true; - var result = Context.GetIpForFramework(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => defaultIp, () => cfg); result.Should().Be("6.6.6.6"); } @@ -200,7 +200,7 @@ public void Should_get_remote_addr_if_others_internal(CastleConfiguration cfg, s ["X-Forwarded-For"] = "127.0.0.1,10.0.0.1,172.31.0.1,192.168.0.1" }; - var result = Context.GetIpForFramework(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => defaultIp, () => cfg); result.Should().Be("6.5.4.3"); } @@ -215,7 +215,7 @@ public void Should_get_equivalent_to_trusted_proxy_depth_1(CastleConfiguration c cfg.TrustedProxyDepth = 1; - var result = Context.GetIpForFramework(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => defaultIp, () => cfg); result.Should().Be("2.2.2.3"); } @@ -231,7 +231,7 @@ public void Should_get_equivalent_to_trusted_proxy_depth_2_ip_headers(CastleConf cfg.TrustedProxyDepth = 2; cfg.IpHeaders = new[] {"X-Forwarded-For", "Remote-Addr"}; - var result = Context.GetIpForFramework(headers, null, () => defaultIp, () => cfg); + var result = Options.GetIpForFramework(headers, null, () => defaultIp, () => cfg); result.Should().Be("2.2.2.3"); } @@ -240,7 +240,7 @@ public void Should_get_default_from_http_request(HttpRequest request, CastleConf { CastleConfiguration.SetConfiguration(cfg); - var result = Context.FromHttpRequest(request); + var result = Options.FromHttpRequest(request); result.Should().NotBe(null); }