Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FS-1148] Resilient member adding in presence of unreachable backends (1/2) #3248

Merged
merged 39 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
643aa52
Rename UnrechableUsers to UnreachableUserList
mdimjasevic Mar 28, 2023
4fd8363
Remove duplicated and commented out code
mdimjasevic Mar 28, 2023
9bde09b
Refactoring of wire-api for UnreachableUserList
mdimjasevic Apr 3, 2023
5fe2710
Refactoring: use FailedToProcess
mdimjasevic Apr 3, 2023
7763bfc
Refactoring: make UnreachableUserList a NonEmpty
mdimjasevic Apr 4, 2023
607f277
executeProposalAction: return failed-to-add users
mdimjasevic Apr 4, 2023
6b93a82
Rename back to UnreachableUsers
mdimjasevic Apr 7, 2023
4caf699
Do not expose the getter for UnreachableUsers
mdimjasevic Apr 7, 2023
1855e44
MLS test utility: reuse code among utilities
mdimjasevic Apr 7, 2023
d098b94
Move and generalise mockUnreachableFor
mdimjasevic Apr 7, 2023
76c1e89
Introduce failed to remove (via failed to fetch client info)
mdimjasevic Apr 13, 2023
3536b20
Test WIP
mdimjasevic Apr 13, 2023
fd4134c
Propagate FailedToProcess across federation API arising from conversa…
mdimjasevic Apr 14, 2023
dccf15b
Simplify the definition of the (<\>) operator
mdimjasevic Apr 17, 2023
24d72b4
WIP: Debugging
mdimjasevic Apr 19, 2023
59d212a
The first version that kind of works
mdimjasevic Apr 21, 2023
97fdcda
fixup! WIP: Debugging
mdimjasevic Apr 21, 2023
694d8aa
Fix/align an MLS integration test
mdimjasevic Apr 24, 2023
f20b536
Use a V4 add members endpoint in tests
mdimjasevic Apr 24, 2023
a42246d
Rethrow the invalid-domain exception
mdimjasevic Apr 26, 2023
9bcf433
Rethrow federation-not-available error
mdimjasevic Apr 26, 2023
d51f660
Fix a golden test for LeaveConversationResponse
mdimjasevic Apr 26, 2023
f0b3fe5
Golden tests for MLSMessageSendingStatus
mdimjasevic Apr 26, 2023
d5529f8
Merge remote-tracking branch 'origin/develop' into fs-1148/mls-create…
mdimjasevic Apr 26, 2023
9fbff8a
Fix a test with an unreachable user
mdimjasevic Apr 27, 2023
0a99e47
Test: clean up debugging leftovers
mdimjasevic Apr 27, 2023
fa0be89
fixup! Test: clean up debugging leftovers
mdimjasevic Apr 27, 2023
6ed1368
Test utility: fix wording of a haddoc
mdimjasevic Apr 27, 2023
1a7eeb5
Clean up conv action federation failure handling
mdimjasevic Apr 27, 2023
ca60406
Merge remote-tracking branch 'origin/develop' into fs-1148/mls-create…
mdimjasevic Apr 27, 2023
23452df
Add changelogs
mdimjasevic Apr 27, 2023
13bc11c
Linting
mdimjasevic Apr 27, 2023
2d2beb6
Remove a hand-rolled Semigroup Maybe instance
mdimjasevic May 4, 2023
0c260b7
Move unreachability stuff into its own module
mdimjasevic May 4, 2023
9b146aa
Change the export list of the Unreachable module
mdimjasevic May 4, 2023
f618a80
Run a fed error instead of mapping it
mdimjasevic May 4, 2023
fc010ea
Simplify computation for failed-to-add
mdimjasevic May 5, 2023
626bf05
fixup! Simplify computation for failed-to-add
mdimjasevic May 5, 2023
ad8324c
Merge remote-tracking branch 'origin/develop' into fs-1148/mls-create…
mdimjasevic May 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1-api-changes/mls-conv-add-across-federation
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Report a failure to add remote users to an MLS conversation
1 change: 1 addition & 0 deletions changelog.d/6-federation/failed-to-process
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Several federation Galley endpoints have a breaking change in their response types: "leave-conversation", "update-conversation", "send-mls-message" and "send-mls-commit-bundle".
10 changes: 5 additions & 5 deletions libs/wire-api-federation/src/Wire/API/Federation/API/Galley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ import Wire.API.Conversation.Typing
import Wire.API.Error.Galley
import Wire.API.Federation.API.Common
import Wire.API.Federation.Endpoint
import Wire.API.MLS.Message
import Wire.API.MLS.SubConversation
import Wire.API.MakesFederatedCall
import Wire.API.Message
import Wire.API.Routes.Public.Galley.Messaging
import Wire.API.Unreachable
import Wire.API.Util.Aeson (CustomEncoded (..))
import Wire.Arbitrary (Arbitrary, GenericUniform (..))

