Skip to content

Commit fec0260

Browse files
Refactor Permissions class for type hints and methods (#8)
1 parent 440d683 commit fec0260

File tree

1 file changed

+54
-44
lines changed

1 file changed

+54
-44
lines changed

src/nonebot_plugin_liteperm/nodelib.py

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
from copy import deepcopy
33
from typing import Any
44

5+
from typing_extensions import Self
6+
57

68
class Permissions:
79
permissions_data: dict[str, str | dict | bool]
10+
node_dict: dict[str, bool]
11+
__permissions_str: str = ""
812

913
def __init__(
1014
self, permissions_data: dict[str, str | dict | bool] | None = None
@@ -13,98 +17,108 @@ def __init__(
1317
permissions_data = {}
1418
self.permissions_data = permissions_data
1519

16-
__permissions_str: str = ""
17-
1820
def __str__(self):
1921
return json.dumps(self.permissions_data)
2022

21-
def __search_perm(self, data, parent_key="", result=None):
23+
def __search_perm(
24+
self, data: dict[str, Any], parent_key="", result=None
25+
) -> list[tuple[str, bool]]:
2226
if result is None:
2327
result = []
2428

25-
for key in data:
26-
node = data[key]
29+
for key, node in data.items():
2730
current_path = f"{parent_key}.{key}" if parent_key else key
2831

2932
# 检查当前节点权限
3033
if node.get("has_permission", False):
31-
result.append(f"{current_path} true")
34+
result.append((current_path, True))
3235
elif node.get("explicit_hasnt", False):
33-
result.append(f"{current_path} false")
36+
result.append((current_path, False))
3437
if node.get("children", {}) != {}:
3538
children = node.get("children", {})
3639
self.__search_perm(children, current_path, result)
3740
return result
3841

39-
def __dump_to_str(
42+
def __dump(
4043
self,
4144
overwrite: bool = False,
4245
):
4346
if overwrite:
4447
self.__permissions_str = ""
4548
data = self.permissions_data
4649
data = deepcopy(data)
47-
for d in self.__search_perm(data):
48-
self.__permissions_str += f"{d}\n"
49-
50-
def del_permission(self, node: str):
50+
node_dict = {}
51+
for n, v in self.__search_perm(data):
52+
self.__permissions_str += f"{n} {'true' if v else 'false'}\n"
53+
node_dict[n] = v
54+
for line in self.__permissions_str.splitlines():
55+
if line:
56+
perm, arg = line.split(" ")
57+
node_dict[perm] = arg == "true"
58+
self.node_dict = node_dict
59+
60+
def del_permission(self, node: str) -> Self:
5161
node_parts = node.split(".")
5262
current_children: dict[str, Any] = self.permissions_data # 当前层级的子节点字典
5363
try:
5464
for i, part in enumerate(node_parts):
5565
if part not in current_children:
56-
return # 节点不存在,无法删除
66+
return self # 节点不存在,无法删除
5767
current_node = current_children[part]
5868
if i == len(node_parts) - 1:
5969
del current_children[part]
6070
current_children = current_node["children"]
6171
finally:
62-
self.__dump_to_str(overwrite=True)
72+
self.__dump(overwrite=True)
73+
return self
6374

64-
def set_permission(self, node: str, has_permission: bool, has_parent: bool = False):
75+
def set_permission(
76+
self, node: str, has_permission: bool, has_parent: bool = False
77+
) -> Self:
6578
node_parts = node.split(".")
6679
current_children: dict[str, Any] = self.permissions_data # 当前层级的子节点字典
6780

6881
for i, part in enumerate(node_parts):
6982
# 不存在创建新节点
7083
if part not in current_children:
71-
current_children[part] = {"has_permission": has_parent, "children": {}}
84+
current_children[part] = {
85+
"has_permission": has_parent,
86+
"children": {},
87+
"explicit_hasnt": False,
88+
}
7289
current_node = current_children[part]
7390
# 最后一个部分设权
7491
if i == len(node_parts) - 1:
7592
current_node["has_permission"] = has_permission
7693
current_node["explicit_hasnt"] = not has_permission
7794
# 下一层
7895
current_children = current_node["children"]
79-
self.__dump_to_str(overwrite=True)
96+
self.__dump(overwrite=True)
97+
return self
8098

8199
def check_permission(self, node: str) -> bool:
82-
node_parts = node.split(".")
83-
current_children: dict[str, Any] = self.permissions_data # 当前层级的子节点字典
84-
current_node = None
85-
86-
for part in node_parts:
87-
if part in current_children:
88-
current_node = current_children[part]
89-
current_children = current_node["children"]
90-
elif "*" in current_children:
91-
current_node = current_children["*"]
92-
current_children = current_node["children"]
93-
else:
94-
return False # 没有找到节点或通配符
95-
96-
# 返回最终节点的权限
97-
return current_node["has_permission"] if current_node else False
100+
node = node.strip()
101+
node_dict = self.node_dict
102+
if node_dict.get(node):
103+
return True
104+
current_node = ""
105+
for part in node.split("."):
106+
if node_dict.get(current_node + "." + "*"):
107+
return True
108+
current_node += ("." if current_node else "") + part
109+
if node_dict.get(current_node):
110+
return True
111+
return False
98112

99113
def dump_to_file(self, filename: str):
100114
with open(filename, "w", encoding="utf-8") as f:
101115
json.dump(self.permissions_data, f, indent=4)
102-
self.__dump_to_str(overwrite=True)
116+
self.__dump(overwrite=True)
103117

104118
def load_from_json(self, filename: str):
105119
with open(filename, encoding="utf-8") as f:
106120
self.permissions_data = json.load(f)
107-
self.__dump_to_str(overwrite=True)
121+
self.__dump(overwrite=True)
108122

109123
def from_perm_str(self, perm_str: str):
110124
for line in perm_str.split("\n"):
@@ -123,27 +137,23 @@ def data(self) -> dict[str, Any]:
123137
@data.setter
124138
def data(self, data: dict[str, Any]):
125139
self.permissions_data = data
126-
self.__dump_to_str(overwrite=True)
140+
self.__dump(overwrite=True)
127141

128142
@property
129143
def perm_str(self) -> str:
130144
return self.permissions_str
131145

132146
@property
133147
def permissions_str(self) -> str:
134-
self.__dump_to_str(True)
148+
self.__dump(True)
135149
return self.__permissions_str
136150

137151

138152
# 此处仅用于测试
139153
if __name__ == "__main__":
140-
permissions = Permissions({})
141-
permissions.set_permission("user.read", True)
142-
permissions.set_permission("user.write", True)
154+
permissions = Permissions()
143155
permissions.set_permission("user.*", True)
144-
permissions.set_permission("user", False)
145-
permissions.set_permission("children", True)
146-
permissions.set_permission("children.read", True)
147-
permissions.set_permission("children.children", True)
156+
print(permissions.check_permission("user.a"))
148157
print(permissions.permissions_str)
149158
print(json.dumps(permissions.dump_data(), indent=4))
159+
print(permissions.node_dict)

0 commit comments

Comments
 (0)