Skip to content

Commit f02901d

Browse files
authored
Merge pull request #131 from twilio-labs/trim-trailing-slash
Trim trailing slash from BaseUrlOverride
2 parents 0f1881c + d58df90 commit f02901d

File tree

5 files changed

+43
-34
lines changed

5 files changed

+43
-34
lines changed

Diff for: src/Twilio.AspNet.Core.UnitTests/ValidateTwilioRequestTests.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class ValidateTwilioRequestTests
2727
{
2828
AuthToken = "My Twilio:RequestValidation:AuthToken",
2929
AllowLocal = false,
30-
BaseUrlOverride = "https://example.localhost"
30+
BaseUrlOverride = "https://example.localhost/"
3131
}
3232
};
3333

@@ -55,7 +55,7 @@ public async Task Validate_Request_Successfully(Type type)
5555
});
5656
c.Request.Headers.Add(
5757
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
58-
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
58+
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
5959
ValidTwilioOptions.RequestValidation.AuthToken,
6060
c.Request.Form
6161
)
@@ -123,7 +123,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
123123
});
124124
c.Request.Headers.Add(
125125
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
126-
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
126+
$"{ValidTwilioOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
127127
ValidTwilioOptions.RequestValidation.AuthToken,
128128
c.Request.Form
129129
)
@@ -138,7 +138,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
138138
{
139139
AuthToken = "My Twilio:RequestValidation:Updated Auth Token",
140140
AllowLocal = false,
141-
BaseUrlOverride = "https://example.local"
141+
BaseUrlOverride = "https://example.local/"
142142
}
143143
};
144144

@@ -160,7 +160,7 @@ public async Task Validate_Request_With_ReloadOnChange(Type type)
160160
});
161161
c.Request.Headers.Add(
162162
"X-Twilio-Signature", ValidationHelper.CalculateSignature(
163-
$"{updatedOptions.RequestValidation.BaseUrlOverride}{c.Request.Path}",
163+
$"{updatedOptions.RequestValidation.BaseUrlOverride.TrimEnd('/')}{c.Request.Path}",
164164
updatedOptions.RequestValidation.AuthToken,
165165
c.Request.Form
166166
)

Diff for: src/Twilio.AspNet.Core/RequestValidationDependencyInjectionExtensions.cs

+17-9
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,17 @@ public static IServiceCollection AddTwilioRequestValidation(this IServiceCollect
2020

2121
var requestValidationSection = config.GetSection("Twilio:RequestValidation");
2222
requestValidationSection.Bind(options);
23-
if (options.AuthToken == "") options.AuthToken = null;
24-
if (options.BaseUrlOverride == "") options.BaseUrlOverride = null;
2523

2624
var authTokenFallback = twilioSection["AuthToken"];
27-
if (options.AuthToken == null && string.IsNullOrEmpty(authTokenFallback) == false)
25+
if (string.IsNullOrEmpty(options.AuthToken) && !string.IsNullOrEmpty(authTokenFallback))
2826
options.AuthToken = authTokenFallback;
2927
});
30-
3128
optionsBuilder.Services.AddSingleton<
3229
IOptionsChangeTokenSource<TwilioRequestValidationOptions>,
3330
ConfigurationChangeTokenSource<TwilioRequestValidationOptions>
3431
>();
35-
36-
Validate(optionsBuilder);
37-
32+
Sanitize(optionsBuilder);
33+
Validate(optionsBuilder);
3834
return services;
3935
}
4036

@@ -46,6 +42,7 @@ IConfiguration namedConfigurationSection
4642
var optionsBuilder = services.AddOptions<TwilioRequestValidationOptions>();
4743
optionsBuilder.Bind(namedConfigurationSection);
4844
Validate(optionsBuilder);
45+
Sanitize(optionsBuilder);
4946
return services;
5047
}
5148

@@ -55,14 +52,15 @@ public static IServiceCollection AddTwilioRequestValidation(
5552
Action<TwilioRequestValidationOptions> configureOptions
5653
)
5754
=> AddTwilioRequestValidation(services, (_, options) => configureOptions(options));
58-
55+
5956
public static IServiceCollection AddTwilioRequestValidation(
6057
this IServiceCollection services,
6158
Action<IServiceProvider, TwilioRequestValidationOptions> configureOptions
6259
)
6360
{
6461
var optionsBuilder = services.AddOptions<TwilioRequestValidationOptions>();
6562
optionsBuilder.Configure<IServiceProvider>((options, provider) => configureOptions(provider, options));
63+
Sanitize(optionsBuilder);
6664
Validate(optionsBuilder);
6765
return services;
6866
}
@@ -79,11 +77,21 @@ TwilioRequestValidationOptions options
7977
optionsToConfigure.AllowLocal = options.AllowLocal;
8078
optionsToConfigure.BaseUrlOverride = options.BaseUrlOverride;
8179
});
82-
80+
Sanitize(optionsBuilder);
8381
Validate(optionsBuilder);
8482
return services;
8583
}
8684