Expand Down Expand Up @@ -365,11 +365,11 @@ newtype MessageSendResponse = MessageSendResponse
)

newtype LeaveConversationResponse = LeaveConversationResponse
{leaveResponse :: Either RemoveFromConversationError ()}
{leaveResponse :: Either RemoveFromConversationError FailedToProcess}
deriving stock (Eq, Show)
deriving
(ToJSON, FromJSON)
via (Either (CustomEncoded RemoveFromConversationError) ())
via (Either (CustomEncoded RemoveFromConversationError) FailedToProcess)

type UserDeletedNotificationMaxConvs = 1000

Expand Down Expand Up @@ -398,7 +398,7 @@ data ConversationUpdateRequest = ConversationUpdateRequest

data ConversationUpdateResponse
= ConversationUpdateResponseError GalleyError
| ConversationUpdateResponseUpdate ConversationUpdate
| ConversationUpdateResponseUpdate (ConversationUpdate, FailedToProcess)
| ConversationUpdateResponseNoChanges
deriving stock (Eq, Show, Generic)
deriving
Expand All @@ -423,7 +423,7 @@ data MLSMessageResponse
= MLSMessageResponseError GalleyError
| MLSMessageResponseProtocolError Text
| MLSMessageResponseProposalFailure Wai.Error
| MLSMessageResponseUpdates [ConversationUpdate] UnreachableUsers
| MLSMessageResponseUpdates [ConversationUpdate] FailedToProcess
deriving stock (Eq, Show, Generic)
deriving (ToJSON, FromJSON) via (CustomEncoded MLSMessageResponse)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ spec =
testObjects
[ (MLSMessageSendingStatus.testObject_MLSMessageSendingStatus1, "testObject_MLSMessageSendingStatus1.json"),
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus2, "testObject_MLSMessageSendingStatus2.json"),
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus3, "testObject_MLSMessageSendingStatus3.json")
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus3, "testObject_MLSMessageSendingStatus3.json"),
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus4, "testObject_MLSMessageSendingStatus4.json"),
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus5, "testObject_MLSMessageSendingStatus5.json"),
(MLSMessageSendingStatus.testObject_MLSMessageSendingStatus6, "testObject_MLSMessageSendingStatus6.json")
]
testObjects [(LeaveConversationRequest.testObject_LeaveConversationRequest1, "testObject_LeaveConversationRequest1.json")]
testObjects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Imports
import Wire.API.Federation.API.Galley

testObject_LeaveConversationResponse1 :: LeaveConversationResponse
testObject_LeaveConversationResponse1 = LeaveConversationResponse $ Right ()
testObject_LeaveConversationResponse1 = LeaveConversationResponse $ Right mempty

testObject_LeaveConversationResponse2 :: LeaveConversationResponse
testObject_LeaveConversationResponse2 = LeaveConversationResponse $ Left RemoveFromConversationErrorRemovalNotAllowed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,65 @@ import Data.Qualified
import qualified Data.UUID as UUID
import Imports
import Wire.API.MLS.Message
import Wire.API.Unreachable

testObject_MLSMessageSendingStatus1 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus1 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "1864-04-12 12:22:43.673 UTC"),
mmssUnreachableUsers = UnreachableUsers []
mmssFailedToProcess = mempty
}

testObject_MLSMessageSendingStatus2 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus2 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "2001-04-12 12:22:43.673 UTC"),
mmssUnreachableUsers = failed1
mmssFailedToProcess = failedToSend failed1
}

testObject_MLSMessageSendingStatus3 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus3 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "1999-04-12 12:22:43.673 UTC"),
mmssUnreachableUsers = failed2
mmssFailedToProcess = failedToSend failed2
}

failed1 :: UnreachableUsers
testObject_MLSMessageSendingStatus4 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus4 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "2023-04-12 12:22:43.673 UTC"),
mmssFailedToProcess = failedToAdd failed1
}

testObject_MLSMessageSendingStatus5 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus5 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "1901-04-12 12:22:43.673 UTC"),
mmssFailedToProcess = failedToRemove failed2
}

testObject_MLSMessageSendingStatus6 :: MLSMessageSendingStatus
testObject_MLSMessageSendingStatus6 =
MLSMessageSendingStatus
{ mmssEvents = [],
mmssTime = toUTCTimeMillis (read "1905-04-12 12:22:43.673 UTC"),
mmssFailedToProcess = failedToAdd failed1 <> failedToRemove failed2
}

