feat(mgmt): /api/audit/{query,export} endpoints with permission gates (#23 M8)
This commit is contained in:
@@ -86,14 +86,25 @@ public static class AuthorizationPolicies
|
||||
/// Roles that satisfy <see cref="OperationalAudit"/>. Held in one place
|
||||
/// so the seed/docs and the policy stay in lockstep.
|
||||
/// </summary>
|
||||
internal static readonly string[] OperationalAuditRoles = { "Admin", "Audit", "AuditReadOnly" };
|
||||
/// <remarks>
|
||||
/// Public so the ManagementService HTTP API (#23 M8) — which gates the
|
||||
/// <c>/api/audit/*</c> routes with a manual Basic-Auth + LDAP role check
|
||||
/// rather than the ASP.NET authorization-policy pipeline — can reuse the
|
||||
/// exact same role set the <see cref="OperationalAudit"/> policy enforces.
|
||||
/// </remarks>
|
||||
public static readonly string[] OperationalAuditRoles = { "Admin", "Audit", "AuditReadOnly" };
|
||||
|
||||
/// <summary>
|
||||
/// Roles that satisfy <see cref="AuditExport"/>. A strict subset of
|
||||
/// <see cref="OperationalAuditRoles"/> — read access does NOT imply
|
||||
/// export permission.
|
||||
/// </summary>
|
||||
internal static readonly string[] AuditExportRoles = { "Admin", "Audit" };
|
||||
/// <remarks>
|
||||
/// Public for the same reason as <see cref="OperationalAuditRoles"/> —
|
||||
/// the ManagementService <c>/api/audit/export</c> route checks roles
|
||||
/// against this set directly.
|
||||
/// </remarks>
|
||||
public static readonly string[] AuditExportRoles = { "Admin", "Audit" };
|
||||
|
||||
public static IServiceCollection AddScadaLinkAuthorization(this IServiceCollection services)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,9 @@ public class LdapAuthService
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public async Task<LdapAuthResult> AuthenticateAsync(string username, string password, CancellationToken ct = default)
|
||||
// virtual: a test seam so HTTP-pipeline tests (e.g. the #23 M8 audit
|
||||
// endpoints) can substitute the LDAP bind without standing up a directory.
|
||||
public virtual async Task<LdapAuthResult> AuthenticateAsync(string username, string password, CancellationToken ct = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
return new LdapAuthResult(false, null, null, null, "Username is required.");
|
||||
|
||||
@@ -11,7 +11,9 @@ public class RoleMapper
|
||||
_securityRepository = securityRepository ?? throw new ArgumentNullException(nameof(securityRepository));
|
||||
}
|
||||
|
||||
public async Task<RoleMappingResult> MapGroupsToRolesAsync(
|
||||
// virtual: a test seam so HTTP-pipeline tests (e.g. the #23 M8 audit
|
||||
// endpoints) can substitute the LDAP-group→role resolution.
|
||||
public virtual async Task<RoleMappingResult> MapGroupsToRolesAsync(
|
||||
IReadOnlyList<string> ldapGroups,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user