Skip to content

Commit 76db65c

Browse files
CopilotJerryNixon
andcommitted
Fix currentRole fallback logic and exclude from cached response
Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
1 parent 11038dd commit 76db65c

2 files changed

Lines changed: 24 additions & 19 deletions

File tree

src/Service/HealthCheck/ComprehensiveHealthReportResponseWriter.cs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT License.
33

44
using System;
5-
using System.IO;
65
using System.Text.Json;
76
using System.Threading;
87
using System.Threading.Tasks;
@@ -85,34 +84,33 @@ public async Task WriteResponseAsync(HttpContext context)
8584
return;
8685
}
8786

88-
string? response;
8987
// Check if the cache is enabled
9088
if (config.CacheTtlSecondsForHealthReport > 0)
9189
{
90+
ComprehensiveHealthCheckReport? report = null;
9291
try
9392
{
94-
response = await _cache.GetOrSetAsync<string?>(
93+
report = await _cache.GetOrSetAsync<ComprehensiveHealthCheckReport?>(
9594
key: CACHE_KEY,
96-
async (FusionCacheFactoryExecutionContext<string?> ctx, CancellationToken ct) =>
95+
async (FusionCacheFactoryExecutionContext<ComprehensiveHealthCheckReport?> ctx, CancellationToken ct) =>
9796
{
98-
string? response = await ExecuteHealthCheckAsync(config).ConfigureAwait(false);
97+
ComprehensiveHealthCheckReport? r = await _healthCheckHelper.GetHealthCheckResponseAsync(config).ConfigureAwait(false);
9998
ctx.Options.SetDuration(TimeSpan.FromSeconds(config.CacheTtlSecondsForHealthReport));
100-
return response;
99+
return r;
101100
});
102101

103102
_logger.LogTrace($"Health check response is fetched from cache with key: {CACHE_KEY} and TTL: {config.CacheTtlSecondsForHealthReport} seconds.");
104103
}
105104
catch (Exception ex)
106105
{
107-
response = null; // Set response to null in case of an error
108106
_logger.LogError($"Error in caching health check response: {ex.Message}");
109107
}
110108

111109
// Ensure cachedResponse is not null before calling WriteAsync
112-
if (response != null)
110+
if (report != null)
113111
{
114-
// Return the cached or newly generated response
115-
await context.Response.WriteAsync(response);
112+
// Set currentRole per-request (not cached) so each caller sees their own role
113+
await context.Response.WriteAsync(SerializeReport(report with { CurrentRole = _healthCheckHelper.GetCurrentRole() }));
116114
}
117115
else
118116
{
@@ -124,9 +122,9 @@ public async Task WriteResponseAsync(HttpContext context)
124122
}
125123
else
126124
{
127-
response = await ExecuteHealthCheckAsync(config).ConfigureAwait(false);
125+
ComprehensiveHealthCheckReport report = await _healthCheckHelper.GetHealthCheckResponseAsync(config).ConfigureAwait(false);
128126
// Return the newly generated response
129-
await context.Response.WriteAsync(response);
127+
await context.Response.WriteAsync(SerializeReport(report with { CurrentRole = _healthCheckHelper.GetCurrentRole() }));
130128
}
131129
}
132130
else
@@ -139,13 +137,10 @@ public async Task WriteResponseAsync(HttpContext context)
139137
return;
140138
}
141139

142-
private async Task<string> ExecuteHealthCheckAsync(RuntimeConfig config)
140+
private string SerializeReport(ComprehensiveHealthCheckReport report)
143141
{
144-
ComprehensiveHealthCheckReport dabHealthCheckReport = await _healthCheckHelper.GetHealthCheckResponseAsync(config);
145-
string response = JsonSerializer.Serialize(dabHealthCheckReport, options: new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull });
146-
_logger.LogTrace($"Health check response writer writing status as: {dabHealthCheckReport.Status}");
147-
148-
return response;
142+
_logger.LogTrace($"Health check response writer writing status as: {report.Status}");
143+
return JsonSerializer.Serialize(report, options: new JsonSerializerOptions { WriteIndented = true, DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull });
149144
}
150145
}
151146
}

src/Service/HealthCheck/HealthCheckHelper.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ public async Task<ComprehensiveHealthCheckReport> GetHealthCheckResponseAsync(Ru
5858
ComprehensiveHealthCheckReport comprehensiveHealthCheckReport = new();
5959
UpdateVersionAndAppName(ref comprehensiveHealthCheckReport);
6060
UpdateTimestampOfResponse(ref comprehensiveHealthCheckReport);
61-
comprehensiveHealthCheckReport.CurrentRole = AuthorizationResolver.ROLE_ANONYMOUS;
6261
UpdateDabConfigurationDetails(ref comprehensiveHealthCheckReport, runtimeConfig);
6362
await UpdateHealthCheckDetailsAsync(comprehensiveHealthCheckReport, runtimeConfig);
6463
UpdateOverallHealthStatus(ref comprehensiveHealthCheckReport);
@@ -88,6 +87,17 @@ public void StoreIncomingRoleHeader(HttpContext httpContext)
8887
}
8988
}
9089

90+
// Returns the effective role for the current request.
91+
// Falls back to "authenticated" if a bearer token is present, or "anonymous" otherwise.
92+
public string GetCurrentRole()
93+
{
94+
return !string.IsNullOrEmpty(_incomingRoleHeader)
95+
? _incomingRoleHeader
96+
: !string.IsNullOrEmpty(_incomingRoleToken)
97+
? AuthorizationResolver.ROLE_AUTHENTICATED
98+
: AuthorizationResolver.ROLE_ANONYMOUS;
99+
}
100+
91101
/// <summary>
92102
/// Checks if the incoming request is allowed to access the health check endpoint.
93103
/// Anonymous requests are only allowed in Development Mode.

0 commit comments

Comments
 (0)