Skip to content

Commit 664520d

Browse files
author
smolny-marko
committed
~fix tenant regex validation
+add method to set defaultrequestheader +add testcases
1 parent 254f722 commit 664520d

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

src/Serilog.Sinks.Grafana.Loki/HttpClients/BaseLokiHttpClient.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class BaseLokiHttpClient : ILokiHttpClient
3333
/// <summary>
3434
/// Regex for Tenant ID validation.
3535
/// </summary>
36-
private static readonly Regex TenantIdValueRegex = new Regex(@"^[a-zA-Z0-9]*$");
36+
private static readonly Regex TenantIdValueRegex = new Regex(@"^(?!.*\.\.)(?!\.$)[a-zA-Z0-9!._*'()\-\u005F]*$");
3737

3838
/// <summary>
3939
/// Initializes a new instance of the <see cref="BaseLokiHttpClient"/> class.
@@ -91,6 +91,28 @@ public virtual void SetTenant(string? tenant)
9191
headers.Add(TenantHeader, tenant);
9292
}
9393

94+
/// <summary>
95+
/// Sets default headers for the HTTP client.
96+
/// Existing headers with the same key will not be overwritten.
97+
/// </summary>
98+
/// <param name="defaultHeaders">A dictionary of headers to set as default.</param>
99+
public virtual void SetDefaultHeaders(IDictionary<string, string> defaultHeaders)
100+
{
101+
if (defaultHeaders == null)
102+
{
103+
throw new ArgumentNullException(nameof(defaultHeaders), "Default headers cannot be null.");
104+
}
105+
106+
foreach (var header in defaultHeaders)
107+
{
108+
// Check if the header already exists before adding
109+
if (!HttpClient.DefaultRequestHeaders.Contains(header.Key))
110+
{
111+
HttpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
112+
}
113+
}
114+
}
115+
94116
/// <inheritdoc/>
95117
public virtual void Dispose() => HttpClient.Dispose();
96118

test/Serilog.Sinks.Grafana.Loki.Tests/HttpClientsTests/BaseLokiHttpClientTests.cs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,35 @@ public void AuthorizationHeaderShouldNotBeSetWithoutCredentials()
5151
[Fact]
5252
public void TenantHeaderShouldBeCorrect()
5353
{
54-
var tenantId = "lokitenant";
55-
using var client = new TestLokiHttpClient();
56-
57-
client.SetTenant(tenantId);
58-
59-
var tenantHeaders = client.Client.DefaultRequestHeaders.GetValues("X-Scope-OrgID").ToList();
60-
tenantHeaders.ShouldBeEquivalentTo(new List<string> {"lokitenant"});
54+
// List of test cases with tenant IDs and their expected validity
55+
var validTenantIds = new List<(string TenantId, bool IsValid)>
56+
{
57+
("tenant123", true), // Only alphanumeric characters
58+
("tenant-123", true), // Valid special characters
59+
("tenant..123", false), // Double period ".." is not allowed
60+
(".", false), // Single period is not allowed
61+
("tenant!_*.123'()", true), // All allowed special characters
62+
("tenant-123...", false), // Multiple periods at the end are not allowed
63+
("tenant123456...test", false), // Ends with a period "."
64+
("tenant1234567890!@", false), // "@" is not allowed
65+
};
66+
67+
foreach (var (tenantId, isValid) in validTenantIds)
68+
{
69+
using var client = new TestLokiHttpClient();
70+
71+
if (isValid)
72+
{
73+
client.SetTenant(tenantId);
74+
75+
var tenantHeaders = client.Client.DefaultRequestHeaders.GetValues("X-Scope-OrgID").ToList();
76+
tenantHeaders.ShouldBeEquivalentTo(new List<string> { tenantId });
77+
}
78+
else
79+
{
80+
Should.Throw<ArgumentException>(() => client.SetTenant(tenantId));
81+
}
82+
}
6183
}
6284

6385
[Fact]
@@ -78,4 +100,24 @@ public void TenantHeaderShouldThrowAnExceptionOnTenantIdAgainstRule()
78100

79101
Should.Throw<ArgumentException>(() => client.SetTenant(tenantId));
80102
}
103+
104+
[Fact]
105+
public void SetDefaultHeadersShouldSetHeaderCorrectly()
106+
{
107+
// Arrange
108+
using var httpClient = new HttpClient();
109+
var client = new TestLokiHttpClient(httpClient);
110+
111+
var headersToSet = new Dictionary<string, string>
112+
{
113+
{ "Custom-Header", "HeaderValue" }
114+
};
115+
116+
// Act
117+
client.SetDefaultHeaders(headersToSet);
118+
119+
// Assert
120+
httpClient.DefaultRequestHeaders.Contains("Custom-Header").ShouldBeTrue();
121+
httpClient.DefaultRequestHeaders.GetValues("Custom-Header").ShouldBe(new[] { "HeaderValue" });
122+
}
81123
}

0 commit comments

Comments
 (0)