diff --git a/src/Simplex/Chat/Library/Commands.hs b/src/Simplex/Chat/Library/Commands.hs index 4bbfa8e09d..d7e5ead0de 100644 --- a/src/Simplex/Chat/Library/Commands.hs +++ b/src/Simplex/Chat/Library/Commands.hs @@ -2643,8 +2643,7 @@ processChatCommand vr nm = \case Nothing -> throwChatError $ CEContactNotActive ct APIAcceptMember groupId gmId role -> withUser $ \user@User {userId} -> do (gInfo, m) <- withFastStore $ \db -> (,) <$> getGroupInfo db vr user groupId <*> getGroupMemberById db vr user gmId - -- TODO check that user's role is > role, possibly restrict role to only observer and member - assertUserGroupRole gInfo GRModerator + assertUserGroupRole gInfo $ max GRModerator role case memberStatus m of GSMemPendingApproval | memberCategory m == GCInviteeMember -> do -- only host can approve let GroupInfo {groupProfile = GroupProfile {memberAdmission}} = gInfo diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index 08ca90f2a6..1af0b07361 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -2601,6 +2601,8 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = xGrpLinkAcpt :: GroupInfo -> GroupMember -> GroupAcceptance -> GroupMemberRole -> MemberId -> RcvMessage -> UTCTime -> CM () xGrpLinkAcpt gInfo@GroupInfo {membership} m acceptance role memberId msg brokerTs + | memberRole' m < GRModerator || memberRole' m < role = + messageError "x.grp.link.acpt with insufficient member permissions" | sameMemberId memberId membership = processUserAccepted | otherwise = withStore' (\db -> runExceptT $ getGroupMemberByMemberId db vr user gInfo memberId) >>= \case diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index e0ff178db4..82906110c6 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -3251,6 +3251,12 @@ testGLinkReviewMember = alice ##> "/_delete member chat #1 5" alice <## "bad chat command: member is pending" + -- moderator can't accept member with a role higher than their own + dan ##> "/_accept member #1 5 admin" + dan <## "#team: you have insufficient permissions for this action, the required role is admin" + dan ##> "/_accept member #1 5 owner" + dan <## "#team: you have insufficient permissions for this action, the required role is owner" + -- accept member dan ##> "/_accept member #1 5 member" concurrentlyN_