refactor(permission): 优化权限装饰器逻辑并增强健壮性

对权限系统进行了一系列重构和加固,主要包括:

- **增强健壮性**:在 `require_permission` 和 `require_master` 装饰器中增加了对 `user_info` 和 `user_id` 的存在性检查。当无法获取用户信息时,会记录警告日志并安全退出,防止因用户信息缺失导致程序崩溃。
- **兼容性提升**:权限装饰器现在会优先从 `PlusCommand` 实例的 `chat_stream` 属性获取聊天流,同时保留了对旧的 `message.chat_stream` 属性的兼容性支持,使代码更具前瞻性。
- **异步改造**:将 `is_master` 方法从同步改为异步,以统一权限检查的调用方式,并为未来可能引入的异步权限源做好准备。
- **代码简化**:移除了部分冗余注释,使代码更加清晰。
This commit is contained in:
tt-P607
2025-11-01 02:32:15 +08:00
committed by Windpicker-owo
parent f446e28571
commit db054e9537
2 changed files with 36 additions and 9 deletions

View File

@@ -51,9 +51,12 @@ def require_permission(permission_node: str, deny_message: str | None = None):
# 如果还没找到,检查是否是 PlusCommand 方法调用
if chat_stream is None and args:
# 检查第一个参数是否有 message.chat_stream 属性PlusCommand 实例)
instance = args[0]
if hasattr(instance, "message") and hasattr(instance.message, "chat_stream"):
# 检查第一个参数是否有 chat_stream 属性PlusCommand 实例)
if hasattr(instance, "chat_stream"):
chat_stream = instance.chat_stream
# 兼容旧的 message.chat_stream 属性
elif hasattr(instance, "message") and hasattr(instance.message, "chat_stream"):
chat_stream = instance.message.chat_stream
if chat_stream is None:
@@ -61,6 +64,12 @@ def require_permission(permission_node: str, deny_message: str | None = None):
return None
# 检查权限
if not chat_stream.user_info or not chat_stream.user_info.user_id:
logger.warning(f"权限检查失败chat_stream 中缺少 user_info 或 user_id函数: {func.__name__}")
if func.__name__ == "execute" and hasattr(args[0], "send_text"):
return False, "无法获取用户信息", True
return None
has_permission = await permission_api.check_permission(
chat_stream.platform, chat_stream.user_info.user_id, permission_node
)
@@ -124,9 +133,12 @@ def require_master(deny_message: str | None = None):
# 如果还没找到,检查是否是 PlusCommand 方法调用
if chat_stream is None and args:
# 检查第一个参数是否有 message.chat_stream 属性PlusCommand 实例)
instance = args[0]
if hasattr(instance, "message") and hasattr(instance.message, "chat_stream"):
# 检查第一个参数是否有 chat_stream 属性PlusCommand 实例)
if hasattr(instance, "chat_stream"):
chat_stream = instance.chat_stream
# 兼容旧的 message.chat_stream 属性
elif hasattr(instance, "message") and hasattr(instance.message, "chat_stream"):
chat_stream = instance.message.chat_stream
if chat_stream is None:
@@ -134,7 +146,13 @@ def require_master(deny_message: str | None = None):
return None
# 检查是否为Master用户
is_master = permission_api.is_master(chat_stream.platform, chat_stream.user_info.user_id)
if not chat_stream.user_info or not chat_stream.user_info.user_id:
logger.warning(f"Master权限检查失败chat_stream 中缺少 user_info 或 user_id函数: {func.__name__}")
if func.__name__ == "execute" and hasattr(args[0], "send_text"):
return False, "无法获取用户信息", True
return None
is_master = await permission_api.is_master(chat_stream.platform, chat_stream.user_info.user_id)
if not is_master:
message = deny_message or "❌ 此操作仅限Master用户执行"
@@ -173,7 +191,7 @@ class PermissionChecker:
)
@staticmethod
def is_master(chat_stream: ChatStream) -> bool:
async def is_master(chat_stream: ChatStream) -> bool:
"""
检查用户是否为Master用户
@@ -183,7 +201,9 @@ class PermissionChecker:
Returns:
bool: 是否为Master用户
"""
return permission_api.is_master(chat_stream.platform, chat_stream.user_info.user_id)
if not chat_stream.user_info or not chat_stream.user_info.user_id:
return False
return await permission_api.is_master(chat_stream.platform, chat_stream.user_info.user_id)
@staticmethod
async def ensure_permission(chat_stream: ChatStream, permission_node: str, deny_message: str | None = None) -> bool:
@@ -198,6 +218,8 @@ class PermissionChecker:
Returns:
bool: 是否拥有权限
"""
if not chat_stream.user_info or not chat_stream.user_info.user_id:
return False
has_permission = await permission_api.check_permission(
chat_stream.platform, chat_stream.user_info.user_id, permission_node
)
@@ -218,7 +240,7 @@ class PermissionChecker:
Returns:
bool: 是否为Master用户
"""
is_master = PermissionChecker.is_master(chat_stream)
is_master = await PermissionChecker.is_master(chat_stream)
if not is_master:
message = deny_message or "❌ 此操作仅限Master用户执行"

View File

@@ -35,7 +35,12 @@ class SendFeedCommand(PlusCommand):
"""
topic = args.get_remaining()
stream_id = self.message.chat_stream.stream_id
if not self.chat_stream:
logger.error("无法获取聊天流信息,操作中止")
return False, "无法获取聊天流信息", True
stream_id = self.chat_stream.stream_id
await self.send_text(f"收到!正在为你生成关于“{topic or '随机'}”的说说,请稍候...")