Commit MWS backend source tree
The ASP.NET Core solution (mws.api/mws.application/mws.domain/ mws.infrastructure) existed only as untracked working files. Adding it to version control, plus a .gitignore for build output and local tooling directories, so the CQRS/mediator refactor plan has a real git history to branch and diff against.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
namespace Mws.Application.Permissions;
|
||||
|
||||
public enum PermissionAction
|
||||
{
|
||||
View,
|
||||
Create,
|
||||
Edit,
|
||||
Delete,
|
||||
}
|
||||
|
||||
public class MenuItemDto
|
||||
{
|
||||
public string Key { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public bool CanView { get; set; }
|
||||
public bool CanCreate { get; set; }
|
||||
public bool CanEdit { get; set; }
|
||||
public bool CanDelete { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Mws.Application.Permissions;
|
||||
|
||||
public interface IPermissionService
|
||||
{
|
||||
Task<List<MenuItemDto>> GetMenuAsync(Guid userId, CancellationToken ct = default);
|
||||
Task EnsureAsync(Guid userId, string screen, PermissionAction action, CancellationToken ct = default);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Mws.Application.Common;
|
||||
|
||||
namespace Mws.Application.Permissions;
|
||||
|
||||
public class PermissionService(IUnitOfWork uow) : IPermissionService
|
||||
{
|
||||
public async Task<List<MenuItemDto>> GetMenuAsync(Guid userId, CancellationToken ct = default)
|
||||
{
|
||||
var roleId = await uow.Users.GetRoleIdAsync(userId, ct);
|
||||
var permissions = await uow.Roles.GetPermissionsAsync(roleId, ct);
|
||||
|
||||
return ScreenCatalog.Screens.Select(s =>
|
||||
{
|
||||
permissions.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 roleId = await uow.Users.GetRoleIdAsync(userId, ct);
|
||||
var permission = await uow.Roles.GetPermissionAsync(roleId, screen, ct);
|
||||
|
||||
var allowed = action switch
|
||||
{
|
||||
PermissionAction.View => permission?.CanView ?? false,
|
||||
PermissionAction.Create => permission?.CanCreate ?? false,
|
||||
PermissionAction.Edit => permission?.CanEdit ?? false,
|
||||
PermissionAction.Delete => permission?.CanDelete ?? false,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if (!allowed)
|
||||
{
|
||||
throw new ForbiddenException($"Not permitted to {action} on {screen}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Mws.Application.Permissions;
|
||||
|
||||
public record ScreenDefinition(string Key, string Label, string Path);
|
||||
|
||||
public static class ScreenCatalog
|
||||
{
|
||||
public static readonly IReadOnlyList<ScreenDefinition> Screens =
|
||||
[
|
||||
new("dashboard", "Dashboard", "/"),
|
||||
new("projects", "Projects", "/projects"),
|
||||
new("tasks", "Tasks", "/tasks"),
|
||||
new("documents", "Documents", "/documents"),
|
||||
new("accounts", "Accounts", "/accounts"),
|
||||
new("roles", "Roles", "/roles"),
|
||||
];
|
||||
|
||||
public static readonly IReadOnlySet<string> Keys = Screens.Select(s => s.Key).ToHashSet();
|
||||
}
|
||||
Reference in New Issue
Block a user