Skip to content

Commit

Permalink
Merge pull request #131 from twilio-labs/trim-trailing-slash
Browse files Browse the repository at this point in the history
Trim trailing slash from BaseUrlOverride
  • Loading branch information
Swimburger authored May 11, 2023
2 parents 0f1881c + d58df90 commit f02901d
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 34 deletions.
10 changes: 5 additions & 5 deletions src/Twilio.AspNet.Core.UnitTests/ValidateTwilioRequestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ValidateTwilioRequestTests
{
AuthToken = "My Twilio:RequestValidation:AuthToken",
AllowLocal = false,
BaseUrlOverride = "https://example.localhost"
BaseUrlOverride = "https://example.localhost/"
}
};

Expand Down Expand Up @@ -55,7 +55,7 @@ public async Task Validate_Request_Successfully(Type type)
});
c.Request.Headers.Add(
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
ValidTwilioOptions.RequestValidation.AuthToken,
c.Request.Form
)
Expand Down Expand Up @@ -123,7 +123,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
});
c.Request.Headers.Add(
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
ValidTwilioOptions.RequestValidation.AuthToken,
c.Request.Form
)
Expand All @@ -138,7 +138,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
{
AuthToken = "My Twilio:RequestValidation:Updated Auth Token",
AllowLocal = false,
BaseUrlOverride = "https://example.local"
BaseUrlOverride = "https://example.local/"
}
};

Expand All @@ -160,7 +160,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
});
c.Request.Headers.Add(
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
$"{updatedOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
$"{updatedOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
updatedOptions.RequestValidation.AuthToken,
c.Request.Form
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,17 @@ public static IServiceCollection AddTwilioRequestValidation(this IServiceCollect

var requestValidationSection = config.GetSection("Twilio:RequestValidation");
requestValidationSection.Bind(options);
if (options.AuthToken == "") options.AuthToken = null;
if (options.BaseUrlOverride == "") options.BaseUrlOverride = null;

var authTokenFallback = twilioSection["AuthToken"];
if (options.AuthToken == null && string.IsNullOrEmpty(authTokenFallback) == false)
if (string.IsNullOrEmpty(options.AuthToken) && !string.IsNullOrEmpty(authTokenFallback))
options.AuthToken = authTokenFallback;
});

optionsBuilder.Services.AddSingleton<
IOptionsChangeTokenSource<TwilioRequestValidationOptions>,
ConfigurationChangeTokenSource<TwilioRequestValidationOptions>
>();

Validate(optionsBuilder);

Sanitize(optionsBuilder);
Validate(optionsBuilder);
return services;
}

Expand All @@ -46,6 +42,7 @@ IConfiguration namedConfigurationSection
var optionsBuilder = services.AddOptions<TwilioRequestValidationOptions>();
optionsBuilder.Bind(namedConfigurationSection);
Validate(optionsBuilder);
Sanitize(optionsBuilder);
return services;
}

Expand All @@ -55,14 +52,15 @@ public static IServiceCollection AddTwilioRequestValidation(
Action<TwilioRequestValidationOptions> configureOptions
)
=> AddTwilioRequestValidation(services, (_, options) => configureOptions(options));

public static IServiceCollection AddTwilioRequestValidation(
this IServiceCollection services,
Action<IServiceProvider, TwilioRequestValidationOptions> configureOptions
)
{
var optionsBuilder = services.AddOptions<TwilioRequestValidationOptions>();
optionsBuilder.Configure<IServiceProvider>((options, provider) => configureOptions(provider, options));
Sanitize(optionsBuilder);
Validate(optionsBuilder);
return services;
}
Expand All @@ -79,11 +77,21 @@ TwilioRequestValidationOptions options
optionsToConfigure.AllowLocal = options.AllowLocal;
optionsToConfigure.BaseUrlOverride = options.BaseUrlOverride;
});

Sanitize(optionsBuilder);
Validate(optionsBuilder);
return services;
}

private static void Sanitize(OptionsBuilder<TwilioRequestValidationOptions> optionsBuilder)
{
optionsBuilder.PostConfigure(options =>
{
if (options.AuthToken == "") options.AuthToken = null;
if (options.BaseUrlOverride == "") options.BaseUrlOverride = null;
if (options.BaseUrlOverride != null) options.BaseUrlOverride = options.BaseUrlOverride.TrimEnd('/');
});
}

