nonebot2/docs/advanced/permission.md
2021-05-20 20:20:51 +08:00

3.6 KiB

权限控制

权限控制是机器人在实际应用中需要解决的重点问题之一,Nonebot 提供了十分完善且灵活的权限控制机制——Permission机制,这个机制与Rule。接下来我们将对这个机制进行简单的说明。

应用

如同Rule一样, Permission可以在注册事件响应器时添加permission参数来加以应用,这样Nonebot会在事件响应时检测事件主体的权限。下面我们以SUPERUSER为例,对该机制的应用做一下介绍。

from nonebot.permission import SUPERUSER
from nonebot.adapters import Bot
from nonebot import on_command

matcher = on_command('测试超管', permission=SUPERUSER)


@matcher.handle()
async def _(bot: Bot):
    await matcher.send("超管命令测试成功")


@matcher.got("key1", "超管提问")
async def _(bot: Bot, event: Event):
    await matcher.send("超管命令got成功")

在这段代码中,我们事件响应器指定了SUPERUSER这样一个权限,那么机器人只会响应超级管理员的测试超管命令,并且会响应该超级管理员的连续对话。

::: tip 提示

在这里需要强调的是,PermissionRule的表现并不相同,Rule只会在初次响应时生效,在余下的对话中并没有限制事件;但是Permission会持续生效,在连续对话中会一直对事件主体加以限制。

:::

进阶

Permission除了可以在注册事件响应器时加以应用,还可以在编写事件处理函数handler时主动调用,我们可以利用这个特性在一个handler里对不同权限的事件主体进行区别响应,下面我们以 CQHTTP中的GROUP_ADMIN (普通管理员非群主)和GROUP_OWNER为例,说明下怎么进行主动调用。

from nonebot.adapters.cqhttp import Bot
from nonebot.adapters.cqhttp.event import GroupMessageEvent
from nonebot.adapters.cqhttp.permission import GROUP_ADMIN, GROUP_OWNER
from nonebot import on_command

matcher = on_command("测试权限")


@matcher.handle()
async def _(bot: Bot, event: GroupMessageEvent):
    if await GROUP_ADMIN(bot, event):
        await matcher.send("管理员测试成功")
    elif await GROUP_OWNER(bot, event):
        await matcher.send("群主测试成功")
    else:
        await matcher.send("群员测试成功")
      

在这段代码里,我们并没有对命令的权限指定,这个命令会响应所有在群聊中的测试权限命令,但是在handler里,我们对两个Permission进行主动调用,从而可以对不同的角色进行不同的响应。

自定义

如同Rule一样, Permission也是由非负数个PermissionChecker组成的,但只需其中一个返回True时就会匹配成功。下面则是PermissionCheckerPermission示例:

from nonebot.permission import Permission
from nonebot.adapters import Bot, Event

async def async_checker(bot: Bot, event: Event) -> bool:
	return True

def sync_checker(bot: Bot, event: Event) -> bool:
	return True

def check(arg1, arg2):

	async def _checker(bot: Bot, event: Event) -> bool:
    	return bool(arg1 + arg2)

	return Permission(_checker)

PermissionPermissionChecker 之间可以使用 或 | 互相组合:

from nonebot.permission import Permission

Permission(async_checker1) | sync_checker | async_checker2

同样地,如果想用Permission(*checkers) 包裹构造Permission,函数必须是异步的;但是在利用或 |符号连接构造时,Nonebot会自动包裹同步函数为异步函数。