Compare commits

...

4 Commits

Author SHA1 Message Date
spaced4ndy b05eb0199f fixing tests wip 2024-03-22 14:24:59 +04:00
spaced4ndy ad85db6434 test 2024-03-22 13:16:49 +04:00
spaced4ndy ad26e9a641 reorder 2024-03-22 12:53:31 +04:00
spaced4ndy d635ec28bd core: delete group link if user role lowers beyond admin 2024-03-22 12:52:08 +04:00
4 changed files with 79 additions and 15 deletions
+20 -11
View File
@@ -1665,7 +1665,9 @@ processChatCommand' vr = \case
APIMemberRole groupId memberId memRole -> withUser $ \user -> do APIMemberRole groupId memberId memRole -> withUser $ \user -> do
Group gInfo@GroupInfo {membership} members <- withStore $ \db -> getGroup db vr user groupId Group gInfo@GroupInfo {membership} members <- withStore $ \db -> getGroup db vr user groupId
if memberId == groupMemberId' membership if memberId == groupMemberId' membership
then changeMemberRole user gInfo members membership $ SGEUserRole memRole then do
when (memRole < GRAdmin) $ deleteGroupLinkIfExists user gInfo
changeMemberRole user gInfo members membership $ SGEUserRole memRole
else case find ((== memberId) . groupMemberId') members of else case find ((== memberId) . groupMemberId') members of
Just m -> changeMemberRole user gInfo members m $ SGEMemberRole memberId (fromLocalProfile $ memberProfile m) memRole Just m -> changeMemberRole user gInfo members m $ SGEMemberRole memberId (fromLocalProfile $ memberProfile m) memRole
_ -> throwChatError CEGroupMemberNotFound _ -> throwChatError CEGroupMemberNotFound
@@ -5490,21 +5492,28 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
xGrpMemRole :: GroupInfo -> GroupMember -> MemberId -> GroupMemberRole -> RcvMessage -> UTCTime -> m () xGrpMemRole :: GroupInfo -> GroupMember -> MemberId -> GroupMemberRole -> RcvMessage -> UTCTime -> m ()
xGrpMemRole gInfo@GroupInfo {membership} m@GroupMember {memberRole = senderRole} memId memRole msg brokerTs xGrpMemRole gInfo@GroupInfo {membership} m@GroupMember {memberRole = senderRole} memId memRole msg brokerTs
| membershipMemId == memId = | membershipMemId == memId =
let gInfo' = gInfo {membership = membership {memberRole = memRole}} checkRole membership $ do
in changeMemberRole gInfo' membership $ RGEUserRole memRole when (memRole < GRAdmin) $ deleteGroupLinkIfExists user gInfo
let gInfo' = gInfo {membership = membership {memberRole = memRole}}
changeMemberRole gInfo' membership $ RGEUserRole memRole
| otherwise = | otherwise =
withStore' (\db -> runExceptT $ getGroupMemberByMemberId db vr user gInfo memId) >>= \case withStore' (\db -> runExceptT $ getGroupMemberByMemberId db vr user gInfo memId) >>= \case
Right member -> changeMemberRole gInfo member $ RGEMemberRole (groupMemberId' member) (fromLocalProfile $ memberProfile member) memRole Right member ->
checkRole member $ do
let gEvent = RGEMemberRole (groupMemberId' member) (fromLocalProfile $ memberProfile member) memRole
changeMemberRole gInfo member gEvent
Left _ -> messageError "x.grp.mem.role with unknown member ID" Left _ -> messageError "x.grp.mem.role with unknown member ID"
where where
GroupMember {memberId = membershipMemId} = membership GroupMember {memberId = membershipMemId} = membership
changeMemberRole gInfo' member@GroupMember {memberRole = fromRole} gEvent checkRole GroupMember {memberRole = fromRole} a
| senderRole < GRAdmin || senderRole < fromRole = messageError "x.grp.mem.role with insufficient member permissions" | senderRole < GRAdmin || senderRole < fromRole =
| otherwise = do messageError "x.grp.mem.role with insufficient member permissions"
withStore' $ \db -> updateGroupMemberRole db user member memRole | otherwise = a
ci <- saveRcvChatItem user (CDGroupRcv gInfo m) msg brokerTs (CIRcvGroupEvent gEvent) changeMemberRole gInfo' member@GroupMember {memberRole = fromRole} gEvent = do
groupMsgToView gInfo ci withStore' $ \db -> updateGroupMemberRole db user member memRole
toView CRMemberRole {user, groupInfo = gInfo', byMember = m, member = member {memberRole = memRole}, fromRole, toRole = memRole} ci <- saveRcvChatItem user (CDGroupRcv gInfo m) msg brokerTs (CIRcvGroupEvent gEvent)
groupMsgToView gInfo ci
toView CRMemberRole {user, groupInfo = gInfo', byMember = m, member = member {memberRole = memRole}, fromRole, toRole = memRole}
checkHostRole :: GroupMember -> GroupMemberRole -> m () checkHostRole :: GroupMember -> GroupMemberRole -> m ()
checkHostRole GroupMember {memberRole, localDisplayName} memRole = checkHostRole GroupMember {memberRole, localDisplayName} memRole =
+2 -2
View File
@@ -38,7 +38,7 @@ directoryServiceTests = do
it "should de-list if service is removed from the group" testDelistedServiceRemoved it "should de-list if service is removed from the group" testDelistedServiceRemoved
it "should de-list/re-list when service/owner roles change" testDelistedRoleChanges it "should de-list/re-list when service/owner roles change" testDelistedRoleChanges
it "should NOT de-list if another member role changes" testNotDelistedMemberRoleChanged it "should NOT de-list if another member role changes" testNotDelistedMemberRoleChanged
it "should NOT send to approval if roles are incorrect" testNotSentApprovalBadRoles fit "should NOT send to approval if roles are incorrect" testNotSentApprovalBadRoles
it "should NOT allow approving if roles are incorrect" testNotApprovedBadRoles it "should NOT allow approving if roles are incorrect" testNotApprovedBadRoles
describe "should require re-approval if profile is changed by" $ do describe "should require re-approval if profile is changed by" $ do
it "the registration owner" testRegOwnerChangedProfile it "the registration owner" testRegOwnerChangedProfile
@@ -55,7 +55,7 @@ directoryServiceTests = do
describe "list groups" $ do describe "list groups" $ do
it "should list user's groups" testListUserGroups it "should list user's groups" testListUserGroups
describe "store log" $ do describe "store log" $ do
it "should restore directory service state" testRestoreDirectory fit "should restore directory service state" testRestoreDirectory
directoryProfile :: Profile directoryProfile :: Profile
directoryProfile = Profile {displayName = "SimpleX-Directory", fullName = "", image = Nothing, contactLink = Nothing, preferences = Nothing} directoryProfile = Profile {displayName = "SimpleX-Directory", fullName = "", image = Nothing, contactLink = Nothing, preferences = Nothing}
+2 -2
View File
@@ -346,8 +346,8 @@ getTermLine cc =
5000000 `timeout` atomically (readTQueue $ termQ cc) >>= \case 5000000 `timeout` atomically (readTQueue $ termQ cc) >>= \case
Just s -> do Just s -> do
-- remove condition to always echo virtual terminal -- remove condition to always echo virtual terminal
-- when True $ do when True $ do
when (printOutput cc) $ do -- when (printOutput cc) $ do
name <- userName cc name <- userName cc
putStrLn $ name <> ": " <> s putStrLn $ name <> ": " <> s
pure s pure s
+55
View File
@@ -78,6 +78,7 @@ chatGroupTests = do
it "invitee incognito" testGroupLinkNoContactInviteeIncognito it "invitee incognito" testGroupLinkNoContactInviteeIncognito
it "host profile received" testGroupLinkNoContactHostProfileReceived it "host profile received" testGroupLinkNoContactHostProfileReceived
it "existing contact merged" testGroupLinkNoContactExistingContactMerged it "existing contact merged" testGroupLinkNoContactExistingContactMerged
it "group link is deleted if user role lowers below admin" testGroupLinkUserRoleLowers
describe "group links without contact connection plan" $ do describe "group links without contact connection plan" $ do
it "group link without contact - known group" testPlanGroupLinkNoContactKnown it "group link without contact - known group" testPlanGroupLinkNoContactKnown
it "group link without contact - connecting" testPlanGroupLinkNoContactConnecting it "group link without contact - connecting" testPlanGroupLinkNoContactConnecting
@@ -3114,6 +3115,60 @@ testGroupLinkNoContactExistingContactMerged =
bob #> "#team hi there" bob #> "#team hi there"
alice <# "#team bob> hi there" alice <# "#team bob> hi there"
testGroupLinkUserRoleLowers :: HasCallStack => FilePath -> IO ()
testGroupLinkUserRoleLowers =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
alice ##> "/g team"
alice <## "group #team is created"
alice <## "to add members use /a team <name> or /create link #team"
alice ##> "/set history #team off"
alice <## "updated group preferences:"
alice <## "Recent history: off"
alice ##> "/create link #team"
gLink <- getGroupLink alice "team" GRMember True
-- lowering role from owner to admin - link works
alice ##> "/mr #team alice admin"
alice <## "#team: you changed your role from owner to admin"
bob ##> ("/c " <> gLink)
bob <## "connection request sent!"
alice <## "bob (Bob): accepting request to join group #team..."
concurrentlyN_
[ alice <## "#team: bob joined the group",
do
bob <## "#team: joining the group..."
bob <## "#team: you joined the group"
]
alice #> "#team hello"
bob <# "#team alice> hello"
bob #> "#team hi there"
alice <# "#team bob> hi there"
alice ##> "/mr #team bob admin"
alice <## "#team: you changed the role of bob from member to admin"
bob <## "#team: alice changed your role from member to admin"
-- lowering role below admin - link is deleted
bob ##> "/mr #team alice member"
bob <## "#team: you changed the role of alice from admin to member"
alice <## "#team: bob changed your role from admin to member"
cath ##> ("/c " <> gLink)
cath <## "error: connection authorization failed - this could happen if connection was deleted, secured with different credentials, or due to a bug - please re-create the connection"
cath ##> "/gs"
cath <## "you have no groups!"
cath <## "to create: /g <name>"
alice #> "#team hello"
bob <# "#team alice> hello"
bob #> "#team hi there"
alice <# "#team bob> hi there"
testPlanGroupLinkNoContactKnown :: HasCallStack => FilePath -> IO () testPlanGroupLinkNoContactKnown :: HasCallStack => FilePath -> IO ()
testPlanGroupLinkNoContactKnown = testPlanGroupLinkNoContactKnown =
testChat2 aliceProfile bobProfile $ testChat2 aliceProfile bobProfile $