using System.Security.Claims; using Data.SeaHavenIndustries; using SeaHaven.Services.Exceptions; namespace SeaHaven.Services.Helpers { /// /// Claims-derived authorization for work-order media read/mutations. /// True multi-tenant CustomerId/TenantId is not modeled on WorkOrder/JWT; /// scope is role + Assigned () for Technician. /// public static class WorkOrderMediaAuthorization { private static readonly string[] StaffRoles = { "Admin", "Manager", "Dispatcher", "Supervisor" }; public static void EnsureCanRead(ClaimsPrincipal user, string? actorId) { EnsureAuthenticated(user, actorId, "You are not allowed to view work order media."); if (IsStaff(user) || user.IsInRole("User")) return; throw Forbidden("You are not allowed to view work order media."); } public static void EnsureCanMutate(ClaimsPrincipal user, string? actorId) { EnsureAuthenticated(user, actorId); if (IsStaff(user) || user.IsInRole("User")) return; throw Forbidden(); } public static void EnsureCanDelete(ClaimsPrincipal user, string? actorId) { EnsureAuthenticated(user, actorId); // Technician (User) may upload/categorize assigned media but not delete. if (IsStaff(user)) return; throw Forbidden(); } /// /// Staff: any in-scope (non-deleted/non-template) work order. /// Technician: only work orders assigned to the caller. Out-of-scope → NotFound (no disclosure). /// public static void EnsureWorkOrderInCallerScope( ClaimsPrincipal user, string actorId, WorkOrder workOrder) { if (IsStaff(user)) return; if (user.IsInRole("User") && string.Equals(workOrder.AssignTo, actorId, StringComparison.Ordinal)) { return; } throw new WorkOrderBoardValidationException("NotFound", "Work order not found."); } private static void EnsureAuthenticated( ClaimsPrincipal user, string? actorId, string? forbiddenMessage = null) { if (user is null || !(user.Identity?.IsAuthenticated ?? false) || string.IsNullOrWhiteSpace(actorId)) { throw Forbidden(forbiddenMessage); } } private static bool IsStaff(ClaimsPrincipal user) => StaffRoles.Any(user.IsInRole); private static WorkOrderBoardValidationException Forbidden(string? message = null) => new( "Forbidden", message ?? "You are not allowed to mutate work order media."); } }