using System.Security.Claims; using SeaHaven.DataServices.Interfaces; using SeaHaven.Services.Exceptions; using SeaHaven.Services.Helpers; using SeaHaven.Services.Interfaces; namespace SeaHaven.Services.Implementation { public class WorkOrderAccountResolver : IWorkOrderAccountResolver { private readonly IAccountDataService _accounts; private readonly ILocationDataService _locations; public WorkOrderAccountResolver(IAccountDataService accounts, ILocationDataService locations) { _accounts = accounts; _locations = locations; } public int? ResolveAccountFilter(ClaimsPrincipal user) { return WorkOrderMediaAuthorization.ResolveMediaScope(user) switch { MediaAccountScope.Account account => account.AccountId, MediaAccountScope.OrgWide => null, _ => throw new WorkOrderBoardValidationException( "Forbidden", "You are not allowed to access work orders without account scope.") }; } public async Task ResolveForAuthenticatedCreateAsync( ClaimsPrincipal user, string? customer, CancellationToken cancellationToken = default) { switch (WorkOrderMediaAuthorization.ResolveMediaScope(user)) { case MediaAccountScope.Account account: return account.AccountId; case MediaAccountScope.OrgWide: return await ResolveRequiredFromCustomerAsync(customer, cancellationToken); default: throw new WorkOrderBoardValidationException( "Forbidden", "You are not allowed to create work orders without account scope."); } } public async Task ResolveForBoardCreateAsync( ClaimsPrincipal user, int? locationId, CancellationToken cancellationToken = default) { if (locationId is not int id || id <= 0) { throw new WorkOrderBoardValidationException( "InvalidValue", "locationId is required."); } var (exists, locationAccountId) = await _locations.GetAccountScopeAsync(id, cancellationToken); if (!exists) { throw new WorkOrderBoardValidationException( "NotFound", "Location was not found."); } if (locationAccountId is not int resolvedAccountId) { throw new WorkOrderBoardValidationException( "AccountUnresolved", "Work order account could not be resolved from location."); } switch (WorkOrderMediaAuthorization.ResolveMediaScope(user)) { case MediaAccountScope.Account account: if (account.AccountId != resolvedAccountId) { throw new WorkOrderBoardValidationException( "Forbidden", "You are not allowed to create a work order for this location."); } return account.AccountId; case MediaAccountScope.OrgWide: return resolvedAccountId; default: throw new WorkOrderBoardValidationException( "Forbidden", "You are not allowed to create work orders without account scope."); } } public Task ResolveForUnauthenticatedCreateAsync( string? customer, CancellationToken cancellationToken = default) => ResolveRequiredFromCustomerAsync(customer, cancellationToken); public Task TryResolveFromCustomerAsync( string? customer, CancellationToken cancellationToken = default) => _accounts.TryGetUniqueActiveIdByExactNameAsync(customer, cancellationToken); private async Task ResolveRequiredFromCustomerAsync( string? customer, CancellationToken cancellationToken) { var resolved = await TryResolveFromCustomerAsync(customer, cancellationToken); if (resolved is int accountId) return accountId; throw new WorkOrderBoardValidationException( "AccountUnresolved", "Work order account could not be resolved from customer."); } } }