Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor permission #49

Merged
merged 2 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading