diff --git a/src/plugin_system/base/component_types.py b/src/plugin_system/base/component_types.py index 92776b05d..d044b6a11 100644 --- a/src/plugin_system/base/component_types.py +++ b/src/plugin_system/base/component_types.py @@ -106,6 +106,13 @@ class PythonDependency: return self.install_name +@dataclass +class PermissionNodeField: + """权限节点声明字段""" + + node_name: str # 节点名称 (例如 "manage" 或 "view") + description: str # 权限描述 + @dataclass class ComponentInfo: """组件信息""" diff --git a/src/plugin_system/base/plugin_base.py b/src/plugin_system/base/plugin_base.py index dd4811c20..0d5af65e3 100644 --- a/src/plugin_system/base/plugin_base.py +++ b/src/plugin_system/base/plugin_base.py @@ -10,6 +10,7 @@ import toml from src.common.logger import get_logger from src.config.config import CONFIG_DIR from src.plugin_system.base.component_types import ( + PermissionNodeField, PluginInfo, PythonDependency, ) @@ -34,6 +35,8 @@ class PluginBase(ABC): config_schema: dict[str, dict[str, ConfigField] | str] = {} + permission_nodes: list["PermissionNodeField"] = [] + config_section_descriptions: dict[str, str] = {} def __init__(self, plugin_dir: str, metadata: PluginMetadata): diff --git a/src/plugin_system/core/plugin_manager.py b/src/plugin_system/core/plugin_manager.py index c3ab2ab99..6542365b7 100644 --- a/src/plugin_system/core/plugin_manager.py +++ b/src/plugin_system/core/plugin_manager.py @@ -6,6 +6,7 @@ from pathlib import Path from typing import Any, Optional from src.common.logger import get_logger +from src.plugin_system.apis.permission_api import permission_api from src.plugin_system.base.component_types import ComponentType from src.plugin_system.base.plugin_base import PluginBase from src.plugin_system.base.plugin_metadata import PluginMetadata @@ -125,6 +126,18 @@ class PluginManager: self.loaded_plugins[plugin_name] = plugin_instance self._show_plugin_components(plugin_name) + # 注册权限节点 + if hasattr(plugin_instance, "permission_nodes") and plugin_instance.permission_nodes: + for node in plugin_instance.permission_nodes: + asyncio.create_task( # noqa: RUF006 + permission_api.register_permission_node( + node_name=node.node_name, + description=node.description, + plugin_name=plugin_name, + ) + ) + logger.info(f"为插件 '{plugin_name}' 注册了 {len(plugin_instance.permission_nodes)} 个权限节点") + # 检查并调用 on_plugin_loaded 钩子(如果存在) if hasattr(plugin_instance, "on_plugin_loaded") and callable(plugin_instance.on_plugin_loaded): logger.debug(f"为插件 '{plugin_name}' 调用 on_plugin_loaded 钩子") @@ -405,6 +418,14 @@ class PluginManager: event_handler_names = [c.name for c in event_handler_components] logger.info(f" 📢 EventHandler组件: {', '.join(event_handler_names)}") + # 权限节点信息 + if plugin_instance := self.loaded_plugins.get(plugin_name): + if hasattr(plugin_instance, "permission_nodes") and plugin_instance.permission_nodes: + node_names = [node.node_name for node in plugin_instance.permission_nodes] + logger.info( + f" 🔑 权限节点 ({len(node_names)}个): {', '.join(node_names)}" + ) + # 依赖信息 if plugin_info.dependencies: logger.info(f" 🔗 依赖: {', '.join(plugin_info.dependencies)}") diff --git a/src/plugins/built_in/maizone_refactored/plugin.py b/src/plugins/built_in/maizone_refactored/plugin.py index 4ef92ff9e..cde0dc051 100644 --- a/src/plugins/built_in/maizone_refactored/plugin.py +++ b/src/plugins/built_in/maizone_refactored/plugin.py @@ -7,7 +7,7 @@ from pathlib import Path from src.common.logger import get_logger from src.plugin_system import BasePlugin, ComponentInfo, register_plugin -from src.plugin_system.apis.permission_api import permission_api +from src.plugin_system.base.component_types import PermissionNodeField from src.plugin_system.base.config_types import ConfigField from .actions.read_feed_action import ReadFeedAction @@ -83,19 +83,16 @@ class MaiZoneRefactoredPlugin(BasePlugin): }, } + permission_nodes: list[PermissionNodeField] = [ + PermissionNodeField(node_name="send_feed", description="是否可以使用机器人发送QQ空间说说"), + PermissionNodeField(node_name="read_feed", description="是否可以使用机器人读取QQ空间说说"), + ] + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) async def on_plugin_loaded(self): """插件加载完成后的回调,初始化服务并启动后台任务""" - # --- 注册权限节点 --- - await permission_api.register_permission_node( - "plugin.maizone.send_feed", "是否可以使用机器人发送QQ空间说说", "maiZone", False - ) - await permission_api.register_permission_node( - "plugin.maizone.read_feed", "是否可以使用机器人读取QQ空间说说", "maiZone", True - ) - # --- 创建并注册所有服务实例 --- content_service = ContentService(self.get_config) image_service = ImageService(self.get_config) diff --git a/src/plugins/built_in/maizone_refactored/services/reply_tracker_service.py b/src/plugins/built_in/maizone_refactored/services/reply_tracker_service.py index 09e89daed..26306f837 100644 --- a/src/plugins/built_in/maizone_refactored/services/reply_tracker_service.py +++ b/src/plugins/built_in/maizone_refactored/services/reply_tracker_service.py @@ -137,7 +137,7 @@ class ReplyTrackerService: try: if temp_file.exists(): temp_file.unlink() - except: + except Exception: pass def _cleanup_old_records(self): diff --git a/src/plugins/built_in/permission_management/plugin.py b/src/plugins/built_in/permission_management/plugin.py index d85ca8dd5..1541e2f1c 100644 --- a/src/plugins/built_in/permission_management/plugin.py +++ b/src/plugins/built_in/permission_management/plugin.py @@ -12,7 +12,11 @@ from src.plugin_system.apis.permission_api import permission_api from src.plugin_system.apis.plugin_register_api import register_plugin from src.plugin_system.base.base_plugin import BasePlugin from src.plugin_system.base.command_args import CommandArgs -from src.plugin_system.base.component_types import ChatType, PlusCommandInfo +from src.plugin_system.base.component_types import ( + ChatType, + PermissionNodeField, + PlusCommandInfo, +) from src.plugin_system.base.config_types import ConfigField from src.plugin_system.base.plus_command import PlusCommand from src.plugin_system.utils.permission_decorators import require_permission @@ -33,14 +37,16 @@ class PermissionCommand(PlusCommand): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - async def on_plugin_loaded(self): - # 注册权限节点(使用显式前缀,避免再次自动补全) - await permission_api.register_permission_node( - "plugin.permission.manage", "权限管理:可以授权和撤销其他用户的权限", "permission_manager", False - ) - await permission_api.register_permission_node( - "plugin.permission.view", "权限查看:可以查看权限节点和用户权限信息", "permission_manager", True - ) + permission_nodes: list[PermissionNodeField] = [ + PermissionNodeField( + node_name="manage", + description="权限管理:可以授权和撤销其他用户的权限", + ), + PermissionNodeField( + node_name="view", + description="权限查看:可以查看权限节点和用户权限信息", + ), + ] async def execute(self, args: CommandArgs) -> tuple[bool, str | None, bool]: """执行权限管理命令""" @@ -225,7 +231,7 @@ class PermissionCommand(PlusCommand): target_user_id = chat_stream.user_info.user_id # 检查是否为Master用户 - is_master = await permission_api.is_master(chat_stream.platform, target_user_id) + is_master = permission_api.is_master(chat_stream.platform, target_user_id) # 获取用户权限 permissions = await permission_api.get_user_permissions(chat_stream.platform, target_user_id) @@ -258,7 +264,7 @@ class PermissionCommand(PlusCommand): # 检查权限 has_permission = await permission_api.check_permission(chat_stream.platform, user_id, permission_node) - is_master = await permission_api.is_master(chat_stream.platform, user_id) + is_master = permission_api.is_master(chat_stream.platform, user_id) if has_permission: if is_master: