Enhanced id validation, made url building more robust

This commit is contained in:
2024-11-10 16:43:56 +01:00
parent 42455e596b
commit e561ad8ee7
3 changed files with 31 additions and 3 deletions

View File

@@ -46,6 +46,21 @@ namespace Cloudflare.Tests.Extensions
// Assert - ArgumentOutOfRangeException // Assert - ArgumentOutOfRangeException
} }
[DataTestMethod]
[DataRow("023e105f4ecef8ad9ca31a8372d0c35")]
[DataRow("023e105f4ecef8ad9ca31a8372d0C353")]
[DataRow("023e105f4ecef8ad9ca31a8372d0y353")]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowArgumentExceptionForValidateId(string id)
{
// Arrange
// Act
id.ValidateCloudflareId();
// Assert - ArgumentException
}
[TestMethod] [TestMethod]
public void ShouldValidateName() public void ShouldValidateName()
{ {

View File

@@ -198,9 +198,12 @@ namespace AMWD.Net.Api.Cloudflare
}; };
} }
// Ensure a clean base URL
string baseUrl = _clientOptions.BaseUrl.Trim().TrimEnd('/');
var client = new HttpClient(handler, true) var client = new HttpClient(handler, true)
{ {
BaseAddress = new Uri(_clientOptions.BaseUrl), BaseAddress = new Uri(baseUrl + '/'),
Timeout = _clientOptions.Timeout, Timeout = _clientOptions.Timeout,
}; };
@@ -259,6 +262,8 @@ namespace AMWD.Net.Api.Cloudflare
private string BuildRequestUrl(string requestPath, IQueryParameterFilter? queryFilter = null) private string BuildRequestUrl(string requestPath, IQueryParameterFilter? queryFilter = null)
{ {
// Ensure a clean request path
string reqPath = requestPath.Trim().TrimStart('/');
var dict = new Dictionary<string, string>(); var dict = new Dictionary<string, string>();
if (_clientOptions.DefaultQueryParams.Count > 0) if (_clientOptions.DefaultQueryParams.Count > 0)
@@ -275,12 +280,12 @@ namespace AMWD.Net.Api.Cloudflare
} }
if (dict.Count == 0) if (dict.Count == 0)
return requestPath; return reqPath;
string[] param = dict.Select(kvp => $"{kvp.Key}={WebUtility.UrlEncode(kvp.Value)}").ToArray(); string[] param = dict.Select(kvp => $"{kvp.Key}={WebUtility.UrlEncode(kvp.Value)}").ToArray();
string query = string.Join("&", param); string query = string.Join("&", param);
return $"{requestPath}?{query}"; return $"{reqPath}?{query}";
} }
private static HttpContent? ConvertRequest<T>(T request) private static HttpContent? ConvertRequest<T>(T request)

View File

@@ -8,6 +8,7 @@ namespace AMWD.Net.Api.Cloudflare
/// </summary> /// </summary>
public static class StringExtensions public static class StringExtensions
{ {
private static readonly Regex _idCheckRegex = new(@"^[0-9a-f]{32}$", RegexOptions.Compiled);
private static readonly Regex _emailCheckRegex = new(@"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$", RegexOptions.Compiled); private static readonly Regex _emailCheckRegex = new(@"^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$", RegexOptions.Compiled);
/// <summary> /// <summary>
@@ -26,6 +27,13 @@ namespace AMWD.Net.Api.Cloudflare
if (id.Length > 32) if (id.Length > 32)
throw new ArgumentOutOfRangeException(nameof(id)); throw new ArgumentOutOfRangeException(nameof(id));
if (!_idCheckRegex.IsMatch(id))
throw new ArgumentException("Invalid Cloudflare ID", nameof(id));
// TODO: It seems like Cloudflare IDs are GUIDs - should be verified.
//if (!Guid.TryParse(id, out _))
// throw new ArgumentException("Invalid Cloudflare ID", nameof(id));
} }
/// <summary> /// <summary>