Skip to content

Commit e742a41

Browse files
pcapriottismattingjschaulakshaymankar
authored
Federation: Allow connecting to remote users (#1824)
One2One conversations are not created yet. This will be worked upon separately. Legal-hold restrictions are also not dealt with as for now, it will not be allowed to turn on legal-hold and federation at the same point. Co-authored-by: Stefan Matting <[email protected]> Co-authored-by: jschaul <[email protected]> Co-authored-by: Akshay Mankar <[email protected]>
1 parent fa25b09 commit e742a41

36 files changed

+958
-130
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow connecting to remote users. One to one conversations are not created yet.

libs/wire-api-federation/src/Wire/API/Federation/API/Brig.hs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ module Wire.API.Federation.API.Brig where
2020
import Control.Monad.Except (MonadError (..))
2121
import Data.Aeson (FromJSON, ToJSON)
2222
import Data.Handle (Handle)
23-
import Data.Id (ClientId, UserId)
23+
import Data.Id
2424
import Imports
2525
import Servant.API
2626
import Servant.API.Generic
2727
import Servant.Client.Generic (AsClientT, genericClient)
2828
import Test.QuickCheck (Arbitrary)
2929
import Wire.API.Arbitrary (GenericUniform (..))
3030
import Wire.API.Federation.Client (FederationClientFailure, FederatorClient)
31+
import Wire.API.Federation.Domain (OriginDomainHeader)
3132
import qualified Wire.API.Federation.GRPC.Types as Proto
3233
import Wire.API.Message (UserClients)
3334
import Wire.API.User (UserProfile)
@@ -92,7 +93,14 @@ data Api routes = Api
9293
:- "federation"
9394
:> "get-user-clients"
9495
:> ReqBody '[JSON] GetUserClients
95-
:> Post '[JSON] (UserMap (Set PubClient))
96+
:> Post '[JSON] (UserMap (Set PubClient)),
97+
sendConnectionAction ::
98+
routes
99+
:- "federation"
100+
:> "send-connection-action"
101+
:> OriginDomainHeader
102+
:> ReqBody '[JSON] NewConnectionRequest
103+
:> Post '[JSON] NewConnectionResponse
96104
}
97105
deriving (Generic)
98106

@@ -102,5 +110,46 @@ newtype GetUserClients = GetUserClients
102110
deriving stock (Eq, Show, Generic)
103111
deriving (ToJSON, FromJSON) via (CustomEncoded GetUserClients)
104112

