From 998d5b327b01e745428ad392c37e1071c488fbba Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Fri, 15 Jun 2018 15:00:58 +0800 Subject: [PATCH] Add permission --- none/__init__.py | 6 ++++++ none/command.py | 40 +++++++++++++++++++++++++++++++++++----- none/helpers.py | 14 +++++++++++++- none/permissions.py | 12 ++++++++++++ plugins/base.py | 13 +++++++++++-- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/none/__init__.py b/none/__init__.py index e18d9432..ddd91450 100644 --- a/none/__init__.py +++ b/none/__init__.py @@ -1,4 +1,5 @@ import os +import sys import importlib import logging import re @@ -9,6 +10,11 @@ from aiocqhttp import CQHttp from aiocqhttp.message import Message logger = logging.getLogger('none') +default_handler = logging.StreamHandler(sys.stdout) +default_handler.setFormatter(logging.Formatter( + '[%(asctime)s] %(levelname)s: %(message)s' +)) +logger.addHandler(default_handler) from .plugin import handle_message, handle_notice, handle_request from .command import on_command diff --git a/none/command.py b/none/command.py index 06070ae9..809df42e 100644 --- a/none/command.py +++ b/none/command.py @@ -1,7 +1,8 @@ import re from typing import Tuple, Union, Callable, Iterable, Dict, Any, Optional -from aiocqhttp import CQHttp +from aiocqhttp import CQHttp, Error as CQHttpError +from aiocqhttp.message import Message from . import permissions as perm @@ -29,7 +30,34 @@ class Command: async def run(self, bot, ctx, session, *args, **kwargs) -> Any: # TODO: check permission - if isinstance(self.func, Callable): + permission = 0 + if ctx['user_id'] in bot.config.SUPERUSERS: + permission |= perm.IS_SUPERUSER + if ctx['message_type'] == 'private': + if ctx['sub_type'] == 'friend': + permission |= perm.IS_PRIVATE_FRIEND + elif ctx['sub_type'] == 'group': + permission |= perm.IS_PRIVATE_GROUP + elif ctx['sub_type'] == 'discuss': + permission |= perm.IS_PRIVATE_DISCUSS + elif ctx['sub_type'] == 'other': + permission |= perm.IS_PRIVATE_OTHER + elif ctx['message_type'] == 'group': + permission |= perm.IS_GROUP_MEMBER + if not ctx['anonymous']: + try: + member_info = await bot.get_group_member_info(**ctx) + if member_info: + if member_info['role'] == 'owner': + permission |= perm.IS_GROUP_OWNER + elif member_info['role'] == 'admin': + permission |= perm.IS_GROUP_ADMIN + except CQHttpError: + pass + elif ctx['message_type'] == 'discuss': + permission |= perm.IS_DISCUSS + + if isinstance(self.func, Callable) and permission & self.permission: return await self.func(bot, ctx, session) return None @@ -48,11 +76,13 @@ def _find_command(name: Tuple[str]) -> Optional[Command]: class Session: - __slots__ = ('cmd', 'arg', 'images', 'data', 'last_interaction') + __slots__ = ('cmd', 'arg', 'arg_text', + 'images', 'data', 'last_interaction') def __init__(self, cmd: Command, arg: str = ''): self.cmd = cmd self.arg = arg + self.arg_text = Message(arg).extract_plain_text() self.images = [] self.data = {} self.last_interaction = None @@ -60,7 +90,7 @@ class Session: async def handle_command(bot: CQHttp, ctx: Dict[str, Any]) -> bool: # TODO: check if there is a session - msg_text = ctx['message'].extract_plain_text().lstrip() + msg_text = str(ctx['message']).lstrip() for start in bot.config.COMMAND_START: if isinstance(start, type(re.compile(''))): @@ -98,7 +128,7 @@ async def handle_command(bot: CQHttp, ctx: Dict[str, Any]) -> bool: if not cmd: return False - session = Session(cmd, ''.join(cmd_remained)) + session = Session(cmd=cmd, arg=''.join(cmd_remained)) session.images = [s.data['url'] for s in ctx['message'] if s.type == 'image' and 'url' in s.data] await cmd.run(bot, ctx, session) diff --git a/none/helpers.py b/none/helpers.py index 3320fe76..ab668673 100644 --- a/none/helpers.py +++ b/none/helpers.py @@ -1,4 +1,6 @@ -from typing import Dict, Any +from typing import Dict, Any, Union, List + +from aiocqhttp import CQHttp, Error as CQHttpError def context_source(ctx: Dict[str, Any]) -> str: @@ -10,3 +12,13 @@ def context_source(ctx: Dict[str, Any]) -> str: if ctx.get('user_id'): src += 'p%s' % ctx['user_id'] return src + + +async def send(bot: CQHttp, ctx: Dict[str, Any], + message: Union[str, Dict[str, Any], List[Dict[str, Any]]], + *, ignore_failure: bool = True) -> None: + try: + await bot.send(ctx, message) + except CQHttpError: + if not ignore_failure: + raise diff --git a/none/permissions.py b/none/permissions.py index 4a843697..b72274c4 100644 --- a/none/permissions.py +++ b/none/permissions.py @@ -10,3 +10,15 @@ GROUP_OWNER = 0x0400 GROUP = 0x0F00 SUPERUSER = 0xF000 EVERYONE = 0xFFFF + +IS_PRIVATE_FRIEND = PRIVATE_FRIEND +IS_PRIVATE_GROUP = PRIVATE_GROUP +IS_PRIVATE_DISCUSS = PRIVATE_DISCUSS +IS_PRIVATE_OTHER = PRIVATE_OTHER +IS_PRIVATE = PRIVATE +IS_DISCUSS = DISCUSS +IS_GROUP_MEMBER = GROUP_MEMBER +IS_GROUP_ADMIN = GROUP_MEMBER | GROUP_ADMIN +IS_GROUP_OWNER = GROUP_ADMIN | GROUP_OWNER +IS_GROUP = GROUP +IS_SUPERUSER = 0xFFFF diff --git a/plugins/base.py b/plugins/base.py index 662ccbfa..c217efbf 100644 --- a/plugins/base.py +++ b/plugins/base.py @@ -1,6 +1,15 @@ +from aiocqhttp.message import unescape + import none +from none import permissions as perm +from none.helpers import send -@none.on_command('echo', aliases=('say',)) +@none.on_command('echo') async def _(bot, ctx, session): - await bot.send(ctx, session.arg) + await send(bot, ctx, session.arg) + + +@none.on_command('say', permission=perm.SUPERUSER) +async def _(bot, ctx, session): + await send(bot, ctx, unescape(session.arg))