nonebot2/nonebot/permission.py

216 lines
6.4 KiB
Python
Raw Normal View History

2020-09-14 20:48:03 +08:00
"""
权限
====
每个 ``Matcher`` 拥有一个 ``Permission`` 其中是 **异步** ``PermissionChecker`` 的集合只要有一个 ``PermissionChecker`` 检查结果为 ``True`` 时就会继续运行
\:\:\:tip 提示
``PermissionChecker`` 既可以是 async function 也可以是 sync function
\:\:\:
"""
2020-08-17 16:09:41 +08:00
import asyncio
2020-12-06 02:30:19 +08:00
from typing import Union, Optional, Callable, NoReturn, Awaitable, TYPE_CHECKING
2020-08-17 16:09:41 +08:00
from nonebot.utils import run_sync
2020-12-06 02:30:19 +08:00
from nonebot.typing import PermissionChecker
if TYPE_CHECKING:
2020-12-07 00:06:09 +08:00
from nonebot.adapters import Bot, Event
2020-08-17 16:09:41 +08:00
class Permission:
__slots__ = ("checkers",)
2020-12-06 02:30:19 +08:00
def __init__(
self, *checkers: Callable[["Bot", "Event"],
Awaitable[bool]]) -> None:
2020-09-14 20:48:03 +08:00
"""
:参数:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
* ``*checkers: Callable[[Bot, Event], Awaitable[bool]]``: **异步** PermissionChecker
"""
2020-09-13 13:01:23 +08:00
self.checkers = set(checkers)
2020-09-14 20:48:03 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
存储 ``PermissionChecker``
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
:类型:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
* ``Set[Callable[[Bot, Event], Awaitable[bool]]]``
"""
2020-08-17 16:09:41 +08:00
2020-12-06 02:30:19 +08:00
async def __call__(self, bot: "Bot", event: "Event") -> bool:
2020-09-14 20:48:03 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
检查是否满足某个权限
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
* ``bot: Bot``: Bot 对象
* ``event: Event``: Event 对象
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
:返回:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
- ``bool``
"""
2020-08-17 16:09:41 +08:00
if not self.checkers:
return True
results = await asyncio.gather(
*map(lambda c: c(bot, event), self.checkers))
return any(results)
def __and__(self, other) -> NoReturn:
raise RuntimeError("And operation between Permissions is not allowed.")
2020-09-27 18:05:13 +08:00
def __or__(
self, other: Optional[Union["Permission",
PermissionChecker]]) -> "Permission":
2020-09-13 13:01:23 +08:00
checkers = self.checkers.copy()
2020-09-27 18:05:13 +08:00
if other is None:
return self
elif isinstance(other, Permission):
2020-09-13 13:01:23 +08:00
checkers |= other.checkers
2020-08-17 16:09:41 +08:00
elif asyncio.iscoroutinefunction(other):
2020-09-13 22:36:40 +08:00
checkers.add(other) # type: ignore
2020-08-17 16:09:41 +08:00
else:
2020-09-13 13:01:23 +08:00
checkers.add(run_sync(other))
2020-08-17 16:09:41 +08:00
return Permission(*checkers)
2020-12-06 02:30:19 +08:00
async def _message(bot: "Bot", event: "Event") -> bool:
2020-12-09 19:57:49 +08:00
return event.get_type() == "message"
2020-08-17 16:09:41 +08:00
2020-12-06 02:30:19 +08:00
async def _notice(bot: "Bot", event: "Event") -> bool:
2020-12-09 19:57:49 +08:00
return event.get_type() == "notice"
2020-08-17 16:09:41 +08:00
2020-12-06 02:30:19 +08:00
async def _request(bot: "Bot", event: "Event") -> bool:
2020-12-09 19:57:49 +08:00
return event.get_type() == "request"
2020-08-17 16:09:41 +08:00
2020-12-06 02:30:19 +08:00
async def _metaevent(bot: "Bot", event: "Event") -> bool:
2020-12-09 19:57:49 +08:00
return event.get_type() == "meta_event"
2020-08-17 16:09:41 +08:00
MESSAGE = Permission(_message)
2020-09-14 20:48:03 +08:00
"""
- **说明**: 匹配任意 ``message`` 类型事件仅在需要同时捕获不同类型事件时使用优先使用 message type Matcher
"""
2020-08-17 16:09:41 +08:00
NOTICE = Permission(_notice)
2020-09-14 20:48:03 +08:00
"""
- **说明**: 匹配任意 ``notice`` 类型事件仅在需要同时捕获不同类型事件时使用优先使用 notice type Matcher
"""
2020-08-17 16:09:41 +08:00
REQUEST = Permission(_request)
2020-09-14 20:48:03 +08:00
"""
- **说明**: 匹配任意 ``request`` 类型事件仅在需要同时捕获不同类型事件时使用优先使用 request type Matcher
"""
2020-08-17 16:09:41 +08:00
METAEVENT = Permission(_metaevent)
2020-09-14 20:48:03 +08:00
"""
- **说明**: 匹配任意 ``meta_event`` 类型事件仅在需要同时捕获不同类型事件时使用优先使用 meta_event type Matcher
"""
2020-08-17 16:09:41 +08:00
2020-12-09 19:57:49 +08:00
def USER(*user: str, perm: Permission = Permission()):
2020-09-14 20:48:03 +08:00
"""
:说明:
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
在白名单内且满足 perm
2020-11-30 11:08:00 +08:00
2020-09-14 20:48:03 +08:00
:参数:
2020-11-30 11:08:00 +08:00
2020-12-09 19:57:49 +08:00
* ``*user: str``: 白名单
2020-09-14 20:48:03 +08:00
* ``perm: Permission``: 需要同时满足的权限
"""
2020-08-17 16:09:41 +08:00
2020-12-06 02:30:19 +08:00
async def _user(bot: "Bot", event: "Event") -> bool:
2020-12-09 19:57:49 +08:00
return event.get_type() == "message" and event.get_session_id(
) in user and await perm(bot, event)
2020-08-17 16:09:41 +08:00
return Permission(_user)
2020-12-09 19:57:49 +08:00
# async def _private(bot: "Bot", event: "Event") -> bool:
# return event.get_type() == "message" and event.detail_type == "private"
# async def _private_friend(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "private" and
# event.sub_type == "friend")
# async def _private_group(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "private" and
# event.sub_type == "group")
# async def _private_other(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "private" and
# event.sub_type == "other")
# PRIVATE = Permission(_private)
# """
# - **说明**: 匹配任意私聊消息类型事件
# """
# PRIVATE_FRIEND = Permission(_private_friend)
# """
# - **说明**: 匹配任意好友私聊消息类型事件
# """
# PRIVATE_GROUP = Permission(_private_group)
# """
# - **说明**: 匹配任意群临时私聊消息类型事件
# """
# PRIVATE_OTHER = Permission(_private_other)
# """
# - **说明**: 匹配任意其他私聊消息类型事件
# """
# async def _group(bot: "Bot", event: "Event") -> bool:
# return event.get_type() == "message" and event.detail_type == "group"
# async def _group_member(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "group" and
# event.sender.get("role") == "member")
# async def _group_admin(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "group" and
# event.sender.get("role") == "admin")
# async def _group_owner(bot: "Bot", event: "Event") -> bool:
# return (event.get_type() == "message" and event.detail_type == "group" and
# event.sender.get("role") == "owner")
# GROUP = Permission(_group)
# """
# - **说明**: 匹配任意群聊消息类型事件
# """
# GROUP_MEMBER = Permission(_group_member)
# """
# - **说明**: 匹配任意群员群聊消息类型事件
# \:\:\:warning 警告
# 该权限通过 event.sender 进行判断且不包含管理员以及群主!
# \:\:\:
# """
# GROUP_ADMIN = Permission(_group_admin)
# """
# - **说明**: 匹配任意群管理员群聊消息类型事件
# """
# GROUP_OWNER = Permission(_group_owner)
# """
# - **说明**: 匹配任意群主群聊消息类型事件
# """
# async def _superuser(bot: "Bot", event: "Event") -> bool:
# return event.get_type(
# ) == "message" and event.user_id in bot.config.superusers
# SUPERUSER = Permission(_superuser)
# """
# - **说明**: 匹配任意超级用户消息类型事件
# """
# EVERYBODY = MESSAGE
# """
# - **说明**: 匹配任意消息类型事件
# """