From cd30be21ba6dc3030f9dce1cc0a9396c43794e49 Mon Sep 17 00:00:00 2001 From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> Date: Thu, 1 Sep 2022 10:41:43 +0800 Subject: [PATCH] :bug: fix nested user permission update (#1208) --- nonebot/internal/matcher.py | 22 ++++++++++------ tests/plugins/matcher/matcher_permission.py | 6 ++++- tests/test_matcher.py | 14 ++++++++++ tests/test_permission.py | 29 ++++++++++++++++++++- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/nonebot/internal/matcher.py b/nonebot/internal/matcher.py index 4d05b786..d9b31f1e 100644 --- a/nonebot/internal/matcher.py +++ b/nonebot/internal/matcher.py @@ -44,7 +44,7 @@ from nonebot.exception import ( ) from .rule import Rule -from .permission import USER, Permission +from .permission import USER, User, Permission from .adapter import Bot, Event, Message, MessageSegment, MessageTemplate from .params import ( Depends, @@ -635,15 +635,21 @@ class Matcher(metaclass=MatcherMeta): async def update_type(self, bot: Bot, event: Event) -> str: updater = self.__class__._default_type_updater - if not updater: - return "message" - return await updater(bot=bot, event=event, state=self.state, matcher=self) + return ( + await updater(bot=bot, event=event, state=self.state, matcher=self) + if updater + else "message" + ) async def update_permission(self, bot: Bot, event: Event) -> Permission: - updater = self.__class__._default_permission_updater - if not updater: - return USER(event.get_session_id(), perm=self.permission) - return await updater(bot=bot, event=event, state=self.state, matcher=self) + if updater := self.__class__._default_permission_updater: + return await updater(bot=bot, event=event, state=self.state, matcher=self) + permission = self.permission + if len(permission.checkers) == 1 and isinstance( + user_perm := tuple(permission.checkers)[0].call, User + ): + permission = user_perm.perm + return USER(event.get_session_id(), perm=permission) async def resolve_reject(self): handler = current_handler.get() diff --git a/tests/plugins/matcher/matcher_permission.py b/tests/plugins/matcher/matcher_permission.py index 27a105b3..d4042502 100644 --- a/tests/plugins/matcher/matcher_permission.py +++ b/tests/plugins/matcher/matcher_permission.py @@ -1,10 +1,14 @@ from nonebot.matcher import Matcher -from nonebot.permission import Permission +from nonebot.permission import USER, Permission default_permission = Permission() test_permission_updater = Matcher.new(permission=default_permission) +test_user_permission_updater = Matcher.new( + permission=USER("test", perm=default_permission) +) + test_custom_updater = Matcher.new(permission=default_permission) diff --git a/tests/test_matcher.py b/tests/test_matcher.py index 187e5981..0e88179f 100644 --- a/tests/test_matcher.py +++ b/tests/test_matcher.py @@ -104,6 +104,7 @@ async def test_permission_updater(app: App, load_plugin): default_permission, test_custom_updater, test_permission_updater, + test_user_permission_updater, ) event = make_fake_event(_session_id="test")() @@ -119,6 +120,19 @@ async def test_permission_updater(app: App, load_plugin): assert checker.users == ("test",) assert checker.perm is default_permission + user_permission = list(test_user_permission_updater.permission.checkers)[0].call + assert isinstance(user_permission, User) + assert user_permission.perm is default_permission + async with app.test_api() as ctx: + bot = ctx.create_bot() + matcher = test_user_permission_updater() + new_perm = await matcher.update_permission(bot, event) + assert len(new_perm.checkers) == 1 + checker = list(new_perm.checkers)[0].call + assert isinstance(checker, User) + assert checker.users == ("test",) + assert checker.perm is default_permission + assert test_custom_updater.permission is default_permission async with app.test_api() as ctx: bot = ctx.create_bot() diff --git a/tests/test_permission.py b/tests/test_permission.py index d1d8e11e..965d2607 100644 --- a/tests/test_permission.py +++ b/tests/test_permission.py @@ -1,3 +1,5 @@ +from typing import Tuple + import pytest from nonebug import App @@ -145,7 +147,7 @@ async def test_metaevent( ("notice", "test", False), ], ) -async def test_startswith( +async def test_superuser( app: App, type: str, user_id: str, @@ -163,3 +165,28 @@ async def test_startswith( async with app.test_api() as ctx: bot = ctx.create_bot() assert await dependent(bot=bot, event=event) == expected + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "session_ids,session_id,expected", + [ + (("user", "foo"), "user", True), + (("user", "foo"), "bar", False), + ], +) +async def test_user( + app: App, session_ids: Tuple[str, ...], session_id: str, expected: bool +): + from nonebot.permission import USER, User + + dependent = list(USER(*session_ids).checkers)[0] + checker = dependent.call + + assert isinstance(checker, User) + + event = make_fake_event(_session_id=session_id)() + + async with app.test_api() as ctx: + bot = ctx.create_bot() + assert await dependent(bot=bot, event=event) == expected