nonebot2/nonebot/permission.py
2020-09-13 22:36:40 +08:00

126 lines
3.7 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import asyncio
from nonebot.utils import run_sync
from nonebot.typing import Bot, Event, Union, NoReturn, Callable, Awaitable, PermissionChecker
class Permission:
__slots__ = ("checkers",)
def __init__(self, *checkers: Callable[[Bot, Event],
Awaitable[bool]]) -> None:
self.checkers = set(checkers)
async def __call__(self, bot: Bot, event: Event) -> bool:
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.")
def __or__(self, other: Union["Permission",
PermissionChecker]) -> "Permission":
checkers = self.checkers.copy()
if isinstance(other, Permission):
checkers |= other.checkers
elif asyncio.iscoroutinefunction(other):
checkers.add(other) # type: ignore
else:
checkers.add(run_sync(other))
return Permission(*checkers)
async def _message(bot: Bot, event: Event) -> bool:
return event.type == "message"
async def _notice(bot: Bot, event: Event) -> bool:
return event.type == "notice"
async def _request(bot: Bot, event: Event) -> bool:
return event.type == "request"
async def _metaevent(bot: Bot, event: Event) -> bool:
return event.type == "meta_event"
MESSAGE = Permission(_message)
NOTICE = Permission(_notice)
REQUEST = Permission(_request)
METAEVENT = Permission(_metaevent)
def USER(*user: int, perm: Permission = Permission()):
async def _user(bot: Bot, event: Event) -> bool:
return event.type == "message" and event.user_id in user and await perm(
bot, event)
return Permission(_user)
async def _private(bot: Bot, event: Event) -> bool:
return event.type == "message" and event.detail_type == "private"
async def _private_friend(bot: Bot, event: Event) -> bool:
return (event.type == "message" and event.detail_type == "private" and
event.sub_type == "friend")
async def _private_group(bot: Bot, event: Event) -> bool:
return (event.type == "message" and event.detail_type == "private" and
event.sub_type == "group")
async def _private_other(bot: Bot, event: Event) -> bool:
return (event.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.type == "message" and event.detail_type == "group"
async def _group_member(bot: Bot, event: Event) -> bool:
return (event.type == "message" and event.detail_type == "group" and
event.sender.get("role") == "member")
async def _group_admin(bot: Bot, event: Event) -> bool:
return (event.type == "message" and event.detail_type == "group" and
event.sender.get("role") == "admin")
async def _group_owner(bot: Bot, event: Event) -> bool:
return (event.type == "message" and event.detail_type == "group" and
event.sender.get("role") == "owner")
GROUP = Permission(_group)
GROUP_MEMBER = Permission(_group_member)
GROUP_ADMIN = Permission(_group_admin)
GROUP_OWNER = Permission(_group_owner)
async def _superuser(bot: Bot, event: Event) -> bool:
return event.type == "message" and event.user_id in bot.config.superusers
SUPERUSER = Permission(_superuser)
EVERYBODY = MESSAGE