Skip to content

Commit 020cc60

Browse files
committed
refractor: 拆分 rbac
1 parent 037bab8 commit 020cc60

File tree

5 files changed

+408
-250
lines changed

5 files changed

+408
-250
lines changed

config.yaml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
root: '123456'
2-
bt_uin: '123456789'
3-
enable_webui_interaction: true
4-
debug: false
5-
github_proxy: null
6-
check_ncatbot_update: true
7-
skip_ncatbot_install_check: false
8-
websocket_timeout: 15
9-
napcat:
10-
ws_uri: ws://localhost:16708
11-
ws_token: napcat_ws
12-
ws_listen_ip: localhost
13-
webui_uri: http://localhost:6099
14-
webui_token: (7Pyst9=}RO^^=|b
15-
enable_webui: true
16-
check_napcat_update: false
17-
stop_napcat: false
18-
remote_mode: false
19-
report_self_message: false
20-
report_forward_message_detail: true
21-
plugin:
22-
plugins_dir: plugins
23-
plugin_whitelist: []
24-
plugin_blacklist: []
25-
skip_plugin_load: true
1+
root: '123456'
2+
bt_uin: '123456789'
3+
enable_webui_interaction: true
4+
debug: false
5+
github_proxy: null
6+
check_ncatbot_update: true
7+
skip_ncatbot_install_check: false
8+
websocket_timeout: 15
9+
napcat:
10+
ws_uri: ws://localhost:16708
11+
ws_token: napcat_ws
12+
ws_listen_ip: localhost
13+
webui_uri: http://localhost:6099
14+
webui_token: (7Pyst9=}RO^^=|b
15+
enable_webui: true
16+
check_napcat_update: false
17+
stop_napcat: false
18+
remote_mode: false
19+
report_self_message: false
20+
report_forward_message_detail: true
21+
plugin:
22+
plugins_dir: plugins
23+
plugin_whitelist: []
24+
plugin_blacklist: []
25+
skip_plugin_load: true
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
"""
2+
RBAC 实体管理模块 - 处理权限、角色、用户的管理
3+
"""
4+
5+
from typing import TYPE_CHECKING, List
6+
7+
if TYPE_CHECKING:
8+
from .service import RBACService
9+
10+
11+
class EntityManager:
12+
"""权限、角色、用户管理器"""
13+
14+
def __init__(self, service: "RBACService"):
15+
self._service = service
16+
17+
# ==========================================================================
18+
# 权限管理
19+
# ==========================================================================
20+
21+
def add_permission(self, path: str) -> None:
22+
"""添加权限"""
23+
if not self._service._permissions.exists(path, exact=True):
24+
self._service._permissions.add(path)
25+
self._service._clear_cache()
26+
27+
def remove_permission(self, path: str) -> None:
28+
"""移除权限"""
29+
self._service._permissions.remove(path)
30+
self._service._clear_cache()
31+
32+
def permission_exists(self, path: str) -> bool:
33+
"""检查权限是否存在"""
34+
return self._service._permissions.exists(path, exact=True)
35+
36+
# ==========================================================================
37+
# 角色管理
38+
# ==========================================================================
39+
40+
def add_role(self, role: str, exist_ok: bool = False) -> None:
41+
"""添加角色"""
42+
if role in self._service._roles:
43+
if not exist_ok:
44+
raise ValueError(f"角色 {role} 已存在")
45+
return
46+
47+
self._service._roles[role] = {"whitelist": set(), "blacklist": set()}
48+
self._service._role_users[role] = set()
49+
self._service._role_inheritance[role] = []
50+
51+
def remove_role(self, role: str) -> None:
52+
"""移除角色"""
53+
if role not in self._service._roles:
54+
raise ValueError(f"角色 {role} 不存在")
55+
56+
# 从所有用户中移除该角色
57+
for user_data in self._service._users.values():
58+
if role in user_data["roles"]:
59+
user_data["roles"].remove(role)
60+
61+
# 从继承链中移除
62+
for parent_roles in self._service._role_inheritance.values():
63+
if role in parent_roles:
64+
parent_roles.remove(role)
65+
66+
del self._service._roles[role]
67+
del self._service._role_users[role]
68+
del self._service._role_inheritance[role]
69+
70+
def role_exists(self, role: str) -> bool:
71+
"""检查角色是否存在"""
72+
return role in self._service._roles
73+
74+
def set_role_inheritance(self, role: str, parent: str) -> None:
75+
"""设置角色继承"""
76+
if role not in self._service._roles:
77+
raise ValueError(f"角色 {role} 不存在")
78+
if parent not in self._service._roles:
79+
raise ValueError(f"父角色 {parent} 不存在")
80+
if role == parent:
81+
raise ValueError("不能继承自身")
82+
if self._would_create_cycle(role, parent):
83+
raise ValueError(f"检测到循环继承: {role} -> {parent}")
84+
85+
if parent not in self._service._role_inheritance[role]:
86+
self._service._role_inheritance[role].append(parent)
87+
self._service._clear_cache()
88+
89+
def _would_create_cycle(self, role: str, new_parent: str) -> bool:
90+
"""检查是否会形成循环继承"""
91+
visited = set()
92+
93+
def check(current: str) -> bool:
94+
if current == role:
95+
return True
96+
if current in visited:
97+
return False
98+
visited.add(current)
99+
for parent in self._service._role_inheritance.get(current, []):
100+
if check(parent):
101+
return True
102+
return False
103+
104+
return check(new_parent)
105+
106+
# ==========================================================================
107+
# 用户管理
108+
# ==========================================================================
109+
110+
def add_user(self, user: str, exist_ok: bool = False) -> None:
111+
"""添加用户"""
112+
if user in self._service._users:
113+
if not exist_ok:
114+
raise ValueError(f"用户 {user} 已存在")
115+
return
116+
117+
roles = [self._service._default_role] if self._service._default_role else []
118+
self._service._users[user] = {"whitelist": set(), "blacklist": set(), "roles": roles}
119+
120+
# 添加到默认角色的用户列表
121+
if self._service._default_role and self._service._default_role in self._service._role_users:
122+
self._service._role_users[self._service._default_role].add(user)
123+
124+
def remove_user(self, user: str) -> None:
125+
"""移除用户"""
126+
if user not in self._service._users:
127+
raise ValueError(f"用户 {user} 不存在")
128+
129+
# 从所有角色的用户列表中移除
130+
for role, users in self._service._role_users.items():
131+
users.discard(user)
132+
133+
del self._service._users[user]
134+
self._service._clear_cache()
135+
136+
def user_exists(self, user: str) -> bool:
137+
"""检查用户是否存在"""
138+
return user in self._service._users
139+
140+
def user_has_role(self, user: str, role: str, create_user: bool = True) -> bool:
141+
"""检查用户是否拥有角色"""
142+
if user not in self._service._users:
143+
if create_user:
144+
self.add_user(user, exist_ok=True)
145+
else:
146+
return False
147+
148+
return role in self._service._users[user]["roles"]
149+
150+
def assign_role(
151+
self,
152+
user: str,
153+
role: str,
154+
create_user: bool = True,
155+
) -> None:
156+
"""
157+
分配角色给用户
158+
159+
Args:
160+
user: 用户名
161+
role: 角色名
162+
create_user: 用户不存在时是否自动创建
163+
"""
164+
if role not in self._service._roles:
165+
raise ValueError(f"角色 {role} 不存在")
166+
167+
if user not in self._service._users:
168+
if create_user:
169+
self.add_user(user)
170+
else:
171+
raise ValueError(f"用户 {user} 不存在")
172+
173+
user_data = self._service._users[user]
174+
if role not in user_data["roles"]:
175+
user_data["roles"].append(role)
176+
177+
if user not in self._service._role_users[role]:
178+
self._service._role_users[role].add(user)
179+
180+
self._service._clear_cache()
181+
182+
def unassign_role(self, user: str, role: str) -> None:
183+
"""
184+
从用户移除角色
185+
186+
Args:
187+
user: 用户名
188+
role: 角色名
189+
"""
190+
if user not in self._service._users:
191+
raise ValueError(f"用户 {user} 不存在")
192+
193+
if role not in self._service._roles:
194+
raise ValueError(f"角色 {role} 不存在")
195+
196+
user_data = self._service._users[user]
197+
if role in user_data["roles"]:
198+
user_data["roles"].remove(role)
199+
200+
self._service._role_users[role].discard(user)
201+
self._service._clear_cache()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""
2+
RBAC 权限分配模块
3+
"""
4+
5+
from typing import Dict, Literal
6+
7+
8+
class PermissionAssigner:
9+
"""权限分配逻辑的抽象"""
10+
11+
def __init__(self, service):
12+
self.service = service
13+
14+
def grant(
15+
self,
16+
target_type: Literal["user", "role"],
17+
target: str,
18+
permission: str,
19+
mode: Literal["white", "black"] = "white",
20+
create_permission: bool = True,
21+
) -> None:
22+
"""
23+
授予权限
24+
25+
Args:
26+
target_type: 目标类型 ("user" 或 "role")
27+
target: 用户名或角色名
28+
permission: 权限路径
29+
mode: white=白名单, black=黑名单
30+
create_permission: 权限不存在时是否自动创建
31+
"""
32+
if not self.service.permission_exists(permission):
33+
if create_permission:
34+
self.service.add_permission(permission)
35+
else:
36+
raise ValueError(f"权限 {permission} 不存在")
37+
38+
if target_type == "user":
39+
if target not in self.service._users:
40+
raise ValueError(f"用户 {target} 不存在")
41+
target_data = self.service._users[target]
42+
else:
43+
if target not in self.service._roles:
44+
raise ValueError(f"角色 {target} 不存在")
45+
target_data = self.service._roles[target]
46+
47+
list_key = "whitelist" if mode == "white" else "blacklist"
48+
opposite_key = "blacklist" if mode == "white" else "whitelist"
49+
50+
target_data[list_key].add(permission)
51+
target_data[opposite_key].discard(permission) # 从相反列表移除
52+
self.service._clear_cache()
53+
54+
def revoke(
55+
self,
56+
target_type: Literal["user", "role"],
57+
target: str,
58+
permission: str,
59+
) -> None:
60+
"""撤销权限"""
61+
if target_type == "user":
62+
if target not in self.service._users:
63+
raise ValueError(f"用户 {target} 不存在")
64+
target_data = self.service._users[target]
65+
else:
66+
if target not in self.service._roles:
67+
raise ValueError(f"角色 {target} 不存在")
68+
target_data = self.service._roles[target]
69+
70+
target_data["whitelist"].discard(permission)
71+
target_data["blacklist"].discard(permission)
72+
self.service._clear_cache()

0 commit comments

Comments
 (0)