using mws.backend.dotnet.application.Common; namespace mws.backend.dotnet.application.Permissions; public class PermissionService(IUnitOfWork uow) : IPermissionService { public async Task> GetMenuAsync(Guid userId, CancellationToken ct = default) { var roleIds = await uow.Users.GetRoleIdsAsync(userId, ct); var permissions = await uow.Roles.GetPermissionsForRolesAsync(roleIds, ct); var merged = permissions.GroupBy(p => p.Screen).ToDictionary( g => g.Key, g => new { CanView = g.Any(p => p.CanView), CanCreate = g.Any(p => p.CanCreate), CanEdit = g.Any(p => p.CanEdit), CanDelete = g.Any(p => p.CanDelete), } ); return ScreenCatalog.Screens.Select(s => { merged.TryGetValue(s.Key, out var p); return new MenuItemDto { Key = s.Key, Label = s.Label, Path = s.Path, CanView = p?.CanView ?? false, CanCreate = p?.CanCreate ?? false, CanEdit = p?.CanEdit ?? false, CanDelete = p?.CanDelete ?? false, }; }).ToList(); } public async Task EnsureAsync(Guid userId, string screen, PermissionAction action, CancellationToken ct = default) { var roleIds = await uow.Users.GetRoleIdsAsync(userId, ct); var permissions = await uow.Roles.GetPermissionsForRolesAsync(roleIds, ct); var screenPermissions = permissions.Where(p => p.Screen == screen).ToList(); var allowed = action switch { PermissionAction.View => screenPermissions.Any(p => p.CanView), PermissionAction.Create => screenPermissions.Any(p => p.CanCreate), PermissionAction.Edit => screenPermissions.Any(p => p.CanEdit), PermissionAction.Delete => screenPermissions.Any(p => p.CanDelete), _ => false, }; if (!allowed) { throw new ForbiddenException($"Not permitted to {action} on {screen}"); } } }