mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-25 05:00:07 +00:00
5163d7d6a0
73 sites in 68 files built the query collection with HttpUtility.ParseQueryString(req.Url.Query), 15 files used req.Query and five mixed both. HttpRequestData.Query is that same call, cached per request, and the ASP.NET Core request type does not override it, so the change is behaviour-neutral. - QueryParamGuardTests: ParseQueryString in the Functions project is limited to a named baseline of three sites that parse something other than the request query. - A fact pins req.Query against HttpUtility.ParseQueryString (repeated keys, encoded values, caching) so a worker update that changes the implementation fails a test. - Test mocks that set Url answer Query through CallBase; a loose mock returns null. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
59 lines
2.5 KiB
C#
59 lines
2.5 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using AutopilotMonitor.Functions.Helpers;
|
|
using AutopilotMonitor.Functions.Services;
|
|
using Microsoft.Azure.Functions.Worker;
|
|
using Microsoft.Azure.Functions.Worker.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace AutopilotMonitor.Functions.Functions.Config
|
|
{
|
|
/// <summary>
|
|
/// Global-Admin view of what an agent of the tenant receives from GET agent/config right
|
|
/// now: the same <see cref="AgentConfigResolver"/> derivation the agent channel uses, minus
|
|
/// the per-device kill verdict (no device here). Drives the runtime column of the Tenant
|
|
/// Config Report, so the report cannot drift from the backend rules. Read-only, no
|
|
/// side effects, no ops event.
|
|
/// </summary>
|
|
public class GetEffectiveAgentConfigFunction
|
|
{
|
|
private readonly ILogger<GetEffectiveAgentConfigFunction> _logger;
|
|
private readonly AgentConfigResolver _resolver;
|
|
|
|
public GetEffectiveAgentConfigFunction(
|
|
ILogger<GetEffectiveAgentConfigFunction> logger,
|
|
AgentConfigResolver resolver)
|
|
{
|
|
_logger = logger;
|
|
_resolver = resolver;
|
|
}
|
|
|
|
[Function("GetEffectiveAgentConfig")]
|
|
public async Task<HttpResponseData> Run(
|
|
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "config/{tenantId}/effective-agent-config")] HttpRequestData req,
|
|
string tenantId)
|
|
{
|
|
try
|
|
{
|
|
// GlobalAdminOnly + RouteParam scoping enforced by PolicyEnforcementMiddleware.
|
|
var requestCtx = req.GetRequestContext();
|
|
|
|
// Optional ?agentVersion= selects the hash-oracle line like the agent's
|
|
// X-Agent-Version header would; absent → the current (V2) line, never the
|
|
// legacy fallback an absent header means on the agent channel.
|
|
var agentVersion = req.Query["agentVersion"];
|
|
var agentMajor = string.IsNullOrWhiteSpace(agentVersion)
|
|
? AgentConfigResolver.CurrentAgentMajor
|
|
: AgentConfigResolver.ParseAgentMajor(agentVersion);
|
|
|
|
var resolution = await _resolver.ResolveAsync(requestCtx.TargetTenantId, agentMajor);
|
|
return await req.OkAsync(resolution.Response);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return await req.InternalServerErrorAsync(_logger, ex, "GetEffectiveAgentConfig");
|
|
}
|
|
}
|
|
}
|
|
}
|