设计权限定义和权限提供者
This commit is contained in:
parent
6742812bf2
commit
5a170f3024
@ -1,4 +1,4 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.9.34414.90
|
VisualStudioVersion = 17.9.34414.90
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
@ -18,8 +18,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ProductService",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.BasketService", "src\HelloShop.BasketService\HelloShop.BasketService.csproj", "{02EBA5AD-84B4-4AF4-B519-72061C08800D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.BasketService", "src\HelloShop.BasketService\HelloShop.BasketService.csproj", "{02EBA5AD-84B4-4AF4-B519-72061C08800D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.HybridApp", "src\HelloShop.HybridApp\HelloShop.HybridApp.csproj", "{CC0E5839-B7E9-400E-9AF3-95863BBF518B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1AD03316-A743-4E9D-B3BC-FB9499D15141}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1AD03316-A743-4E9D-B3BC-FB9499D15141}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{29BE158E-825E-48AB-A02D-4E537A5DC502}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{29BE158E-825E-48AB-A02D-4E537A5DC502}"
|
||||||
@ -66,12 +64,6 @@ Global
|
|||||||
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.Build.0 = Release|Any CPU
|
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
|
||||||
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2022279A-E39F-4489-82AE-39AC53C594C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2022279A-E39F-4489-82AE-39AC53C594C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -93,7 +85,6 @@ Global
|
|||||||
{C4789097-3694-4370-9252-44268661A26E} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
{C4789097-3694-4370-9252-44268661A26E} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
||||||
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
||||||
{02EBA5AD-84B4-4AF4-B519-72061C08800D} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
{02EBA5AD-84B4-4AF4-B519-72061C08800D} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
||||||
{CC0E5839-B7E9-400E-9AF3-95863BBF518B} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
|
|
||||||
{2022279A-E39F-4489-82AE-39AC53C594C9} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
|
{2022279A-E39F-4489-82AE-39AC53C594C9} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
|
||||||
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
|
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@ -12,19 +12,20 @@ namespace HelloShop.IdentityService.Controllers
|
|||||||
public class TestsController : ControllerBase
|
public class TestsController : ControllerBase
|
||||||
{
|
{
|
||||||
[HttpGet(nameof(Foo))]
|
[HttpGet(nameof(Foo))]
|
||||||
[Authorize(Roles = "AdminRole")]
|
[Authorize(IdentityPermissions.Users.Update)]
|
||||||
public IActionResult Foo()
|
public IActionResult Foo()
|
||||||
{
|
{
|
||||||
return Ok("Hello, World!");
|
return Ok("Hello, World!");
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet(nameof(Bar))]
|
[HttpGet(nameof(Bar))]
|
||||||
[Authorize(Roles = "GuestRole")]
|
[Authorize(IdentityPermissions.Users.Create)]
|
||||||
public IActionResult Bar()
|
public IActionResult Bar()
|
||||||
{
|
{
|
||||||
return Ok("Hello, World!");
|
return Ok("Hello, World!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(IdentityPermissions.Users.Delete)]
|
||||||
[HttpGet(nameof(Baz))]
|
[HttpGet(nameof(Baz))]
|
||||||
public IActionResult Baz()
|
public IActionResult Baz()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
using HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
namespace HelloShop.IdentityService;
|
||||||
|
|
||||||
|
public class IdentityPermissionDefinitionProvider : IPermissionDefinitionProvider
|
||||||
|
{
|
||||||
|
public void Define(PermissionDefinitionContext context)
|
||||||
|
{
|
||||||
|
var identityGroup = context.AddGroup(IdentityPermissions.GroupName, "访问控制");
|
||||||
|
|
||||||
|
var roles = identityGroup.AddPermission(IdentityPermissions.Roles.Default, "角色管理");
|
||||||
|
|
||||||
|
roles.AddChild(IdentityPermissions.Roles.Create, "创建角色");
|
||||||
|
roles.AddChild(IdentityPermissions.Roles.Update, "更新角色");
|
||||||
|
roles.AddChild(IdentityPermissions.Roles.Delete, "删除角色");
|
||||||
|
roles.AddChild(IdentityPermissions.Roles.ManagePermissions, "管理角色权限");
|
||||||
|
|
||||||
|
var users = identityGroup.AddPermission(IdentityPermissions.Users.Default, "用户管理");
|
||||||
|
|
||||||
|
users.AddChild(IdentityPermissions.Users.Create, "创建用户");
|
||||||
|
users.AddChild(IdentityPermissions.Users.Update, "更新用户");
|
||||||
|
users.AddChild(IdentityPermissions.Users.Delete, "删除用户");
|
||||||
|
users.AddChild(IdentityPermissions.Users.ManageRoles, "管理用户角色");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
namespace HelloShop.IdentityService;
|
||||||
|
|
||||||
|
public static class IdentityPermissions
|
||||||
|
{
|
||||||
|
public const string GroupName = "Identity";
|
||||||
|
|
||||||
|
public static class Roles
|
||||||
|
{
|
||||||
|
public const string Default = GroupName + ".Roles";
|
||||||
|
public const string Create = Default + ".Create";
|
||||||
|
public const string Update = Default + ".Update";
|
||||||
|
public const string Delete = Default + ".Delete";
|
||||||
|
public const string ManagePermissions = Default + ".ManagePermissions";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Users
|
||||||
|
{
|
||||||
|
public const string Default = GroupName + ".Users";
|
||||||
|
public const string Create = Default + ".Create";
|
||||||
|
public const string Update = Default + ".Update";
|
||||||
|
public const string Delete = Default + ".Delete";
|
||||||
|
public const string ManageRoles = Update + ".ManageRoles";
|
||||||
|
}
|
||||||
|
}
|
@ -53,6 +53,7 @@ builder.Services.AddAuthentication(options =>
|
|||||||
|
|
||||||
builder.Services.AddDataSeedingProviders();
|
builder.Services.AddDataSeedingProviders();
|
||||||
builder.Services.AddOpenApi();
|
builder.Services.AddOpenApi();
|
||||||
|
builder.Services.AddPermissionDefinitions();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
@ -66,5 +67,6 @@ app.MapControllers();
|
|||||||
|
|
||||||
app.UseDataSeedingProviders();
|
app.UseDataSeedingProviders();
|
||||||
app.UseOpenApi();
|
app.UseOpenApi();
|
||||||
|
app.MapGroup("api/Permissions").MapPermissionDefinitions("Permissions");
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
using HelloShop.ServiceDefaults.Permissions;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace HelloShop.ServiceDefaults.Extensions;
|
||||||
|
|
||||||
|
public static class PermissionExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddPermissionDefinitions(this IServiceCollection services, Assembly? assembly = null)
|
||||||
|
{
|
||||||
|
assembly ??= Assembly.GetCallingAssembly();
|
||||||
|
|
||||||
|
var permissionDefinitionProviders = assembly.ExportedTypes.Where(t => t.IsAssignableTo(typeof(IPermissionDefinitionProvider)));
|
||||||
|
|
||||||
|
permissionDefinitionProviders.ToList().ForEach(t => services.AddSingleton(typeof(IPermissionDefinitionProvider), t));
|
||||||
|
|
||||||
|
services.AddSingleton<IPermissionDefinitionManager, PermissionDefinitionManager>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEndpointRouteBuilder MapPermissionDefinitions(this IEndpointRouteBuilder endpoints, params string[] tags)
|
||||||
|
{
|
||||||
|
var routeGroup = endpoints.MapGroup(string.Empty);
|
||||||
|
|
||||||
|
routeGroup.MapGet("PermissionDefinitions", async (IPermissionDefinitionManager permissionDefinitionManager) =>
|
||||||
|
{
|
||||||
|
List<PermissionGroupDefinitionResponse> result = [];
|
||||||
|
|
||||||
|
var permissionGroups = await permissionDefinitionManager.GetGroupsAsync();
|
||||||
|
|
||||||
|
foreach (var permissionGroup in permissionGroups)
|
||||||
|
{
|
||||||
|
PermissionGroupDefinitionResponse permissionGroupDefinition = new()
|
||||||
|
{
|
||||||
|
Name = permissionGroup.Name,
|
||||||
|
DisplayName = permissionGroup.DisplayName,
|
||||||
|
Permissions = []
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (PermissionDefinition? permission in permissionGroup.GetPermissionsWithChildren())
|
||||||
|
{
|
||||||
|
PermissionDefinitionResponse permissionDefinition = new()
|
||||||
|
{
|
||||||
|
Name = permission.Name,
|
||||||
|
DisplayName = permission.DisplayName,
|
||||||
|
ParentName = permission.Parent?.Name
|
||||||
|
};
|
||||||
|
|
||||||
|
permissionGroupDefinition.Permissions.Add(permissionDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(permissionGroupDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}).WithTags(tags);
|
||||||
|
|
||||||
|
return routeGroup;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionDefinitionResponse
|
||||||
|
{
|
||||||
|
public required string Name { get; init; }
|
||||||
|
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
|
||||||
|
public string? ParentName { get; set; }
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionGroupDefinitionResponse
|
||||||
|
{
|
||||||
|
public required string Name { get; init; }
|
||||||
|
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
|
||||||
|
public required List<PermissionDefinitionResponse> Permissions { get; init; }
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public interface IPermissionDefinitionManager
|
||||||
|
{
|
||||||
|
Task<PermissionDefinition> GetAsync(string name);
|
||||||
|
|
||||||
|
Task<PermissionDefinition?> GetOrNullAsync(string name);
|
||||||
|
|
||||||
|
Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync();
|
||||||
|
|
||||||
|
Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync();
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public interface IPermissionDefinitionProvider
|
||||||
|
{
|
||||||
|
void Define(PermissionDefinitionContext context);
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionDefinition
|
||||||
|
{
|
||||||
|
public string Name { get; } = default!;
|
||||||
|
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
|
||||||
|
public PermissionDefinition? Parent { get; private set; }
|
||||||
|
|
||||||
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
private readonly List<PermissionDefinition> _children = [];
|
||||||
|
|
||||||
|
public IReadOnlyList<PermissionDefinition> Children => [.. _children];
|
||||||
|
|
||||||
|
protected internal PermissionDefinition(string name, string? displayName = null, bool isEnabled = true)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
DisplayName = displayName;
|
||||||
|
IsEnabled = isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionDefinition AddChild(string name, string? displayName = null, bool isEnabled = true)
|
||||||
|
{
|
||||||
|
var child = new PermissionDefinition(name, displayName, isEnabled) { Parent = this };
|
||||||
|
_children.Add(child);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionDefinitionContext
|
||||||
|
{
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
|
internal Dictionary<string, PermissionGroupDefinition> Groups { get; }
|
||||||
|
|
||||||
|
internal PermissionDefinitionContext(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
Groups = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionGroupDefinition AddGroup(string name, string? displayName = null)
|
||||||
|
{
|
||||||
|
if (Groups.ContainsKey(name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"There is already an existing permission group with name: {name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Groups[name] = new PermissionGroupDefinition(name, displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionGroupDefinition GetGroup(string name)
|
||||||
|
{
|
||||||
|
PermissionGroupDefinition? group = GetGroupOrNull(name);
|
||||||
|
|
||||||
|
return group is null ? throw new InvalidOperationException($"Could not find a permission definition group with the given name: {name}") : group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionGroupDefinition? GetGroupOrNull(string name)
|
||||||
|
{
|
||||||
|
if (!Groups.TryGetValue(name, out PermissionGroupDefinition? value))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RemoveGroup(string name)
|
||||||
|
{
|
||||||
|
if (!Groups.ContainsKey(name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Not found permission group with name: {name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Groups.Remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionDefinition? GetPermissionOrNull(string name)
|
||||||
|
{
|
||||||
|
foreach (var groupDefinition in Groups.Values)
|
||||||
|
{
|
||||||
|
var permissionDefinition = groupDefinition.GetPermissionOrNull(name);
|
||||||
|
|
||||||
|
if (permissionDefinition != null)
|
||||||
|
{
|
||||||
|
return permissionDefinition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionDefinitionManager : IPermissionDefinitionManager
|
||||||
|
{
|
||||||
|
private readonly Lazy<Dictionary<string, PermissionGroupDefinition>> _lazyPermissionGroupDefinitions;
|
||||||
|
|
||||||
|
protected IDictionary<string, PermissionGroupDefinition> PermissionGroupDefinitions => _lazyPermissionGroupDefinitions.Value;
|
||||||
|
|
||||||
|
private readonly Lazy<Dictionary<string, PermissionDefinition>> _lazyPermissionDefinitions;
|
||||||
|
|
||||||
|
protected IDictionary<string, PermissionDefinition> PermissionDefinitions => _lazyPermissionDefinitions.Value;
|
||||||
|
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
public PermissionDefinitionManager(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_lazyPermissionGroupDefinitions = new Lazy<Dictionary<string, PermissionGroupDefinition>>(CreatePermissionGroupDefinitions, isThreadSafe: true);
|
||||||
|
_lazyPermissionDefinitions = new Lazy<Dictionary<string, PermissionDefinition>>(CreatePermissionDefinitions, isThreadSafe: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Dictionary<string, PermissionGroupDefinition> CreatePermissionGroupDefinitions()
|
||||||
|
{
|
||||||
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
|
var context = new PermissionDefinitionContext(scope.ServiceProvider);
|
||||||
|
|
||||||
|
var providers = _serviceProvider.GetServices<IPermissionDefinitionProvider>();
|
||||||
|
|
||||||
|
foreach (IPermissionDefinitionProvider provider in providers)
|
||||||
|
{
|
||||||
|
provider.Define(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.Groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Dictionary<string, PermissionDefinition> CreatePermissionDefinitions()
|
||||||
|
{
|
||||||
|
var permissions = new Dictionary<string, PermissionDefinition>();
|
||||||
|
|
||||||
|
foreach (var groupDefinition in PermissionGroupDefinitions.Values)
|
||||||
|
{
|
||||||
|
foreach (var permission in groupDefinition.Permissions)
|
||||||
|
{
|
||||||
|
AddPermissionToDictionaryRecursively(permissions, permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void AddPermissionToDictionaryRecursively(Dictionary<string, PermissionDefinition> permissions, PermissionDefinition permission)
|
||||||
|
{
|
||||||
|
if (permissions.ContainsKey(permission.Name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Duplicate permission name {permission.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions[permission.Name] = permission;
|
||||||
|
|
||||||
|
foreach (var child in permission.Children)
|
||||||
|
{
|
||||||
|
AddPermissionToDictionaryRecursively(permissions, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PermissionDefinition> GetAsync(string name)
|
||||||
|
{
|
||||||
|
var permission = await GetOrNullAsync(name);
|
||||||
|
|
||||||
|
return permission ?? throw new InvalidOperationException($"Undefined permission {name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<PermissionDefinition?> GetOrNullAsync(string name)
|
||||||
|
{
|
||||||
|
return Task.FromResult(PermissionDefinitions.TryGetValue(name, out var obj) ? obj : default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync()
|
||||||
|
{
|
||||||
|
IReadOnlyList<PermissionGroupDefinition> permissionGroups = [.. PermissionGroupDefinitions.Values];
|
||||||
|
|
||||||
|
return Task.FromResult(permissionGroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync()
|
||||||
|
{
|
||||||
|
IReadOnlyList<PermissionDefinition> permissions = [.. PermissionDefinitions.Values];
|
||||||
|
|
||||||
|
return Task.FromResult(permissions);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
namespace HelloShop.ServiceDefaults.Permissions;
|
||||||
|
|
||||||
|
public class PermissionGroupDefinition
|
||||||
|
{
|
||||||
|
public string Name { get; } = default!;
|
||||||
|
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
|
||||||
|
private readonly List<PermissionDefinition> _permissions = [];
|
||||||
|
|
||||||
|
public IReadOnlyList<PermissionDefinition> Permissions => [.. _permissions];
|
||||||
|
|
||||||
|
protected internal PermissionGroupDefinition(string name, string? displayName = null)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
DisplayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual PermissionDefinition AddPermission(string name, string? displayName = null, bool isEnabled = true)
|
||||||
|
{
|
||||||
|
var permission = new PermissionDefinition(name, displayName, isEnabled);
|
||||||
|
_permissions.Add(permission);
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<PermissionDefinition> GetPermissionsWithChildren()
|
||||||
|
{
|
||||||
|
var permissions = new List<PermissionDefinition>();
|
||||||
|
|
||||||
|
foreach (var permission in _permissions)
|
||||||
|
{
|
||||||
|
AddPermissionToListRecursively(permissions, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddPermissionToListRecursively(List<PermissionDefinition> permissions, PermissionDefinition permission)
|
||||||
|
{
|
||||||
|
permissions.Add(permission);
|
||||||
|
|
||||||
|
foreach (var child in permission.Children)
|
||||||
|
{
|
||||||
|
AddPermissionToListRecursively(permissions, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PermissionDefinition? GetPermissionOrNull(string name) => GetPermissionOrNullRecursively(Permissions, name);
|
||||||
|
|
||||||
|
private static PermissionDefinition? GetPermissionOrNullRecursively(IReadOnlyList<PermissionDefinition> permissions, string name)
|
||||||
|
{
|
||||||
|
foreach (var permission in permissions)
|
||||||
|
{
|
||||||
|
if (permission.Name == name)
|
||||||
|
{
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
var childPermission = GetPermissionOrNullRecursively(permission.Children, name);
|
||||||
|
if (childPermission != null)
|
||||||
|
{
|
||||||
|
return childPermission;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user