Skip to content

Commit

Permalink
Merge pull request #49 from netcorepal/refactorPermission
Browse files Browse the repository at this point in the history
refactor permission
  • Loading branch information
witskeeper authored Dec 8, 2024
2 parents 41381a1 + 38695ea commit b04c81a
Show file tree
Hide file tree
Showing 36 changed files with 549 additions and 288 deletions.
72 changes: 72 additions & 0 deletions src/NetCorePal.D3Shop.Admin.Shared/Permission/Permission.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Collections.Immutable;

namespace NetCorePal.D3Shop.Admin.Shared.Permission;

/// <summary>
/// 表示一个权限对象,包含权限的基本信息及子权限
/// </summary>
public sealed class Permission
{
/// <summary>
/// 权限的唯一名称(代码)
/// </summary>
public string Code { get; }

/// <summary>
/// 权限的显示名称
/// </summary>
public string DisplayName { get; }

/// <summary>
/// 当前权限的所有子权限
/// 子权限是只读的
/// </summary>
public IReadOnlyList<Permission> Children => _children.ToImmutableList();

private readonly List<Permission> _children;

/// <summary>
/// 指示当前权限是否启用
/// 默认情况下权限是启用的
/// 禁用的权限无法被授予,但仍然可以检查其值(始终为 false)
/// 禁用权限可以用来隐藏相关的应用功能
/// 默认值:true(启用)
/// </summary>
public bool IsEnabled { get; }

/// <summary>
/// 创建一个新的权限对象。
/// </summary>
/// <param name="code">权限的唯一代码。</param>
/// <param name="displayName">权限的显示名称。</param>
/// <param name="isEnabled">是否启用此权限,默认为 true。</param>
internal Permission(
string code,
string displayName,
bool isEnabled = true)
{
ArgumentException.ThrowIfNullOrWhiteSpace(code);
ArgumentException.ThrowIfNullOrWhiteSpace(displayName);

Code = code;
DisplayName = displayName;
IsEnabled = isEnabled;
_children = [];
}

/// <summary>
/// 向当前权限添加一个子权限。
/// </summary>
/// <param name="code">子权限的唯一代码。</param>
/// <param name="displayName">子权限的显示名称。</param>
/// <param name="isEnabled">子权限是否启用,默认为 true。</param>
/// <returns>返回创建的子权限对象。</returns>
public Permission AddChild(string code, string displayName, bool isEnabled = true)
{
var child = new Permission(code, displayName, isEnabled);

_children.Add(child);

return child;
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
namespace NetCorePal.D3Shop.Domain.AggregatesModel.Identity.Permission;
namespace NetCorePal.D3Shop.Admin.Shared.Permission;

public static class PermissionDefinitions
public static class PermissionCodes
{
#region AdminUserManagement

public const string AdminUserManagement = nameof(AdminUserManagement);
public const string AdminUserCreate = nameof(AdminUserCreate);
public const string AdminUserEdit = nameof(AdminUserEdit);
public const string AdminUserUpdateRoles = nameof(AdminUserUpdateRoles);
public const string AdminUserSetPermissions = nameof(AdminUserSetPermissions);
public const string AdminUserView = nameof(AdminUserView);
public const string AdminUserUpdatePassword = nameof(AdminUserUpdatePassword);
public const string AdminUserDelete = nameof(AdminUserDelete);

#endregion

#region RoleManagement

public const string RoleManagement = nameof(RoleManagement);
public const string RoleCreate = nameof(RoleCreate);
public const string RoleEdit = nameof(RoleEdit);
public const string RoleUpdatePermissions = nameof(RoleUpdatePermissions);
public const string RoleDelete = nameof(RoleDelete);
public const string RoleView = nameof(RoleView);
#endregion

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Collections.Immutable;
using NetCorePal.Extensions.Primitives;

namespace NetCorePal.D3Shop.Admin.Shared.Permission;

/// <summary>
/// 管理权限定义的上下文类,负责初始化和提供权限组及其权限项。
/// </summary>
public static class PermissionDefinitionContext
{
// 存储权限组的字典,键为权限组名称,值为权限组对象
private static Dictionary<string, PermissionGroup> Groups { get; } = new();

// 静态构造函数,在类初始化时创建默认的权限组和权限项
static PermissionDefinitionContext()
{
var systemAccess = AddGroup("SystemAccess");
var adminUserManagement = systemAccess.AddPermission(PermissionCodes.AdminUserManagement, "用户管理");
adminUserManagement.AddChild(PermissionCodes.AdminUserCreate, "创建用户");
adminUserManagement.AddChild(PermissionCodes.AdminUserEdit, "编辑用户");
adminUserManagement.AddChild(PermissionCodes.AdminUserDelete, "删除用户");
adminUserManagement.AddChild(PermissionCodes.AdminUserView, "查看用户");
adminUserManagement.AddChild(PermissionCodes.AdminUserUpdateRoles, "更新用户角色");
adminUserManagement.AddChild(PermissionCodes.AdminUserUpdatePassword, "更新用户密码");
adminUserManagement.AddChild(PermissionCodes.AdminUserSetPermissions, "配置用户权限");
var roleManagement = systemAccess.AddPermission(PermissionCodes.RoleManagement, "角色管理");
roleManagement.AddChild(PermissionCodes.RoleCreate, "创建角色");
roleManagement.AddChild(PermissionCodes.RoleEdit, "编辑角色");
roleManagement.AddChild(PermissionCodes.RoleDelete, "删除角色");
roleManagement.AddChild(PermissionCodes.RoleView, "查看角色");
roleManagement.AddChild(PermissionCodes.RoleUpdatePermissions, "更新角色权限");
}

/// <summary>
/// 添加一个新的权限组,如果权限组名称已存在则抛出异常。
/// </summary>
/// <param name="name">权限组名称</param>
/// <returns>返回创建的权限组</returns>
/// <exception cref="ArgumentException">如果权限组名称已经存在,则抛出异常</exception>
private static PermissionGroup AddGroup(string name)
{
ArgumentException.ThrowIfNullOrWhiteSpace(name);

if (Groups.ContainsKey(name))
{
throw new ArgumentException($"There is already an existing permission group with name: {name}");
}

return Groups[name] = new PermissionGroup(name);
}

/// <summary>
/// 获取所有的权限组。
/// </summary>
public static IReadOnlyList<PermissionGroup> PermissionGroups => Groups.Values.ToImmutableList();

/// <summary>
/// 获取所有的权限。
/// </summary>
public static IReadOnlyList<Permission> AllPermissions
{
get
{
if (_allPermissions is not null) return _allPermissions;
var allPermissions = PermissionGroups.SelectMany(pg => pg.PermissionsWithChildren).ToImmutableList();
_allPermissions = allPermissions;
return _allPermissions;
}
}

private static IReadOnlyList<Permission>? _allPermissions;

/// <summary>
/// 根据权限码获取对应的权限。如果权限不存在,抛出异常。
/// </summary>
/// <param name="code">权限码</param>
/// <returns>返回对应的权限</returns>
/// <exception cref="KnownException">如果未找到权限,则抛出异常</exception>
public static Permission GetPermission(string code)
{
return AllPermissions.SingleOrDefault(p => p.Code == code) ??
throw new KnownException($"Permission with code '{code}' was not found");
}
}
87 changes: 87 additions & 0 deletions src/NetCorePal.D3Shop.Admin.Shared/Permission/PermissionGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System.Collections.Immutable;

namespace NetCorePal.D3Shop.Admin.Shared.Permission;

/// <summary>
/// 表示一个权限组,包含该组的所有权限以及相关操作。
/// </summary>
public sealed class PermissionGroup
{
/// <summary>
/// 权限组的唯一名称。
/// </summary>
public string Name { get; }

/// <summary>
/// 权限组内的所有权限,权限是只读的。
/// </summary>
public IReadOnlyList<Permission> Permissions => _permissions.ToImmutableList();

private readonly List<Permission> _permissions = [];

/// <summary>
/// 创建一个新的权限组。
/// </summary>
/// <param name="name">权限组的名称。</param>
internal PermissionGroup(string name)
{
// 初始化权限组的名称和权限集合
Name = name;
}

/// <summary>
/// 向权限组中添加一个权限。
/// </summary>
/// <param name="code">权限的唯一代码。</param>
/// <param name="name">权限的名称。</param>
/// <param name="isEnabled">是否启用该权限,默认为 true。</param>
/// <returns>返回创建的权限对象。</returns>
public Permission AddPermission(string code, string name, bool isEnabled = true)
{
var permission = new Permission(code, name, isEnabled);
_permissions.Add(permission); // 将权限添加到权限组中
return permission;
}


private List<Permission>? _permissionsWithChildren;

/// <summary>
/// 当前权限组中的所有权限,包括子权限。
/// </summary>
public IReadOnlyList<Permission> PermissionsWithChildren
{
get
{
if (_permissionsWithChildren is not null)
{
return _permissionsWithChildren;
}

var permissions = new List<Permission>();

foreach (var permission in _permissions)
{
AddPermissionToListRecursively(permissions, permission);
}

_permissionsWithChildren = permissions;
return permissions.ToImmutableList();
}
}

/// <summary>
/// 递归地将权限及其子权限添加到列表中。
/// </summary>
/// <param name="permissions">目标权限列表。</param>
/// <param name="permission">当前权限。</param>
private static void AddPermissionToListRecursively(List<Permission> permissions, Permission permission)
{
permissions.Add(permission);

foreach (var child in permission.Children)
{
AddPermissionToListRecursively(permissions, child);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace NetCorePal.D3Shop.Admin.Shared.Responses;

public record AdminUserAssignedPermissionResponse(string Code, bool IsFromRole);

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@

public record RolePermissionResponse(
string Code,
string GroupName,
string Remark,
bool IsAssigned);
string Remark);

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using NetCorePal.D3Shop.Admin.Shared.Const;

Expand Down
Loading

0 comments on commit b04c81a

Please sign in to comment.