NoneBot 全局权限管理插件 (perms)

这是一个为 NoneBot2 设计的、中心化的、可分离的全局权限管理插件。它旨在将所有业务插件的权限逻辑统一起来,提供一个强大而易用的管理后台和指令。


✨ 特性

  • 中心化权限管理: 所有插件的权限都由本插件统一控制,告别分散的配置文件。
  • 可视化 Web UI: 提供一个简单易用的网页后台,让管理员可以直观地搜索用户/群组,并用开关管理权限。
  • 交互式指令: 提供带翻页功能的交互式指令 /权限管理,方便在 QQ 内快速授权。
  • 开发者友好: 其他插件接入极其简单,只需两步即可将自己的功能纳入权限系统。
  • 分层权限模型: 权限检查遵循 超级用户 > 用户精确授权 > 群组授权 > 角色等级 的链式逻辑,兼具灵活性和默认规则。

⚙️ 安装与配置

  1. 安装依赖:
    请在你的 NoneBot 项目环境下,通过终端运行以下命令:

    pip install sqlalchemy "passlib[bcrypt]==1.7.4" bcrypt==3.2.0
    pip install fastapi uvicorn jinja2 python-jose python-multipart
  2. 配置 .env 文件:
    在你的 .env.env.prod 文件中添加以下配置项:

    # ===============================
    # 权限管理插件 (perms) 配置
    # ===============================
    # Web UI 监听的主机地址, 0.0.0.0 表示允许外网访问
    AUTH_WEB_HOST="127.0.0.1"
    
    # Web UI 监听的端口 (请确保此端口未被 NoneBot 主程序或其他应用占用)
    AUTH_WEB_PORT=8082
    
    # 登录 Web UI 的密码
    AUTH_WEB_PASSWORD="your_strong_password_here"

🎮 管理员使用

1. Web UI (推荐)

  1. 启动你的 NoneBot。
  2. 在浏览器中访问 http://<你的服务器IP>:<AUTH_WEB_PORT> (例如 http://127.0.0.1:8082)。
  3. 用户名为 admin,密码为你在 .env 文件中设置的 AUTH_WEB_PASSWORD
  4. 登录后,你可以搜索任何用户或群组的 QQ 号,并可视化地管理他们的权限。

2. QQ 指令

你可以通过指令在 QQ 群聊或私聊中管理权限。

  • 主指令: /权限管理/perms
  • 授予权限: /权限管理 授予 @用户
  • 撤销权限: /权限管理 撤销 [用户QQ号]

示例: /权限管理 授予 @张三

机器人会回复一个带翻页的权限菜单,你可以通过回复数字来选择要授予的权限,或回复 n/p 来进行翻页。


🚀 开发者集成

将你自己的插件接入本权限系统非常简单,只需两步:

第 1 步: 注册权限节点

在你插件的 __init__.py 文件中,声明你的插件有哪些功能可以被管理。

# file: /plugins/your_plugin/__init__.py

from nonebot import require, logger

try:
    # 引用权限插件 (请确保 'plugins.perms' 是你权限插件的正确路径)
    require("plugins.perms")
    from plugins.perms import register_node
    
    # 注册本插件的所有权限节点
    # 参数: 插件名, 节点字符串, 节点描述
    register_node("你的插件名", "your_plugin.feature_a", "功能A的权限")
    register_node("你的插件名", "your_plugin.feature_b", "功能B的权限")
    
except (ImportError, RuntimeError):
    logger.warning("权限插件 'perms' 未找到,你的插件权限节点将无法注册。")

第 2 步: 保护你的指令

在你插件的 main.py (或包含指令的文件) 中,使用 PermissionChecker 来保护你的指令。

推荐使用现代 NoneBot2 的 dependencies 写法:

# file: /plugins/your_plugin/main.py

from nonebot import on_command
from nonebot.params import Depends

# 从我们的权限插件中导入核心组件
from plugins.perms import PermissionChecker, PermissionLevel

# 用一行代码完成权限声明
feature_a_matcher = on_command(
    "功能A",
    priority=1,
    # 声明:此指令需要 "your_plugin.feature_a" 权限,
    # 并且默认只有群管理员(ADMIN)及以上才能使用
    dependencies=[Depends(PermissionChecker("your_plugin.feature_a", level=PermissionLevel.ADMIN))]
)

@feature_a_matcher.handle()
async def _():
    # 权限检查已自动完成,这里只用写核心业务逻辑
    await feature_a_matcher.finish("功能A执行成功!")

PermissionCheckerlevel 参数是你为该指令设置的默认权限等级,可选值有:

  • PermissionLevel.USER (默认值,任何人)
  • PermissionLevel.ADMIN (群管理员)
  • PermissionLevel.OWNER (群主)
  • PermissionLevel.SUPERUSER (超级用户)

即使设置了默认等级,超级管理员依然可以在 Web UI 或通过指令进行更精确的、覆盖默认规则的授权。