From 12e3c4fa9073da526aa2f01b5b8749317328e9c0 Mon Sep 17 00:00:00 2001 From: Eritque arcus <1930893235@qq.com> Date: Wed, 10 Nov 2021 22:39:18 +0800 Subject: [PATCH] check permission before recall (#1662) * recall check(owner sender) * recall check * test * fix permission check and test * update test * add one more test --- mirai-core/src/commonMain/kotlin/MiraiImpl.kt | 8 +- .../kotlin/notice/processors/RecallTest.kt | 154 ++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 mirai-core/src/commonTest/kotlin/notice/processors/RecallTest.kt diff --git a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt index 1fe021056..327e3d9e0 100644 --- a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt +++ b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt @@ -473,7 +473,13 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { else -> error("stub") } if (bot.id != source.fromId) { - group.checkBotPermission(MemberPermission.ADMINISTRATOR) + // if member leave, messageSource will throw exception(#1661) + when (group[source.fromId]?.permission ?: MemberPermission.MEMBER) { + MemberPermission.MEMBER -> group.checkBotPermission(MemberPermission.ADMINISTRATOR) + MemberPermission.ADMINISTRATOR -> group.checkBotPermission(MemberPermission.OWNER) + // bot cannot be owner + MemberPermission.OWNER -> throw PermissionDeniedException("Permission denied: cannot recall message from owner") + } } network.run { diff --git a/mirai-core/src/commonTest/kotlin/notice/processors/RecallTest.kt b/mirai-core/src/commonTest/kotlin/notice/processors/RecallTest.kt new file mode 100644 index 000000000..a93c9411f --- /dev/null +++ b/mirai-core/src/commonTest/kotlin/notice/processors/RecallTest.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2019-2021 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.notice.processors + +import net.mamoe.mirai.Bot +import net.mamoe.mirai.Mirai +import net.mamoe.mirai.contact.MemberPermission +import net.mamoe.mirai.contact.PermissionDeniedException +import net.mamoe.mirai.internal.message.OnlineMessageSourceFromGroupImpl +import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody +import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm +import net.mamoe.mirai.message.data.OnlineMessageSource +import net.mamoe.mirai.utils.hexToBytes +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +internal class RecallTest : AbstractNoticeProcessorTest() { + + fun source(b: Bot, senderid: Long, groupid: Long, permision: MemberPermission): OnlineMessageSource = + OnlineMessageSourceFromGroupImpl( + b, + listOf( + MsgComm.Msg( + msgHead = MsgComm.MsgHead( + fromUin = senderid, + toUin = b.id, + msgType = 82, + msgSeq = 1628, + msgTime = 1629, + msgUid = 1441, + groupInfo = MsgComm.GroupInfo( + groupCode = groupid, + groupType = 1, + groupInfoSeq = 624, + groupCard = "user3", + groupLevel = 1, + groupCardType = 2, + groupName = "testtest".toByteArray(), /* 74 65 73 74 74 65 73 74 */ + ), + fromAppid = 1, + fromInstid = 1, + userActive = 1, + ), + contentHead = MsgComm.ContentHead( + pkgNum = 1, + ), + msgBody = ImMsgBody.MsgBody( + richText = ImMsgBody.RichText( + attr = ImMsgBody.Attr( + codePage = 0, + time = 162, + random = -313, + size = 9, + effect = 0, + charSet = 134, + pitchAndFamily = 0, + fontName = "微软雅黑", + ), + elems = mutableListOf( + ImMsgBody.Elem( + text = ImMsgBody.Text( + str = "123123123", + ), + ), ImMsgBody.Elem( + elemFlags2 = ImMsgBody.ElemFlags2( + msgRptCnt = 1, + ), + ), ImMsgBody.Elem( + generalFlags = ImMsgBody.GeneralFlags( + pbReserve = "08 01 20 CB 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 00 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 02 10 02 90 04 80 01 B8 04 00 C0 04 00 CA 04 00 F8 04 00 88 05 00".hexToBytes(), + ), + ), ImMsgBody.Elem( + extraInfo = ImMsgBody.ExtraInfo( + nick = "user3", + level = permision.level, + groupMask = 1, + ), + ) + ), + ), + ), + ) + ) + ) + + @Test + suspend fun `recall member message without permission`() { + val bot = setBot(2) + val group = bot.addGroup(5, 3, MemberPermission.MEMBER).apply { + // owner + addMember(3, permission = MemberPermission.OWNER) + // sender + addMember(1, permission = MemberPermission.MEMBER) + } + assertThrows { + Mirai.recallMessage(bot, source(bot, 1, group.id, group.botPermission)) + } + } + + @Test + suspend fun `recall member message`() { + val bot = setBot(2) + val group = bot.addGroup(5, 3, MemberPermission.ADMINISTRATOR).apply { + // owner + addMember(3, permission = MemberPermission.OWNER) + // sender + addMember(1, permission = MemberPermission.MEMBER) + } + Mirai.recallMessage(bot, source(bot, 1, group.id, group.botPermission)) + } + + @Test + suspend fun `recall administrator message`() { + val bot = setBot(2) + val group = bot.addGroup(5, 3, MemberPermission.ADMINISTRATOR).apply { + // owner + addMember(3, permission = MemberPermission.OWNER) + // sender + addMember(1, permission = MemberPermission.ADMINISTRATOR) + } + assertThrows { + Mirai.recallMessage(bot, source(bot, 1, group.id, group.botPermission)) + } + } + + @Test + suspend fun `recall administrator message as owner`() { + val bot = setBot(2) + val group = bot.addGroup(5, 2, MemberPermission.OWNER).apply { + // sender + addMember(1, permission = MemberPermission.ADMINISTRATOR) + } + Mirai.recallMessage(bot, source(bot, 1, group.id, group.botPermission)) + } + + @Test + suspend fun `recall owner message`() { + val bot = setBot(2) + val group = bot.addGroup(5, 1, MemberPermission.ADMINISTRATOR).apply { + // sender + addMember(1, permission = MemberPermission.OWNER) + } + assertThrows { + Mirai.recallMessage(bot, source(bot, 1, group.id, group.botPermission)) + } + } +}