Skip to content

Commit 3279146

Browse files
authored
Rename the two federation/on-user-deleted endpoints (#1883)
* Update Federation API conventions doc in prep for on-user-deleted * brig/galley: Rename the two federation/on-user-deleted endpoints This is to ensure that they do not overlap. This will hopefully make it easier to merge brig and galley. * Extract type level vars for UserDeleteNotificationMax{Conns,Convs}
1 parent e9d8d99 commit 3279146

File tree

13 files changed

+78
-60
lines changed

13 files changed

+78
-60
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
When a user gets deleted, notify remotes about conversations and connections in chunks of 1000
1+
When a user gets deleted, notify remotes about conversations and connections in chunks of 1000 (#1872, #1883)

docs/developer/federation-api-conventions.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@
33
# Federation API Conventions
44

55
- All endpoints must start with `/federation/`
6-
- All endpoints must have exactly one path segment after federation, so
7-
`/federation/foo` is valid `/fedeartion/foo/bar` is not. The path segments
8-
must be in kebab-case. The name of the field in this record must be the
9-
same name in camelCase.
6+
- All path segments must be in kebab-case. The name the field in the record must
7+
be the same name in camelCase.
8+
- There can be either one or two path segments after `/federation/`, so
9+
`/federation/foo` is valid, `/fedeartion/foo/bar` is valid, but
10+
`/federation/foo/bar/baz` is not.
1011
- All endpoints must be `POST`.
11-
- No query query params, all information that needs to go must go in body.
12+
- No query query params or captured path params, all information that needs to
13+
go must go in body.
1214
- All responses must be `200 OK`, domain specific failures (e.g. the
1315
conversation doesn't exist) must be indicated as a Sum type. Unhandled
1416
failures can be 5xx, an endpoint not being implemented will of course
1517
return 404. But we shouldn't pile onto these. This keeps the federator simple.
1618
- Accept only json, respond with only json. Maybe we can think of changing
1719
this in future. But as of now, the federator hardcodes application/json as
1820
the content type of the body.
19-
- Name of the last path segment must be either `<imperative-verb>-<object>` or
20-
`on-<subject>-<past-tense-verb>`, e.g. `get-conversations` or
21-
`on-conversation-created`.
21+
- Ensure that paths don't collide between brig and galley federation API, this
22+
will be very helpful when we merge brig and galley.
23+
- Name of the first path segment after `/federation/` must be either
24+
`<imperative-verb>-<object>` or `on-<subject>-<past-tense-verb>`, e.g.
25+
`get-conversations` or `on-conversation-created`.
2226

2327
How to decide which one to use:
2428
- If the request is supposed to ask for information/change from another
@@ -29,3 +33,9 @@
2933
this request has authority on, like a conversation got created, or a message
3034
is sent, then use the second format like `on-conversation-created` or
3135
`on-message-sent`
36+
- Path segment number 3 (so `/federation/not-this/but-this-one`), must only be
37+
used in exceptional circumstances, like when there needs to be the same path
38+
in brig and galley, e.g. `on-user-deleted`. In this case use the third segment
39+
to express the difference. For `on-user-deleted` we came up with
40+
`on-user-deleted/connections`for brig and `on-user-deleted/conversations` for
41+
galley.

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ data Api routes = Api
107107
routes
108108
:- "federation"
109109
:> "on-user-deleted"
110+
:> "connections"
110111
:> OriginDomainHeader
111-
:> ReqBody '[JSON] UserDeletedNotification
112+
:> ReqBody '[JSON] UserDeletedConnectionsNotification
112113
:> Post '[JSON] EmptyResponse
113114
}
114115
deriving (Generic)
@@ -160,15 +161,17 @@ data NewConnectionResponse
160161
deriving (Arbitrary) via (GenericUniform NewConnectionResponse)
161162
deriving (FromJSON, ToJSON) via (CustomEncoded NewConnectionResponse)
162163

163-
data UserDeletedNotification = UserDeletedNotification
164+
type UserDeletedNotificationMaxConnections = 1000
165+
166+
data UserDeletedConnectionsNotification = UserDeletedConnectionsNotification
164167
{ -- | This is qualified implicitly by the origin domain
165-
udnUser :: UserId,
168+
udcnUser :: UserId,
166169
-- | These are qualified implicitly by the target domain
167-
udnConnections :: Range 1 1000 [UserId]
170+
udcnConnections :: Range 1 UserDeletedNotificationMaxConnections [UserId]
168171
}
169172
deriving stock (Eq, Show, Generic)
170-
deriving (Arbitrary) via (GenericUniform UserDeletedNotification)
171-
deriving (FromJSON, ToJSON) via (CustomEncoded UserDeletedNotification)
173+
deriving (Arbitrary) via (GenericUniform UserDeletedConnectionsNotification)
174+
deriving (FromJSON, ToJSON) via (CustomEncoded UserDeletedConnectionsNotification)
172175

173176
clientRoutes :: (MonadError FederationClientFailure m, MonadIO m) => Api (AsClientT (FederatorClient 'Proto.Brig m))
174177
clientRoutes = genericClient

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ data Api routes = Api
109109
routes
110110
:- "federation"
111111
:> "on-user-deleted"
112+
:> "conversations"
112113
:> OriginDomainHeader
113-
:> ReqBody '[JSON] UserDeletedNotification
114+
:> ReqBody '[JSON] UserDeletedConversationsNotification
114115
:> Post '[JSON] EmptyResponse
115116
}
116117
deriving (Generic)
@@ -262,15 +263,17 @@ newtype LeaveConversationResponse = LeaveConversationResponse
262263
(ToJSON, FromJSON)
263264
via (Either (CustomEncoded RemoveFromConversationError) ())
264265

265-
data UserDeletedNotification = UserDeletedNotification
266+
type UserDeletedNotificationMaxConvs = 1000
267+
268+
data UserDeletedConversationsNotification = UserDeletedConversationsNotification
266269
{ -- | This is qualified implicitly by the origin domain
267-
udnUser :: UserId,
270+
udcnUser :: UserId,
268271
-- | These are qualified implicitly by the target domain
269-
udnConversations :: Range 1 1000 [ConvId]
272+
udcnConversations :: Range 1 UserDeletedNotificationMaxConvs [ConvId]
270273
}
271274
deriving stock (Eq, Show, Generic)
272-
deriving (Arbitrary) via (GenericUniform UserDeletedNotification)
273-
deriving (FromJSON, ToJSON) via (CustomEncoded UserDeletedNotification)
275+
deriving (Arbitrary) via (GenericUniform UserDeletedConversationsNotification)
276+
deriving (FromJSON, ToJSON) via (CustomEncoded UserDeletedConversationsNotification)
274277

275278
clientRoutes :: (MonadError FederationClientFailure m, MonadIO m) => Api (AsClientT (FederatorClient 'Proto.Galley m))
276279
clientRoutes = genericClient

services/brig/src/Brig/API/Federation.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ searchUsers (SearchRequest searchTerm) = do
123123
getUserClients :: GetUserClients -> Handler (UserMap (Set PubClient))
124124
getUserClients (GetUserClients uids) = API.lookupLocalPubClientsBulk uids !>> clientError
125125

126-
onUserDeleted :: Domain -> UserDeletedNotification -> Handler EmptyResponse
127-
onUserDeleted origDomain udn = lift $ do
128-
let deletedUser = toRemoteUnsafe origDomain (udnUser udn)
129-
connections = udnConnections udn
126+
onUserDeleted :: Domain -> UserDeletedConnectionsNotification -> Handler EmptyResponse
127+
onUserDeleted origDomain udcn = lift $ do
128+
let deletedUser = toRemoteUnsafe origDomain (udcnUser udcn)
129+
connections = udcnConnections udcn
130130
event = pure . UserEvent $ UserDeleted (qUntagged deletedUser)
131131
acceptedLocals <-
132132
map csv2From

services/brig/src/Brig/Federation/Client.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,5 @@ notifyUserDeleted self remotes = do
104104
let remoteConnections = tUnqualified remotes
105105
let fedRPC =
106106
FederatedBrig.onUserDeleted clientRoutes (tDomain self) $
107-
UserDeletedNotification (tUnqualified self) remoteConnections
107+
UserDeletedConnectionsNotification (tUnqualified self) remoteConnections
108108
void $ executeFederated (tDomain remotes) fedRPC

services/brig/src/Brig/IO/Intra.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,11 @@ import Data.Id
9898
import Data.Json.Util (UTCTimeMillis, (#))
9999
import Data.List.Split (chunksOf)
100100
import Data.List1 (List1, list1, singleton)
101+
import Data.Proxy
101102
import Data.Qualified
102103
import Data.Range
103104
import qualified Data.Set as Set
105+
import GHC.TypeLits
104106
import Galley.Types (Connect (..), Conversation)
105107
import Galley.Types.Conversations.Intra (UpsertOne2OneConversationRequest, UpsertOne2OneConversationResponse)
106108
import qualified Galley.Types.Teams as Team
@@ -114,6 +116,7 @@ import Network.HTTP.Types.Method
114116
import Network.HTTP.Types.Status
115117
import qualified Network.Wai.Utilities.Error as Wai
116118
import System.Logger.Class as Log hiding (name, (.=))
119+
import Wire.API.Federation.API.Brig
117120
import Wire.API.Federation.Client
118121
import Wire.API.Federation.Error (federationErrorToWai, federationNotImplemented)
119122
import Wire.API.Message (UserClients)
@@ -256,16 +259,15 @@ notifyUserDeletionLocals deleted conn event = do
256259
notifyUserDeletionRemotes :: UserId -> AppIO ()
257260
notifyUserDeletionRemotes deleted = do
258261
runConduit $
259-
Data.lookupRemoteConnectedUsersC deleted 1000
262+
Data.lookupRemoteConnectedUsersC deleted (fromInteger (natVal (Proxy @UserDeletedNotificationMaxConnections)))
260263
.| C.mapM_ fanoutNotifications
261264
where
262265
fanoutNotifications :: [Remote UserId] -> AppIO ()
263266
fanoutNotifications = mapM_ notifyBackend . bucketRemote
264267

265268
notifyBackend :: Remote [UserId] -> AppIO ()
266269
notifyBackend uids = do
267-
let rangedMaybeUids = checked @_ @1 @1000 <$> uids
268-
case tUnqualified rangedMaybeUids of
270+
case tUnqualified (checked <$> uids) of
269271
Nothing ->
270272
-- The user IDs cannot be more than 1000, so we can assume the range
271273
-- check will only fail because there are 0 User Ids.

services/brig/test/integration/API/Federation.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import Test.Tasty
4242
import qualified Test.Tasty.Cannon as WS
4343
import Test.Tasty.HUnit (assertEqual, assertFailure)
4444
import Util
45-
import Wire.API.Federation.API.Brig (GetUserClients (..), SearchRequest (SearchRequest), UserDeletedNotification (..))
45+
import Wire.API.Federation.API.Brig (GetUserClients (..), SearchRequest (SearchRequest), UserDeletedConnectionsNotification (..))
4646
import qualified Wire.API.Federation.API.Brig as FedBrig
4747
import Wire.API.Message (UserClients (..))
4848
import Wire.API.User.Client (mkUserClientPrekeyMap)
@@ -67,7 +67,7 @@ tests m opts brig cannon fedBrigClient =
6767
test m "POST /federation/claim-multi-prekey-bundle : 200" (testClaimMultiPrekeyBundleSuccess brig fedBrigClient),
6868
test m "POST /federation/get-user-clients : 200" (testGetUserClients brig fedBrigClient),
6969
test m "POST /federation/get-user-clients : Not Found" (testGetUserClientsNotFound fedBrigClient),
70-
test m "POST /federation/on-user-deleted : 200" (testRemoteUserGetsDeleted opts brig cannon fedBrigClient)
70+
test m "POST /federation/on-user-deleted/connections : 200" (testRemoteUserGetsDeleted opts brig cannon fedBrigClient)
7171
]
7272

7373
testSearchSuccess :: Brig -> FedBrigClient -> Http ()
@@ -238,7 +238,7 @@ testRemoteUserGetsDeleted opts brig cannon fedBrigClient = do
238238
FedBrig.onUserDeleted
239239
fedBrigClient
240240
(qDomain remoteUser)
241-
(UserDeletedNotification (qUnqualified remoteUser) (unsafeRange localUsers))
241+
(UserDeletedConnectionsNotification (qUnqualified remoteUser) (unsafeRange localUsers))
242242

243243
WS.assertMatchN_ (5 # Second) [cc] $ matchDeleteUserNotification remoteUser
244244
WS.assertNoEvent (1 # Second) [pc, bc, uc]

services/brig/test/integration/API/User/Account.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ import UnliftIO (mapConcurrently_)
7777
import Util as Util
7878
import Util.AWS as Util
7979
import Web.Cookie (parseSetCookie)
80-
import Wire.API.Federation.API.Brig (UserDeletedNotification (..))
80+
import Wire.API.Federation.API.Brig (UserDeletedConnectionsNotification (..))
8181
import qualified Wire.API.Federation.API.Brig as FedBrig
8282
import Wire.API.Federation.API.Common (EmptyResponse (EmptyResponse))
8383
import Wire.API.Federation.GRPC.Types (OutwardResponse (OutwardResponseBody))
@@ -1241,14 +1241,14 @@ testDeleteWithRemotes opts brig = do
12411241
liftIO $ do
12421242
remote1Call <- assertOne $ filter (\c -> F.domain c == domainText remote1Domain) rpcCalls
12431243
remote1Udn <- assertRight $ parseFedRequest remote1Call
1244-
udnUser remote1Udn @?= userId localUser
1245-
sort (fromRange (udnConnections remote1Udn))
1244+
udcnUser remote1Udn @?= userId localUser
1245+
sort (fromRange (udcnConnections remote1Udn))
12461246
@?= sort (map qUnqualified [remote1UserConnected, remote1UserPending])
12471247

12481248
remote2Call <- assertOne $ filter (\c -> F.domain c == domainText remote2Domain) rpcCalls
12491249
remote2Udn <- assertRight $ parseFedRequest remote2Call
1250-
udnUser remote2Udn @?= userId localUser
1251-
fromRange (udnConnections remote2Udn) @?= [qUnqualified remote2UserBlocked]
1250+
udcnUser remote2Udn @?= userId localUser
1251+
fromRange (udcnConnections remote2Udn) @?= [qUnqualified remote2UserBlocked]
12521252
where
12531253
parseFedRequest :: FromJSON a => F.FederatedRequest -> Either String a
12541254
parseFedRequest fr =

services/galley/src/Galley/API/Federation.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ import Wire.API.Federation.API.Galley
6464
MessageSendResponse (..),
6565
NewRemoteConversation (..),
6666
RemoteMessage (..),
67-
UserDeletedNotification,
67+
UserDeletedConversationsNotification,
6868
)
6969
import qualified Wire.API.Federation.API.Galley as FederationAPIGalley
7070
import Wire.API.Routes.Internal.Brig.Connection
@@ -278,11 +278,11 @@ sendMessage originDomain msr = do
278278
where
279279
err = throwM . invalidPayload . LT.pack
280280

281-
onUserDeleted :: Domain -> UserDeletedNotification -> Galley EmptyResponse
282-
onUserDeleted origDomain udn = do
283-
let deletedUser = toRemoteUnsafe origDomain (FederationAPIGalley.udnUser udn)
281+
onUserDeleted :: Domain -> UserDeletedConversationsNotification -> Galley EmptyResponse
282+
onUserDeleted origDomain udcn = do
283+
let deletedUser = toRemoteUnsafe origDomain (FederationAPIGalley.udcnUser udcn)
284284
untaggedDeletedUser = qUntagged deletedUser
285-
convIds = FederationAPIGalley.udnConversations udn
285+
convIds = FederationAPIGalley.udcnConversations udcn
286286
pooledForConcurrentlyN_ 16 (fromRange convIds) $ \c -> do
287287
lc <- qualifyLocal c
288288
mconv <- Data.conversation c

0 commit comments

Comments
 (0)