failed1 :: [Qualified UserId]
failed1 =
let domain = Domain "offline.example.com"
in UnreachableUsers [Qualified (Id . fromJust . UUID.fromString $ "00000000-0000-0000-0000-000200000008") domain]
in [Qualified (Id . fromJust . UUID.fromString $ "00000000-0000-0000-0000-000200000008") domain]

failed2 :: UnreachableUsers
failed2 :: [Qualified UserId]
failed2 =
let domain = Domain "golden.example.com"
in UnreachableUsers
[ Qualified (Id . fromJust . UUID.fromString $ "00000000-0000-0000-0000-000200000008") domain,
Qualified (Id . fromJust . UUID.fromString $ "00000000-0000-0000-0000-000100000007") domain
]
in flip Qualified domain . Id . fromJust . UUID.fromString
<$> [ "00000000-0000-0000-0000-000200000008",
"00000000-0000-0000-0000-000100000007"
]
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"Right": []
"Right": {}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"events": [],
"time": "1864-04-12T12:22:43.673Z",
"failed_to_send": []
}
"events": [],
"time": "1864-04-12T12:22:43.673Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"events": [],
"failed_to_add": [
{
"domain": "offline.example.com",
"id": "00000000-0000-0000-0000-000200000008"
}
],
"time": "2023-04-12T12:22:43.673Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"events": [],
"failed_to_remove": [
{
"domain": "golden.example.com",
"id": "00000000-0000-0000-0000-000200000008"
},
{
"domain": "golden.example.com",
"id": "00000000-0000-0000-0000-000100000007"
}
],
"time": "1901-04-12T12:22:43.673Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"events": [],
"failed_to_add": [
{
"domain": "offline.example.com",
"id": "00000000-0000-0000-0000-000200000008"
}
],
"failed_to_remove": [
{
"domain": "golden.example.com",
"id": "00000000-0000-0000-0000-000200000008"
},
{
"domain": "golden.example.com",
"id": "00000000-0000-0000-0000-000100000007"
}
],
"time": "1905-04-12T12:22:43.673Z"
}
24 changes: 3 additions & 21 deletions libs/wire-api/src/Wire/API/MLS/Message.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ module Wire.API.MLS.Message
MLSCipherTextSym0,
MLSMessageSendingStatus (..),
KnownFormatTag (..),
UnreachableUsers (..),
verifyMessageSignature,
mkSignedMessage,
)
Expand All @@ -50,10 +49,8 @@ import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.ByteArray as BA
import Data.Id
import Data.Json.Util
import Data.Kind
import Data.Qualified
import Data.Schema
import Data.Singletons.TH
import qualified Data.Swagger as S
Expand All @@ -67,6 +64,7 @@ import Wire.API.MLS.Group
import Wire.API.MLS.KeyPackage
import Wire.API.MLS.Proposal
import Wire.API.MLS.Serialisation
import Wire.API.Unreachable
import Wire.Arbitrary (GenericUniform (..))

data WireFormatTag = MLSPlainText | MLSCipherText
Expand Down Expand Up @@ -318,22 +316,10 @@ instance SerialiseMLS (MessagePayload 'MLSPlainText) where
-- so the next case is left as a stub
serialiseMLS _ = pure ()

newtype UnreachableUsers = UnreachableUsers {unreachableUsers :: [Qualified UserId]}
deriving stock (Eq, Show)
deriving (A.ToJSON, A.FromJSON, S.ToSchema) via Schema UnreachableUsers
deriving newtype (Semigroup, Monoid)

instance ToSchema UnreachableUsers where
schema =
named "UnreachableUsers" $
UnreachableUsers
<$> unreachableUsers
.= array schema

data MLSMessageSendingStatus = MLSMessageSendingStatus
{ mmssEvents :: [Event],
mmssTime :: UTCTimeMillis,
mmssUnreachableUsers :: UnreachableUsers
mmssFailedToProcess :: FailedToProcess
}
deriving (Eq, Show)
deriving (A.ToJSON, A.FromJSON, S.ToSchema) via Schema MLSMessageSendingStatus
Expand All @@ -352,11 +338,7 @@ instance ToSchema MLSMessageSendingStatus where
"time"
(description ?~ "The time of sending the message.")
schema
<*> mmssUnreachableUsers
.= fieldWithDocModifier
"failed_to_send"
(description ?~ "List of federated users who could not be reached and did not receive the message")
schema
<*> mmssFailedToProcess .= failedToProcessObjectSchema

verifyMessageSignature :: CipherSuiteTag -> Message 'MLSPlainText -> ByteString -> Bool
verifyMessageSignature cs msg pubkey =
Expand Down
Loading