diff --git a/src/ScadaLink.CentralUI/Audit/AuditExportEndpoints.cs b/src/ScadaLink.CentralUI/Audit/AuditExportEndpoints.cs index 66ed746..fdf34f6 100644 --- a/src/ScadaLink.CentralUI/Audit/AuditExportEndpoints.cs +++ b/src/ScadaLink.CentralUI/Audit/AuditExportEndpoints.cs @@ -23,9 +23,12 @@ namespace ScadaLink.CentralUI.Audit; /// /// /// -/// The route is admin-gated to mirror the NavMenu (RequireAdmin wraps -/// the Audit section). The query-string parser silently drops unrecognised -/// values to match the page-level parser in +/// The route is gated on the +/// policy (#23 M7-T15 / Bundle G) so only roles with the bulk-export +/// permission can pull a CSV — the page-level +/// gate is read-only +/// and intentionally narrower. The query-string parser silently drops +/// unrecognised values to match the page-level parser in /// AuditLogPage.ApplyQueryStringFilters — an unknown enum value yields /// the same "no constraint" outcome rather than a 400. /// @@ -43,7 +46,7 @@ public static class AuditExportEndpoints public static IEndpointRouteBuilder MapAuditExportEndpoints(this IEndpointRouteBuilder endpoints) { endpoints.MapGet("/api/centralui/audit/export", HandleExportAsync) - .RequireAuthorization(AuthorizationPolicies.RequireAdmin); + .RequireAuthorization(AuthorizationPolicies.AuditExport); return endpoints; } diff --git a/src/ScadaLink.CentralUI/Components/Layout/NavMenu.razor b/src/ScadaLink.CentralUI/Components/Layout/NavMenu.razor index 798d306..1c05b7e 100644 --- a/src/ScadaLink.CentralUI/Components/Layout/NavMenu.razor +++ b/src/ScadaLink.CentralUI/Components/Layout/NavMenu.razor @@ -108,11 +108,15 @@ - @* Audit — Admin only. Hosts the new Audit Log page (#23 M7) - and the renamed Configuration Audit Log (IAuditService - config-change viewer). Both items are Admin-gated, so - the section header sits inside the same policy block. *@ - + @* Audit — gated on the OperationalAudit policy (#23 M7-T15 + / Bundle G). Hosts the new Audit Log page (#23 M7) and + the renamed Configuration Audit Log (IAuditService + config-change viewer). Both items share the same gate, + so the section header sits inside the same policy block: + a non-audit user does not even see the heading. + OperationalAudit is satisfied by the Admin, Audit, and + AuditReadOnly roles. *@ +