From 53fadbfc864bb40003250f5ac206ea8345643ddc Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Mon, 6 Mar 2023 21:29:45 +1000 Subject: [PATCH 1/5] FS-1530: Allow partial success when removing users from conversations --- services/galley/src/Galley/API/Action.hs | 66 +++++++++++++++----- services/galley/src/Galley/API/Federation.hs | 2 + services/galley/src/Galley/API/Teams.hs | 4 +- services/galley/src/Galley/API/Update.hs | 36 +++++++---- 4 files changed, 80 insertions(+), 28 deletions(-) diff --git a/services/galley/src/Galley/API/Action.hs b/services/galley/src/Galley/API/Action.hs index 7467c3ff90..7d4113b188 100644 --- a/services/galley/src/Galley/API/Action.hs +++ b/services/galley/src/Galley/API/Action.hs @@ -563,6 +563,7 @@ updateLocalConversation :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, + Member (Logger (Log.Msg -> Log.Msg)) r, HasConversationActionEffects tag r, SingI tag ) => @@ -601,6 +602,7 @@ updateLocalConversationUnchecked :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, + Member (Logger (Log.Msg -> Log.Msg)) r, HasConversationActionEffects tag r ) => Local Conversation -> @@ -620,9 +622,10 @@ updateLocalConversationUnchecked lconv qusr con action = do ensureConversationActionAllowed (sing @tag) lcnv action conv self -- perform action - (extraTargets, action') <- performAction tag qusr lconv action + (extraTargets, action') <- performAction tag qusr lconv action notifyConversationAction + True (sing @tag) qusr False @@ -680,8 +683,10 @@ notifyConversationAction :: ( Member FederatorAccess r, Member ExternalAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Log.Msg -> Log.Msg)) r ) => + Bool -> Sing tag -> Qualified UserId -> Bool -> @@ -690,7 +695,7 @@ notifyConversationAction :: BotsAndMembers -> ConversationAction (tag :: ConversationActionTag) -> Sem r LocalConversationUpdate -notifyConversationAction tag quid notifyOrigDomain con lconv targets action = do +notifyConversationAction failEarly tag quid notifyOrigDomain con lconv targets action = do now <- input let lcnv = fmap convId lconv conv = tUnqualified lconv @@ -715,19 +720,43 @@ notifyConversationAction tag quid notifyOrigDomain con lconv targets action = do { nrcConvId = convId conv, nrcProtocol = convProtocol conv } - E.runFederatedConcurrently_ (toList newDomains) $ \_ -> do - void $ fedClient @'Galley @"on-new-remote-conversation" nrc - - update <- fmap (fromMaybe (mkUpdate []) . asum . map tUnqualified) - . E.runFederatedConcurrently (toList (bmRemotes targets)) - $ \ruids -> do - let update = mkUpdate (tUnqualified ruids) - -- if notifyOrigDomain is false, filter out user from quid's domain, - -- because quid's backend will update local state and notify its users - -- itself using the ConversationUpdate returned by this function - if notifyOrigDomain || tDomain ruids /= qDomain quid - then fedClient @'Galley @"on-conversation-updated" update $> Nothing - else pure (Just update) + let errorIntolerant = do + E.runFederatedConcurrently_ (toList newDomains) $ \_ -> do + void $ fedClient @'Galley @"on-new-remote-conversation" nrc + fmap (fromMaybe (mkUpdate []) . asum . map tUnqualified) + . E.runFederatedConcurrently (toList (bmRemotes targets)) + $ \ruids -> do + let update = mkUpdate (tUnqualified ruids) + -- if notifyOrigDomain is false, filter out user from quid's domain, + -- because quid's backend will update local state and notify its users + -- itself using the ConversationUpdate returned by this function + if notifyOrigDomain || tDomain ruids /= qDomain quid + then fedClient @'Galley @"on-conversation-updated" update $> Nothing + else pure (Just update) + errorTolerant = do + fedEithers <- E.runFederatedConcurrentlyEither (toList newDomains) $ \_ -> do + void $ fedClient @'Galley @"on-new-remote-conversation" nrc + for_ fedEithers $ either + (logError "on-new-remote-conversation" "An error occurred while communicating with federated server: ") + (pure . tUnqualified) + updates <- + E.runFederatedConcurrentlyEither (toList (bmRemotes targets)) + $ \ruids -> do + let update = mkUpdate (tUnqualified ruids) + -- if notifyOrigDomain is false, filter out user from quid's domain, + -- because quid's backend will update local state and notify its users + -- itself using the ConversationUpdate returned by this function + if notifyOrigDomain || tDomain ruids /= qDomain quid + then fedClient @'Galley @"on-conversation-updated" update $> Nothing + else pure (Just update) + let f = fromMaybe (mkUpdate []) . asum . map tUnqualified . rights + update = f updates + for_ (lefts updates) $ logError + "on-conversation-update" + "An error occurred while communicating with federated server: " + pure update + + update <- if failEarly then errorIntolerant else errorTolerant -- notify local participants and bots pushConversationEvent con e (qualifyAs lcnv (bmLocals targets)) (bmBots targets) @@ -735,6 +764,10 @@ notifyConversationAction tag quid notifyOrigDomain con lconv targets action = do -- return both the event and the 'ConversationUpdate' structure corresponding -- to the originating domain (if it is remote) pure $ LocalConversationUpdate e update + where + logError :: Show a => String -> String -> (a, FederationError) -> Sem r () + logError field msg e = P.warn $ + Log.field "federation call" field . Log.msg (msg <> show e) -- | Notify all local members about a remote conversation update that originated -- from a local user @@ -809,6 +842,7 @@ kickMember qusr lconv targets victim = void . runError @NoChanges $ do lconv () notifyConversationAction + False (sing @'ConversationRemoveMembersTag) qusr True diff --git a/services/galley/src/Galley/API/Federation.hs b/services/galley/src/Galley/API/Federation.hs index 6610a5cbf6..4f280b25fb 100644 --- a/services/galley/src/Galley/API/Federation.hs +++ b/services/galley/src/Galley/API/Federation.hs @@ -371,6 +371,7 @@ leaveConversation requestingDomain lc = do let botsAndMembers = BotsAndMembers mempty (Set.fromList remotes) mempty _ <- notifyConversationAction + False SConversationLeaveTag (tUntagged leaver) False @@ -498,6 +499,7 @@ onUserDeleted origDomain udcn = do removeUser (qualifyAs lc conv) (tUntagged deletedUser) void $ notifyConversationAction + False (sing @'ConversationLeaveTag) untaggedDeletedUser False diff --git a/services/galley/src/Galley/API/Teams.hs b/services/galley/src/Galley/API/Teams.hs index 393a49f45b..45c608c029 100644 --- a/services/galley/src/Galley/API/Teams.hs +++ b/services/galley/src/Galley/API/Teams.hs @@ -150,6 +150,7 @@ import Wire.API.User.Identity (UserSSOId (UserSSOId)) import Wire.API.User.RichInfo (RichInfo) import qualified Wire.Sem.Paging as E import Wire.Sem.Paging.Cassandra +import System.Logger (Msg) getTeamH :: forall r. @@ -1098,7 +1099,8 @@ deleteTeamConversation :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, - Member TeamStore r + Member TeamStore r, + Member (P.Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> diff --git a/services/galley/src/Galley/API/Update.hs b/services/galley/src/Galley/API/Update.hs index 8243d941c8..dce35ae3b1 100644 --- a/services/galley/src/Galley/API/Update.hs +++ b/services/galley/src/Galley/API/Update.hs @@ -136,6 +136,7 @@ import Wire.API.ServantProto (RawProto (..)) import Wire.API.Team.Feature hiding (setStatus) import Wire.API.Team.Member import Wire.API.User.Client +import System.Logger (Msg) acceptConvH :: ( Member ConversationStore r, @@ -401,7 +402,8 @@ updateConversationMessageTimer :: Member ExternalAccess r, Member FederatorAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -433,7 +435,8 @@ updateConversationMessageTimerUnqualified :: Member ExternalAccess r, Member FederatorAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -454,7 +457,8 @@ deleteLocalConversation :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, - Member TeamStore r + Member TeamStore r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -653,6 +657,7 @@ joinConversationByReusableCode :: Member MemberStore r, Member TeamStore r, Member (TeamFeatureStore db) r, + Member (Logger (Msg -> Msg)) r, FeaturePersistentConstraint db GuestLinksConfig ) => Local UserId -> @@ -680,7 +685,8 @@ joinConversationById :: Member (Input Opts) r, Member (Input UTCTime) r, Member MemberStore r, - Member TeamStore r + Member TeamStore r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -703,7 +709,8 @@ joinConversation :: Member (Input Opts) r, Member (Input UTCTime) r, Member MemberStore r, - Member TeamStore r + Member TeamStore r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -725,6 +732,7 @@ joinConversation lusr zcon conv access = do addMembersToLocalConversation lcnv (UserList users []) roleNameWireMember lcuEvent <$> notifyConversationAction + False (sing @'ConversationJoinTag) (tUntagged lusr) False @@ -917,7 +925,8 @@ updateOtherMemberLocalConv :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, - Member MemberStore r + Member MemberStore r, + Member (Logger (Msg -> Msg)) r ) => Local ConvId -> Local UserId -> @@ -942,7 +951,8 @@ updateOtherMemberUnqualified :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, - Member MemberStore r + Member MemberStore r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -967,7 +977,8 @@ updateOtherMember :: Member FederatorAccess r, Member GundeckAccess r, Member (Input UTCTime) r, - Member MemberStore r + Member MemberStore r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -1276,7 +1287,8 @@ updateConversationName :: Member ExternalAccess r, Member FederatorAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -1300,7 +1312,8 @@ updateUnqualifiedConversationName :: Member ExternalAccess r, Member FederatorAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> @@ -1320,7 +1333,8 @@ updateLocalConversationName :: Member ExternalAccess r, Member FederatorAccess r, Member GundeckAccess r, - Member (Input UTCTime) r + Member (Input UTCTime) r, + Member (Logger (Msg -> Msg)) r ) => Local UserId -> ConnId -> From b1457ec6f348a4d0c739f809d08414ceda6f1fc8 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 7 Mar 2023 18:12:36 +1000 Subject: [PATCH 2/5] FS-1530 Adding tests for deleting conversations and removing members --- services/galley/src/Galley/API/Action.hs | 6 +- services/galley/test/integration/API.hs | 105 +++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/services/galley/src/Galley/API/Action.hs b/services/galley/src/Galley/API/Action.hs index b42d9818f2..c9ce5de56c 100644 --- a/services/galley/src/Galley/API/Action.hs +++ b/services/galley/src/Galley/API/Action.hs @@ -631,7 +631,11 @@ updateLocalConversationUnchecked lconv qusr con action = do (extraTargets, action') <- performAction tag qusr lconv action notifyConversationAction - True + -- Removing members should be fault tolerant. + (case tag of + SConversationRemoveMembersTag -> False + _ -> True + ) (sing @tag) qusr False diff --git a/services/galley/test/integration/API.hs b/services/galley/test/integration/API.hs index 9f28461430..f54fcea71e 100644 --- a/services/galley/test/integration/API.hs +++ b/services/galley/test/integration/API.hs @@ -171,6 +171,7 @@ tests s = test s "fail to add too many members" postTooManyMembersFail, test s "add remote members" testAddRemoteMember, test s "delete conversation with remote members" testDeleteTeamConversationWithRemoteMembers, + test s "delete conversation with unavailable remote members" testDeleteTeamConversationWithUnavailableRemoteMembers, test s "get conversations/:domain/:cnv - local" testGetQualifiedLocalConv, test s "get conversations/:domain/:cnv - local, not found" testGetQualifiedLocalConvNotFound, test s "get conversations/:domain/:cnv - local, not participating" testGetQualifiedLocalConvNotParticipating, @@ -186,6 +187,7 @@ tests s = test s "delete conversations/:domain/:cnv/members/:domain/:usr - local conv with all locals" deleteMembersConvLocalQualifiedOk, test s "delete conversations/:domain/:cnv/members/:domain/:usr - local conv with locals and remote, delete local" deleteLocalMemberConvLocalQualifiedOk, test s "delete conversations/:domain/:cnv/members/:domain/:usr - local conv with locals and remote, delete remote" deleteRemoteMemberConvLocalQualifiedOk, + test s "delete conversations/:domain/:cnv/members/:domain/:usr - local conv with locals and remote, delete unavailable remote" deleteUnavailableRemoteMemberConvLocalQualifiedOk, test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, leave conv" leaveRemoteConvQualifiedOk, test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, leave conv, non-existent" leaveNonExistentRemoteConv, test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, leave conv, denied" leaveRemoteConvDenied, @@ -2468,6 +2470,40 @@ testDeleteTeamConversationWithRemoteMembers = do cuAlreadyPresentUsers convUpdate @?= [bobId] cuOrigUserId convUpdate @?= qalice +testDeleteTeamConversationWithUnavailableRemoteMembers :: TestM () +testDeleteTeamConversationWithUnavailableRemoteMembers = do + (alice, tid) <- createBindingTeam + localDomain <- viewFederationDomain + let qalice = Qualified alice localDomain + + bobId <- randomId + let remoteDomain = Domain "far-away.example.com" + remoteBob = Qualified bobId remoteDomain + + convId <- decodeConvId <$> postTeamConv tid alice [] (Just "remote gossip") [] Nothing Nothing + + connectWithRemoteUser alice remoteBob + + let mock = + ("on-new-remote-conversation" ~> EmptyResponse) + -- Mock an unavailable federation server for the deletion call + <|> (guardRPC "on-conversation-updated" *> throw (MockErrorResponse HTTP.status503 "Down for maintenance.")) + <|> (guardRPC "delete-team-conversation" *> throw (MockErrorResponse HTTP.status503 "Down for maintenance.")) + (_, received) <- withTempMockFederator' mock $ do + postQualifiedMembers alice (remoteBob :| []) convId + !!! const 503 === statusCode + + deleteTeamConv tid convId alice + !!! const 503 === statusCode + liftIO $ do + let convUpdates = mapMaybe (eitherToMaybe . parseFedRequest) received + convUpdate <- case filter ((== SomeConversationAction (sing @'ConversationDeleteTag) ()) . cuAction) convUpdates of + [] -> assertFailure "No ConversationUpdate requests received" + [convDelete] -> pure convDelete + _ -> assertFailure "Multiple ConversationUpdate requests received" + cuAlreadyPresentUsers convUpdate @?= [bobId] + cuOrigUserId convUpdate @?= qalice + testGetQualifiedLocalConv :: TestM () testGetQualifiedLocalConv = do alice <- randomUser @@ -2975,6 +3011,75 @@ deleteRemoteMemberConvLocalQualifiedOk = do const 204 === statusCode const Nothing === responseBody + + +-- Creates a conversation with five users. Alice and Bob are on the local +-- domain. Chad and Dee are on far-away-1.example.com. Eve is on +-- far-away-2.example.com. It uses a qualified endpoint to remove Chad from the +-- conversation. The federator for far-away-2.example.com isn't availabe: +-- +-- DELETE /conversations/:domain/:cnv/members/:domain/:usr +deleteUnavailableRemoteMemberConvLocalQualifiedOk :: TestM () +deleteUnavailableRemoteMemberConvLocalQualifiedOk = do + localDomain <- viewFederationDomain + [alice, bob] <- randomUsers 2 + let [qAlice, qBob] = (`Qualified` localDomain) <$> [alice, bob] + remoteDomain1 = Domain "far-away-1.example.com" + remoteDomain2 = Domain "far-away-2.example.com" + qChad <- (`Qualified` remoteDomain1) <$> randomId + qDee <- (`Qualified` remoteDomain1) <$> randomId + qEve <- (`Qualified` remoteDomain2) <$> randomId + connectUsers alice (singleton bob) + mapM_ (connectWithRemoteUser alice) [qChad, qDee, qEve] + + let mockedGetUsers = do + guardRPC "get-users-by-ids" + d <- frTargetDomain <$> getRequest + asum + [ guard (d == remoteDomain1) + *> mockReply [mkProfile qChad (Name "Chad"), mkProfile qDee (Name "Dee")], + guard (d == remoteDomain2) + *> throw (MockErrorResponse HTTP.status503 "Down for maintenance.") + ] + mockedOther = do + d <- frTargetDomain <$> getRequest + asum + [ guard (d == remoteDomain1) + *> mockReply (), + guard (d == remoteDomain2) *> asum + [ guardRPC "on-conversation-created" *> mockReply () + , throw $ MockErrorResponse HTTP.status503 "Down for maintenance." + ] + ] + (convId, _) <- + withTempMockFederator' (mockedGetUsers <|> mockedOther) $ + fmap decodeConvId $ + postConvQualified + alice + Nothing + defNewProteusConv {newConvQualifiedUsers = [qBob, qChad, qDee, qEve]} + mockedOther) $ + deleteMemberQualified alice qChad qconvId + liftIO $ do + statusCode respDel @?= 200 + case responseJsonEither respDel of + Left err -> assertFailure err + Right e -> assertLeaveEvent qconvId qAlice [qChad] e + + let [remote1GalleyFederatedRequest] = fedRequestsForDomain remoteDomain1 Galley federatedRequests + [remote2GalleyFederatedRequest] = fedRequestsForDomain remoteDomain2 Galley federatedRequests + assertRemoveUpdate remote1GalleyFederatedRequest qconvId qAlice [qUnqualified qChad, qUnqualified qDee] qChad + assertRemoveUpdate remote2GalleyFederatedRequest qconvId qAlice [qUnqualified qEve] qChad + + -- Now that Chad is gone, try removing him once again + deleteMemberQualified alice qChad qconvId !!! do + const 204 === statusCode + const Nothing === responseBody + -- Alice, a local user, leaves a remote conversation. Bob's domain is the same -- as that of the conversation. The test uses the following endpoint: -- From 35c79cc3eb3e8d33e0e37ffe916ab938d8e63c59 Mon Sep 17 00:00:00 2001 From: Owen Harvey Date: Tue, 7 Mar 2023 18:29:07 +1000 Subject: [PATCH 3/5] FS-1530 Formatting and hlint --- services/galley/src/Galley/API/Action.hs | 45 +++++++++++++----------- services/galley/src/Galley/API/Teams.hs | 2 +- services/galley/src/Galley/API/Update.hs | 2 +- services/galley/test/integration/API.hs | 13 ++++--- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/services/galley/src/Galley/API/Action.hs b/services/galley/src/Galley/API/Action.hs index c9ce5de56c..38b0541099 100644 --- a/services/galley/src/Galley/API/Action.hs +++ b/services/galley/src/Galley/API/Action.hs @@ -628,13 +628,13 @@ updateLocalConversationUnchecked lconv qusr con action = do ensureConversationActionAllowed (sing @tag) lcnv action conv self -- perform action - (extraTargets, action') <- performAction tag qusr lconv action + (extraTargets, action') <- performAction tag qusr lconv action notifyConversationAction -- Removing members should be fault tolerant. - (case tag of - SConversationRemoveMembersTag -> False - _ -> True + ( case tag of + SConversationRemoveMembersTag -> False + _ -> True ) (sing @tag) qusr @@ -746,24 +746,26 @@ notifyConversationAction failEarly tag quid notifyOrigDomain con lconv targets a errorTolerant = do fedEithers <- E.runFederatedConcurrentlyEither (toList newDomains) $ \_ -> do void $ fedClient @'Galley @"on-new-remote-conversation" nrc - for_ fedEithers $ either - (logError "on-new-remote-conversation" "An error occurred while communicating with federated server: ") - (pure . tUnqualified) + for_ fedEithers $ + either + (logError "on-new-remote-conversation" "An error occurred while communicating with federated server: ") + (pure . tUnqualified) updates <- - E.runFederatedConcurrentlyEither (toList (bmRemotes targets)) - $ \ruids -> do - let update = mkUpdate (tUnqualified ruids) - -- if notifyOrigDomain is false, filter out user from quid's domain, - -- because quid's backend will update local state and notify its users - -- itself using the ConversationUpdate returned by this function - if notifyOrigDomain || tDomain ruids /= qDomain quid - then fedClient @'Galley @"on-conversation-updated" update $> Nothing - else pure (Just update) + E.runFederatedConcurrentlyEither (toList (bmRemotes targets)) $ + \ruids -> do + let update = mkUpdate (tUnqualified ruids) + -- if notifyOrigDomain is false, filter out user from quid's domain, + -- because quid's backend will update local state and notify its users + -- itself using the ConversationUpdate returned by this function + if notifyOrigDomain || tDomain ruids /= qDomain quid + then fedClient @'Galley @"on-conversation-updated" update $> Nothing + else pure (Just update) let f = fromMaybe (mkUpdate []) . asum . map tUnqualified . rights update = f updates - for_ (lefts updates) $ logError - "on-conversation-update" - "An error occurred while communicating with federated server: " + for_ (lefts updates) $ + logError + "on-conversation-update" + "An error occurred while communicating with federated server: " pure update update <- if failEarly then errorIntolerant else errorTolerant @@ -776,8 +778,9 @@ notifyConversationAction failEarly tag quid notifyOrigDomain con lconv targets a pure $ LocalConversationUpdate e update where logError :: Show a => String -> String -> (a, FederationError) -> Sem r () - logError field msg e = P.warn $ - Log.field "federation call" field . Log.msg (msg <> show e) + logError field msg e = + P.warn $ + Log.field "federation call" field . Log.msg (msg <> show e) -- | Notify all local members about a remote conversation update that originated -- from a local user diff --git a/services/galley/src/Galley/API/Teams.hs b/services/galley/src/Galley/API/Teams.hs index 45c608c029..1c8a93461c 100644 --- a/services/galley/src/Galley/API/Teams.hs +++ b/services/galley/src/Galley/API/Teams.hs @@ -120,6 +120,7 @@ import Polysemy.Input import Polysemy.Output import qualified Polysemy.TinyLog as P import qualified SAML2.WebSSO as SAML +import System.Logger (Msg) import qualified System.Logger.Class as Log import Wire.API.Conversation.Role (Action (DeleteConversation), wireConvRoles) import qualified Wire.API.Conversation.Role as Public @@ -150,7 +151,6 @@ import Wire.API.User.Identity (UserSSOId (UserSSOId)) import Wire.API.User.RichInfo (RichInfo) import qualified Wire.Sem.Paging as E import Wire.Sem.Paging.Cassandra -import System.Logger (Msg) getTeamH :: forall r. diff --git a/services/galley/src/Galley/API/Update.hs b/services/galley/src/Galley/API/Update.hs index c8ccbc3cf0..217b213a8b 100644 --- a/services/galley/src/Galley/API/Update.hs +++ b/services/galley/src/Galley/API/Update.hs @@ -118,6 +118,7 @@ import Polysemy import Polysemy.Error import Polysemy.Input import Polysemy.TinyLog +import System.Logger (Msg) import Wire.API.Conversation hiding (Member) import Wire.API.Conversation.Action import Wire.API.Conversation.Code @@ -137,7 +138,6 @@ import Wire.API.ServantProto (RawProto (..)) import Wire.API.Team.Feature hiding (setStatus) import Wire.API.Team.Member import Wire.API.User.Client -import System.Logger (Msg) acceptConvH :: ( Member ConversationStore r, diff --git a/services/galley/test/integration/API.hs b/services/galley/test/integration/API.hs index f54fcea71e..95dc99fb0b 100644 --- a/services/galley/test/integration/API.hs +++ b/services/galley/test/integration/API.hs @@ -2486,7 +2486,7 @@ testDeleteTeamConversationWithUnavailableRemoteMembers = do let mock = ("on-new-remote-conversation" ~> EmptyResponse) - -- Mock an unavailable federation server for the deletion call + -- Mock an unavailable federation server for the deletion call <|> (guardRPC "on-conversation-updated" *> throw (MockErrorResponse HTTP.status503 "Down for maintenance.")) <|> (guardRPC "delete-team-conversation" *> throw (MockErrorResponse HTTP.status503 "Down for maintenance.")) (_, received) <- withTempMockFederator' mock $ do @@ -3011,8 +3011,6 @@ deleteRemoteMemberConvLocalQualifiedOk = do const 204 === statusCode const Nothing === responseBody - - -- Creates a conversation with five users. Alice and Bob are on the local -- domain. Chad and Dee are on far-away-1.example.com. Eve is on -- far-away-2.example.com. It uses a qualified endpoint to remove Chad from the @@ -3046,10 +3044,11 @@ deleteUnavailableRemoteMemberConvLocalQualifiedOk = do asum [ guard (d == remoteDomain1) *> mockReply (), - guard (d == remoteDomain2) *> asum - [ guardRPC "on-conversation-created" *> mockReply () - , throw $ MockErrorResponse HTTP.status503 "Down for maintenance." - ] + guard (d == remoteDomain2) + *> asum + [ guardRPC "on-conversation-created" *> mockReply (), + throw $ MockErrorResponse HTTP.status503 "Down for maintenance." + ] ] (convId, _) <- withTempMockFederator' (mockedGetUsers <|> mockedOther) $ From 3d213c0e76931ffe179eeb53a80496aba9cec65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Dimja=C5=A1evi=C4=87?= Date: Wed, 8 Mar 2023 14:38:36 +0100 Subject: [PATCH 4/5] Hi CI From 9849bfc16ac15978caf13535ee16a3a23306a731 Mon Sep 17 00:00:00 2001 From: Igor Ranieri Date: Mon, 13 Mar 2023 16:20:36 +0000 Subject: [PATCH 5/5] HI CI