113+
-- NOTE: ConversationId for remote connections
114+
--
115+
-- The plan is to model the connect/one2one conversationId as deterministically derived from
116+
-- the combination of both userIds and both domains. It may be in the domain
117+
-- of the sending OR the receiving backend (with a 50/50 probability).
118+
-- However at the level of the federation API, we are only concerned about
119+
-- the question of which backend has the authority over the conversationId.
120+
--
121+
-- (Backend A should not prescribe backend B to use a certain UUID for its
122+
-- conversation; as that could lead to a potential malicious override of an
123+
-- existing conversation)
124+
--
125+
-- The deterministic conversation Id should be seen as a 'best effort'
126+
-- attempt only. (we cannot guarantee a backend won't change the code in the
127+
-- future)
128+
129+
data NewConnectionRequest = NewConnectionRequest
130+
{ -- | The 'from' userId is understood to always have the domain of the backend making the connection request
131+
ncrFrom :: UserId,
132+
-- | The 'to' userId is understood to always have the domain of the receiving backend.
133+
ncrTo :: UserId,
134+
ncrAction :: RemoteConnectionAction
135+
}
136+
deriving stock (Eq, Show, Generic)
137+
deriving (Arbitrary) via (GenericUniform NewConnectionRequest)
138+
deriving (FromJSON, ToJSON) via (CustomEncoded NewConnectionRequest)
139+
140+
data RemoteConnectionAction
141+
= RemoteConnect
142+
| RemoteRescind
143+
deriving stock (Eq, Show, Generic)
144+
deriving (Arbitrary) via (GenericUniform RemoteConnectionAction)
145+
deriving (FromJSON, ToJSON) via (CustomEncoded RemoteConnectionAction)
146+
147+
data NewConnectionResponse
148+
= NewConnectionResponseUserNotActivated
149+
| NewConnectionResponseOk (Maybe RemoteConnectionAction)
150+
deriving stock (Eq, Show, Generic)
151+
deriving (Arbitrary) via (GenericUniform NewConnectionResponse)
152+
deriving (FromJSON, ToJSON) via (CustomEncoded NewConnectionResponse)
153+
105154
clientRoutes :: (MonadError FederationClientFailure m, MonadIO m) => Api (AsClientT (FederatorClient 'Proto.Brig m))
106155
clientRoutes = genericClient

libs/wire-api-federation/test/Test/Wire/API/Federation/Golden/GoldenSpec.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import qualified Test.Wire.API.Federation.Golden.ConversationUpdate as Conversat
2323
import qualified Test.Wire.API.Federation.Golden.LeaveConversationRequest as LeaveConversationRequest
2424
import qualified Test.Wire.API.Federation.Golden.LeaveConversationResponse as LeaveConversationResponse
2525
import qualified Test.Wire.API.Federation.Golden.MessageSendResponse as MessageSendResponse
26+
import qualified Test.Wire.API.Federation.Golden.NewConnectionRequest as NewConnectionRequest
27+
import qualified Test.Wire.API.Federation.Golden.NewConnectionResponse as NewConnectionResponse
2628
import Test.Wire.API.Federation.Golden.Runner (testObjects)
2729

2830
spec :: Spec
@@ -50,3 +52,13 @@ spec =
5052
(LeaveConversationResponse.testObject_LeaveConversationResponse7, "testObject_LeaveConversationResponse7.json"),
5153
(LeaveConversationResponse.testObject_LeaveConversationResponse8, "testObject_LeaveConversationResponse8.json")
5254
]
55+
testObjects
56+
[ (NewConnectionRequest.testObject_NewConnectionRequest1, "testObject_NewConnectionRequest1.json"),
57+
(NewConnectionRequest.testObject_NewConnectionRequest2, "testObject_NewConnectionRequest2.json")
58+
]
59+
testObjects
60+
[ (NewConnectionResponse.testObject_NewConnectionResponse1, "testObject_NewConnectionResponse1.json"),
61+
(NewConnectionResponse.testObject_NewConnectionResponse2, "testObject_NewConnectionResponse2.json"),
62+
(NewConnectionResponse.testObject_NewConnectionResponse3, "testObject_NewConnectionResponse3.json"),
63+
(NewConnectionResponse.testObject_NewConnectionResponse4, "testObject_NewConnectionResponse4.json")
64+
]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
-- This file is part of the Wire Server implementation.
2+
--
3+
-- Copyright (C) 2021 Wire Swiss GmbH <[email protected]>
4+
--
5+
-- This program is free software: you can redistribute it and/or modify it under
6+
-- the terms of the GNU Affero General Public License as published by the Free
7+
-- Software Foundation, either version 3 of the License, or (at your option) any
8+
-- later version.
9+
--
10+
-- This program is distributed in the hope that it will be useful, but WITHOUT
11+
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12+
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13+
-- details.
14+
--
15+
-- You should have received a copy of the GNU Affero General Public License along
16+
-- with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
module Test.Wire.API.Federation.Golden.NewConnectionRequest where
19+
20+
import Data.Id
21+
import qualified Data.UUID as UUID
22+
import Imports
23+
import Wire.API.Federation.API.Brig
24+
25+
testObject_NewConnectionRequest1 :: NewConnectionRequest
26+
testObject_NewConnectionRequest1 =
27+
NewConnectionRequest
28+
{ ncrFrom = Id (fromJust (UUID.fromString "69f66843-6cf1-48fb-8c05-1cf58c23566a")),
29+
ncrTo = Id (fromJust (UUID.fromString "1669240c-c510-43e0-bf1a-33378fa4ba55")),
30+
ncrAction = RemoteConnect
31+
}
32+
33+
testObject_NewConnectionRequest2 :: NewConnectionRequest
34+
testObject_NewConnectionRequest2 =
35+
NewConnectionRequest
36+
{ ncrFrom = Id (fromJust (UUID.fromString "69f66843-6cf1-48fb-8c05-1cf58c23566a")),
37+
ncrTo = Id (fromJust (UUID.fromString "1669240c-c510-43e0-bf1a-33378fa4ba55")),
38+
ncrAction = RemoteRescind
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-- This file is part of the Wire Server implementation.
2+
--
3+
-- Copyright (C) 2021 Wire Swiss GmbH <[email protected]>
4+
--
5+
-- This program is free software: you can redistribute it and/or modify it under
6+
-- the terms of the GNU Affero General Public License as published by the Free
7+
-- Software Foundation, either version 3 of the License, or (at your option) any
8+
-- later version.
9+
--
10+
-- This program is distributed in the hope that it will be useful, but WITHOUT
11+
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12+
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13+
-- details.
14+
--
15+
-- You should have received a copy of the GNU Affero General Public License along
16+
-- with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
module Test.Wire.API.Federation.Golden.NewConnectionResponse where
19+
20+
import Imports
21+
import Wire.API.Federation.API.Brig
22+
23+
testObject_NewConnectionResponse1 :: NewConnectionResponse
24+
testObject_NewConnectionResponse1 = NewConnectionResponseOk Nothing
25+
26+
testObject_NewConnectionResponse2 :: NewConnectionResponse
27+
testObject_NewConnectionResponse2 = NewConnectionResponseOk (Just RemoteConnect)
28+
29+
testObject_NewConnectionResponse3 :: NewConnectionResponse
30+
testObject_NewConnectionResponse3 = NewConnectionResponseOk (Just RemoteRescind)
31+
32+
testObject_NewConnectionResponse4 :: NewConnectionResponse
33+
testObject_NewConnectionResponse4 = NewConnectionResponseUserNotActivated
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"to": "1669240c-c510-43e0-bf1a-33378fa4ba55",
3+
"from": "69f66843-6cf1-48fb-8c05-1cf58c23566a",
4+
"action": "RemoteConnect"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"to": "1669240c-c510-43e0-bf1a-33378fa4ba55",
3+
"from": "69f66843-6cf1-48fb-8c05-1cf58c23566a",
4+
"action": "RemoteRescind"
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"tag": "NewConnectionResponseOk",
3+
"contents": null
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"tag": "NewConnectionResponseOk",
3+
"contents": "RemoteConnect"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"tag": "NewConnectionResponseOk",
3+
"contents": "RemoteRescind"
4+
}

0 commit comments

Comments
 (0)