85+
private static void Sanitize(OptionsBuilder<TwilioRequestValidationOptions> optionsBuilder)
86+
{
87+
optionsBuilder.PostConfigure(options =>
88+
{
89+
if (options.AuthToken == "") options.AuthToken = null;
90+
if (options.BaseUrlOverride == "") options.BaseUrlOverride = null;
91+
if (options.BaseUrlOverride != null) options.BaseUrlOverride = options.BaseUrlOverride.TrimEnd('/');
92+
});
93+
}
94+
8795
private static void Validate(OptionsBuilder<TwilioRequestValidationOptions> optionsBuilder)
8896
{
8997
optionsBuilder.Validate(

Diff for: src/Twilio.AspNet.Core/RequestValidationHelper.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Net;
45
using System.Threading.Tasks;

Diff for: src/Twilio.AspNet.Core/TwilioClientDependencyInjectionExtensions.cs

+15-15
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ public static class TwilioClientDependencyInjectionExtensions
1515
public static IServiceCollection AddTwilioClient(this IServiceCollection services)
1616
{
1717
var optionsBuilder = services.AddOptions<TwilioClientOptions>();
18-
1918
ConfigureDefaultOptions(optionsBuilder);
2019
PostConfigure(optionsBuilder);
2120
Validate(optionsBuilder);
2221
AddServices(services);
23-
2422
return services;
2523
}
2624

@@ -34,7 +32,6 @@ IConfiguration namedConfigurationSection
3432
PostConfigure(optionsBuilder);
3533
Validate(optionsBuilder);
3634
AddServices(services);
37-
3835
return services;
3936
}
4037

@@ -51,12 +48,10 @@ Action<IServiceProvider, TwilioClientOptions> configureOptions
5148
)
5249
{
5350
var optionsBuilder = services.AddOptions<TwilioClientOptions>();
54-
5551
optionsBuilder.Configure<IServiceProvider>((options, provider) => configureOptions(provider, options));
5652
PostConfigure(optionsBuilder);
5753
Validate(optionsBuilder);
5854
AddServices(services);
59-
6055
return services;
6156
}
6257

@@ -82,7 +77,6 @@ TwilioClientOptions options
8277
PostConfigure(optionsBuilder);
8378
Validate(optionsBuilder);
8479
AddServices(services);
85-
8680
return services;
8781
}
8882

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

10599
clientSection.Bind(options);
106-
if (options.AccountSid == "") options.AccountSid = null;
107-
if (options.AuthToken == "") options.AuthToken = null;
108-
if (options.ApiKeySid == "") options.ApiKeySid = null;
109-
if (options.ApiKeySecret == "") options.ApiKeySecret = null;
110-
if (options.Region == "") options.Region = null;
111-
if (options.Edge == "") options.Edge = null;
112-
if (options.LogLevel == "") options.LogLevel = null;
113100

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

124111
private static void PostConfigure(OptionsBuilder<TwilioClientOptions> optionsBuilder)
125-
=> optionsBuilder.PostConfigure(ConfigureCredentialType);
112+
=> optionsBuilder
113+
.PostConfigure(Sanitize)
114+
.PostConfigure(ConfigureCredentialType);
126115

127116
private static void AddServices(IServiceCollection services)
128117
{
@@ -137,6 +126,17 @@ private static void AddServices(IServiceCollection services)
137126
services.AddScoped<TwilioRestClient>(CreateTwilioClient);
138127
}
139128

129+
private static void Sanitize(TwilioClientOptions options)
130+
{
131+
if (options.AccountSid == "") options.AccountSid = null;
132+
if (options.AuthToken == "") options.AuthToken = null;
133+
if (options.ApiKeySid == "") options.ApiKeySid = null;
134+
if (options.ApiKeySecret == "") options.ApiKeySecret = null;
135+
if (options.Region == "") options.Region = null;
136+
if (options.Edge == "") options.Edge = null;
137+
if (options.LogLevel == "") options.LogLevel = null;
138+
}
139+
140140
private static void Validate(OptionsBuilder<TwilioClientOptions> optionsBuilder)
141141
{
142142
optionsBuilder.Validate(

Diff for: src/Twilio.AspNet.Mvc/ValidateRequestAttribute.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ protected virtual void ConfigureProperties()
4242
?? requestValidationConfiguration?.AuthToken
4343
?? throw new Exception("Twilio Auth Token not configured");
4444

45-
BaseUrlOverride = appSettings["twilio:requestValidation:baseUrlOverride"]
46-
?? requestValidationConfiguration?.BaseUrlOverride;
47-
if (BaseUrlOverride != null) BaseUrlOverride = BaseUrlOverride.TrimEnd('/');
45+
BaseUrlOverride = (appSettings["twilio:requestValidation:baseUrlOverride"]
46+
?? requestValidationConfiguration?.BaseUrlOverride)
47+
?.TrimEnd('/');
4848

4949
var allowLocalAppSetting = appSettings["twilio:requestValidation:allowLocal"];
5050
AllowLocal = allowLocalAppSetting != null
5151
? bool.Parse(allowLocalAppSetting)
5252
: requestValidationConfiguration?.AllowLocal
53-
?? false;
53+
?? false;
5454
}
5555

5656
public override void OnActionExecuting(ActionExecutingContext filterContext)

0 commit comments

Comments
 (0)