-
-
Notifications
You must be signed in to change notification settings - Fork 925
Fix/command permission management #2304
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,202 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import traceback | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import List, Dict, Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from .route import Route, Response, RouteContext | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core import logger | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from quart import request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.star.star_handler import star_handlers_registry, StarHandlerMetadata | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.star.filter.command import CommandFilter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.star.filter.command_group import CommandGroupFilter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.star.filter.permission import PermissionTypeFilter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.star.star import star_map | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core import DEMO_MODE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from astrbot.core.utils.shared_preferences import SharedPreferences | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class CommandPermissionRoute(Route): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def __init__( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context: RouteContext, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
core_lifecycle: AstrBotCoreLifecycle, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
super().__init__(context) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.routes = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"/command_permission/get": ("GET", self.get_command_permissions), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"/command_permission/set": ("POST", self.set_command_permission), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"/command_permission/get_commands": ("GET", self.get_all_commands), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.core_lifecycle = core_lifecycle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.register_routes() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def get_command_permissions(self) -> Response: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""获取所有指令的权限配置""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sp = SharedPreferences() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
alter_cmd_cfg = sp.get("alter_cmd", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# 构建权限配置列表 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
permissions = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# 遍历所有插件的权限配置 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for plugin_name, plugin_config in alter_cmd_cfg.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for command_name, config in plugin_config.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
permission_type = config.get("permission", "member") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
permissions.append({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"plugin_name": plugin_name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"command_name": command_name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"permission": permission_type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"id": f"{plugin_name}.{command_name}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Response().ok({"permissions": permissions}).__dict__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except Exception: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.error(f"/api/command_permission/get: {traceback.format_exc()}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Response().error("获取指令权限配置失败").__dict__ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def get_all_commands(self) -> Response: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""获取所有可用的指令列表""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
commands = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# 遍历所有注册的处理器 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for handler in star_handlers_registry: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert isinstance(handler, StarHandlerMetadata) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
plugin = star_map.get(handler.handler_module_path) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
# 遍历所有注册的处理器 | |
for handler in star_handlers_registry: | |
assert isinstance(handler, StarHandlerMetadata) | |
plugin = star_map.get(handler.handler_module_path) | |
# 遍历所有注册的处理器 | |
+ for handler in star_handlers_registry: | |
+ if not isinstance(handler, StarHandlerMetadata): | |
+ logger.warning(f"Handler {handler} is not an instance of StarHandlerMetadata, skipping.") | |
+ continue | |
+ plugin = star_map.get(handler.handler_module_path) |
Original comment in English
suggestion (bug_risk): Use of assert for type checking may cause issues in production.
Asserts are removed when Python runs with optimizations, so type checks may be skipped. Use an explicit isinstance check and handle failures with an if-statement instead.
# 遍历所有注册的处理器 | |
for handler in star_handlers_registry: | |
assert isinstance(handler, StarHandlerMetadata) | |
plugin = star_map.get(handler.handler_module_path) | |
# 遍历所有注册的处理器 | |
+ for handler in star_handlers_registry: | |
+ if not isinstance(handler, StarHandlerMetadata): | |
+ logger.warning(f"Handler {handler} is not an instance of StarHandlerMetadata, skipping.") | |
+ continue | |
+ plugin = star_map.get(handler.handler_module_path) |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: 只更新了第一个 PermissionTypeFilter。
目前,event_filters 中只有第一个 PermissionTypeFilter 被更新。请确认这是否是预期行为,或者在必要时更新所有匹配的过滤器。
Original comment in English
question: Only the first PermissionTypeFilter is updated.
Currently, only the first PermissionTypeFilter in event_filters is updated. Please confirm if this is intended, or update all matching filters if necessary.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: 缺少参数的错误消息可以更具体。
请指定缺少哪些参数以提高错误清晰度和客户端处理能力。
plugin_name = data.get("plugin_name") | |
handler_name = data.get("handler_name") | |
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
plugin_name = data.get("plugin_name") | |
handler_name = data.get("handler_name") | |
permission = data.get("permission") | |
missing_params = [] | |
if not plugin_name: | |
missing_params.append("plugin_name") | |
if not handler_name: | |
missing_params.append("handler_name") | |
if not permission: | |
missing_params.append("permission") | |
if missing_params: | |
return Response().error(f"参数不完整,缺少: {', '.join(missing_params)}").__dict__ | |
Original comment in English
suggestion: Error message for missing parameters could be more specific.
Specify which parameter(s) are missing to improve error clarity and client-side handling.
plugin_name = data.get("plugin_name") | |
handler_name = data.get("handler_name") | |
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
plugin_name = data.get("plugin_name") | |
handler_name = data.get("handler_name") | |
permission = data.get("permission") | |
missing_params = [] | |
if not plugin_name: | |
missing_params.append("plugin_name") | |
if not handler_name: | |
missing_params.append("handler_name") | |
if not permission: | |
missing_params.append("permission") | |
if missing_params: | |
return Response().error(f"参数不完整,缺少: {', '.join(missing_params)}").__dict__ | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): 权限类型检查区分大小写。
这将拒绝大小写不完全匹配的有效权限。考虑规范化输入或使用不区分大小写的检查。
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
if permission not in ["admin", "member"]: | |
return Response().error("权限类型错误,只能是 admin 或 member").__dict__ | |
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
normalized_permission = permission.lower() | |
if normalized_permission not in ["admin", "member"]: | |
return Response().error("权限类型错误,只能是 admin 或 member").__dict__ | |
Original comment in English
suggestion (bug_risk): Permission type check is case-sensitive.
This will reject valid permissions if the case doesn't match exactly. Consider normalizing input or using a case-insensitive check.
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
if permission not in ["admin", "member"]: | |
return Response().error("权限类型错误,只能是 admin 或 member").__dict__ | |
permission = data.get("permission") | |
if not all([plugin_name, handler_name, permission]): | |
return Response().error("参数不完整").__dict__ | |
normalized_permission = permission.lower() | |
if normalized_permission not in ["admin", "member"]: | |
return Response().error("权限类型错误,只能是 admin 或 member").__dict__ | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): 在 CommandPermissionRoute.get_all_commands 中发现低代码质量 - 14% (
low-code-quality
)解释
此函数的质量得分低于 25% 的质量阈值。此得分是方法长度、认知复杂度和工作内存的组合。
如何解决这个问题?
重构此函数以使其更短、更具可读性可能是有益的。
Original comment in English
issue (code-quality): Low code quality found in CommandPermissionRoute.get_all_commands - 14% (
low-code-quality
)Explanation
The quality score for this function is below the quality threshold of 25%.This score is a combination of the method length, cognitive complexity and working memory.
How can you solve this?
It might be worth refactoring this function to make it shorter and more readable.
their own functions. This is the most important thing you can do - ideally a
function should be less than 10 lines.
sits together within the function rather than being scattered.