From 64909eeeff3248e424f942d73566dbf43b29d3a4 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:44:36 +0400 Subject: [PATCH] fix role check --- src/Simplex/Chat/Library/Subscriber.hs | 4 +++- tests/ChatTests/Groups.hs | 32 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 88e9c283af..5ee5611d0d 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -3238,7 +3238,9 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage = -- applyMember writes the change (role, or role + pinned key for a freshly TOFU-created member); -- the delivery scope (relay forwarding) is computed on the pre-change role changeMemberRole gInfo' member@GroupMember {memberRole = fromRole} applyMember gEvent - | senderRole < GRAdmin || senderRole < fromRole = + | senderRole < GRAdmin + || senderRole < fromRole + || senderRole < memRole = messageError "x.grp.mem.role with insufficient member permissions" $> Nothing | useRelays' gInfo && (isRosterRole memRole || isRosterRole fromRole) && senderRole /= GROwner = messageError "x.grp.mem.role: only the owner can change member, moderator and admin roles in relay groups" $> Nothing diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 5f55c38990..d2f23e2b89 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -83,6 +83,7 @@ chatGroupTests = do it "group live message" testGroupLiveMessage it "update group profile" testUpdateGroupProfile it "update member role" testUpdateMemberRole + it "reject inbound admin owner role change" testRejectInboundAdminOwnerRoleChange it "group description is shown as the first message to new members" testGroupDescription it "moderate message of another group member" testGroupModerate it "moderate own message (should process as deletion)" testGroupModerateOwn @@ -1628,6 +1629,37 @@ testUpdateMemberRole = alice ##> "/mr team alice admin" alice <## "bad chat command: can't change role for self" +testRejectInboundAdminOwnerRoleChange :: HasCallStack => TestParams -> IO () +testRejectInboundAdminOwnerRoleChange = + testChat3 aliceProfile bobProfile cathProfile $ + \alice bob cath -> do + createGroup3 "team" alice bob cath + void $ withCCTransaction cath $ \db -> + DB.execute_ + db + [sql| + UPDATE group_members + SET member_role = 'owner' + WHERE member_category = 'user' + AND group_id IN ( + SELECT group_id FROM groups WHERE local_display_name = 'team' + ) + |] + + cath ##> "/mr #team bob owner" + cath <## "#team: you changed the role of bob to owner" + concurrentlyN_ + [ alice <## "error: x.grp.mem.role with insufficient member permissions", + bob <## "error: x.grp.mem.role with insufficient member permissions" + ] + + bob ##> "/ms team" + bob + <### [ "alice (Alice): owner, host, connected", + "bob (Bob): admin, you, connected", + "cath (Catherine): admin, connected" + ] + testGroupDescription :: HasCallStack => TestParams -> IO () testGroupDescription = testChat4 aliceProfile bobProfile cathProfile danProfile $ \alice bob cath dan -> do connectUsers alice bob