private static void Validate(OptionsBuilder<TwilioRequestValidationOptions> optionsBuilder)
{
optionsBuilder.Validate(
Expand Down
3 changes: 2 additions & 1 deletion src/Twilio.AspNet.Core/RequestValidationHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
Expand Down
30 changes: 15 additions & 15 deletions src/Twilio.AspNet.Core/TwilioClientDependencyInjectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ public static class TwilioClientDependencyInjectionExtensions
public static IServiceCollection AddTwilioClient(this IServiceCollection services)
{
var optionsBuilder = services.AddOptions<TwilioClientOptions>();

ConfigureDefaultOptions(optionsBuilder);
PostConfigure(optionsBuilder);
Validate(optionsBuilder);
AddServices(services);

return services;
}

Expand All @@ -34,7 +32,6 @@ IConfiguration namedConfigurationSection
PostConfigure(optionsBuilder);
Validate(optionsBuilder);
AddServices(services);

return services;
}

Expand All @@ -51,12 +48,10 @@ Action<IServiceProvider, TwilioClientOptions> configureOptions
)
{
var optionsBuilder = services.AddOptions<TwilioClientOptions>();

optionsBuilder.Configure<IServiceProvider>((options, provider) => configureOptions(provider, options));
PostConfigure(optionsBuilder);
Validate(optionsBuilder);
AddServices(services);

return services;
}

Expand All @@ -82,7 +77,6 @@ TwilioClientOptions options
PostConfigure(optionsBuilder);
Validate(optionsBuilder);
AddServices(services);

return services;
}

Expand All @@ -103,16 +97,9 @@ private static void ConfigureDefaultOptions(OptionsBuilder<TwilioClientOptions>
}

clientSection.Bind(options);
if (options.AccountSid == "") options.AccountSid = null;
if (options.AuthToken == "") options.AuthToken = null;
if (options.ApiKeySid == "") options.ApiKeySid = null;
if (options.ApiKeySecret == "") options.ApiKeySecret = null;
if (options.Region == "") options.Region = null;
if (options.Edge == "") options.Edge = null;
if (options.LogLevel == "") options.LogLevel = null;

var authTokenFallback = twilioSection["AuthToken"];
if (options.AuthToken == null && string.IsNullOrEmpty(authTokenFallback) == false)
if (string.IsNullOrEmpty(options.AuthToken) && !string.IsNullOrEmpty(authTokenFallback))
options.AuthToken = authTokenFallback;
});
optionsBuilder.Services.AddSingleton<
Expand All @@ -122,7 +109,9 @@ private static void ConfigureDefaultOptions(OptionsBuilder<TwilioClientOptions>
}

private static void PostConfigure(OptionsBuilder<TwilioClientOptions> optionsBuilder)
=> optionsBuilder.PostConfigure(ConfigureCredentialType);
=> optionsBuilder
.PostConfigure(Sanitize)
.PostConfigure(ConfigureCredentialType);

private static void AddServices(IServiceCollection services)
{
Expand All @@ -137,6 +126,17 @@ private static void AddServices(IServiceCollection services)
services.AddScoped<TwilioRestClient>(CreateTwilioClient);
}

private static void Sanitize(TwilioClientOptions options)
{
if (options.AccountSid == "") options.AccountSid = null;
if (options.AuthToken == "") options.AuthToken = null;
if (options.ApiKeySid == "") options.ApiKeySid = null;
if (options.ApiKeySecret == "") options.ApiKeySecret = null;
if (options.Region == "") options.Region = null;
if (options.Edge == "") options.Edge = null;
if (options.LogLevel == "") options.LogLevel = null;
}

private static void Validate(OptionsBuilder<TwilioClientOptions> optionsBuilder)
{
optionsBuilder.Validate(
Expand Down
8 changes: 4 additions & 4 deletions src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ protected virtual void ConfigureProperties()
?? requestValidationConfiguration?.AuthToken
?? throw new Exception("Twilio Auth Token not configured");

BaseUrlOverride = appSettings["twilio:requestValidation:baseUrlOverride"]
?? requestValidationConfiguration?.BaseUrlOverride;
if (BaseUrlOverride != null) BaseUrlOverride = BaseUrlOverride.TrimEnd('/');
BaseUrlOverride = (appSettings["twilio:requestValidation:baseUrlOverride"]
?? requestValidationConfiguration?.BaseUrlOverride)
?.TrimEnd('/');

var allowLocalAppSetting = appSettings["twilio:requestValidation:allowLocal"];
AllowLocal = allowLocalAppSetting != null
? bool.Parse(allowLocalAppSetting)
: requestValidationConfiguration?.AllowLocal
?? false;
?? false;
}

public override void OnActionExecuting(ActionExecutingContext filterContext)
Expand Down

0 comments on commit f02901d

Please sign in to comment.