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

[WPB-5389] Guard user connection requests by team-level federation settings #3774

Merged
merged 27 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1bf760a
Define the new user connection request error
mdimjasevic Nov 30, 2023
77dbb28
An effect utility to check team federation
mdimjasevic Dec 1, 2023
40af043
Perform team federation checks on the calling side
mdimjasevic Nov 30, 2023
025ee87
Formatting the code
mdimjasevic Dec 1, 2023
0944177
Introduce 1-1 conv test setup helpers
mdimjasevic Dec 13, 2023
2263d76
Test: Migrate "Remote connections: mutual Connect - local action then…
mdimjasevic Dec 12, 2023
735c8e1
Test: Migrate "Remote connections: mutual Connect - remote action the…
mdimjasevic Dec 13, 2023
64a8831
[feat] move testRemoteUserGetsDeleted to new integration testsuite
MangoIV Dec 13, 2023
326d078
Test utility to assert on connection status
mdimjasevic Dec 13, 2023
19103cb
Test: Migrate "Remote connections: ignore then accept"
mdimjasevic Dec 13, 2023
0753614
Test: Migrate "Remote connections: ignore, remote cancels, then accept"
mdimjasevic Dec 13, 2023
974d2ac
Test: Migrate "Remote connections: block then accept"
mdimjasevic Dec 13, 2023
71a3aa5
Test: Migrate "Remote connections: block, remote cancels, then accept"
mdimjasevic Dec 13, 2023
22b6119
Test: Migrate "Remote connections: send then cancel"
mdimjasevic Dec 13, 2023
3334e14
[feat] move testInternalGetConStatusesAll to new testsuite
MangoIV Dec 13, 2023
e969c4a
Include the team ID in the fed connection request
mdimjasevic Dec 13, 2023
2d3b0cd
[feat] move testConnectionLimits to new integration test suite
MangoIV Dec 13, 2023
5ecfbff
Revert the generalisation of 'ensureFederatesWith'
mdimjasevic Dec 14, 2023
afe5585
[fix] comment back in test that is still broken
MangoIV Dec 14, 2023
73aaf60
Test: not federating with a remote team
mdimjasevic Dec 14, 2023
64a6764
Test: connection attempt under non-mutual federation
mdimjasevic Dec 14, 2023
bf9cd5f
Test: connect under allow-all mutual federation
mdimjasevic Dec 14, 2023
baecae3
Test: connect under allow-dynamic mutual federation
mdimjasevic Dec 14, 2023
4428ca6
Test: connect under mixed federation-allow policies
mdimjasevic Dec 14, 2023
e39b56f
Add a changelog
mdimjasevic Dec 14, 2023
8cc26cb
Remove an unused fed client argument in tests
mdimjasevic Dec 15, 2023
2818183
fixup! Introduce 1-1 conv test setup helpers
mdimjasevic Dec 18, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Apply team-level federation policies when establishing and updating user connections
1 change: 1 addition & 0 deletions integration/integration.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ library
Test.B2B
Test.Brig
Test.Client
Test.Connection
Test.Conversation
Test.Demo
Test.Errors
Expand Down
18 changes: 18 additions & 0 deletions integration/test/API/BrigInternal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module API.BrigInternal where

import API.Common
import Data.Aeson qualified as Aeson
import Data.Aeson.Types (Pair)
import Data.Function
import Data.Maybe
import Testlib.Prelude
Expand Down Expand Up @@ -187,3 +188,20 @@ deleteFederationRemoteTeam domain remoteDomain team = do
req <- baseRequest domain Brig Unversioned $ joinHttpPath ["i", "federation", "remotes", d, "teams", t]
res <- submit "DELETE" req
res.status `shouldMatchInt` 200

getConnStatusForUsers :: (HasCallStack, MakesValue users) => users -> Domain -> App Response
getConnStatusForUsers users domain = do
usersList <-
asList users >>= \us -> do
dom <- us `for` (%. "qualified_id.domain")
dom `for_` (`shouldMatch` make domain)
us `for` (%. "id")
usersJSON <- make usersList
getConnStatusInternal ["from" .= usersJSON] domain

getConnStatusInternal :: (HasCallStack) => [Pair] -> Domain -> App Response
getConnStatusInternal body dom = do
req <- baseRequest dom Brig Unversioned do
joinHttpPath ["i", "users", "connections-status", "v2"]
submit "POST" do
req & addJSONObject body
51 changes: 51 additions & 0 deletions integration/test/SetupHelpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,54 @@ withFederatingBackendsAllowDynamic k = do
def {brigCfg = setFederationConfig}
]
$ \[domainA, domainB, domainC] -> k (domainA, domainB, domainC)

-- | Create two users on different domains such that the one-to-one
-- conversation, once finalised, will be hosted on the backend given by the
-- input domain.
createOne2OneConversation :: HasCallStack => Domain -> App (Value, Value, Value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could imagine, that if this gets reused by other tests in the future, that the caller would want to provide both the domains with support for the dynamic backends as well. But then again, this can be added when needed. So all good.

createOne2OneConversation owningDomain = do
owningUser <- randomUser owningDomain def
domainName <- owningUser %. "qualified_id.domain"
let otherDomain = case owningDomain of
OwnDomain -> OtherDomain
OtherDomain -> OwnDomain
let go = do
otherUser <- randomUser otherDomain def
otherUserId <- otherUser %. "qualified_id"
conn <-
postConnection owningUser otherUser `bindResponse` \resp -> do
resp.status `shouldMatchInt` 201
payload <- resp.json
payload %. "status" `shouldMatch` "sent"
payload %. "qualified_to" `shouldMatch` otherUserId
pure payload
one2one <- conn %. "qualified_conversation"
one2oneDomain <- one2one %. "domain"
if domainName == one2oneDomain
then pure (owningUser, otherUser, one2one)
else SetupHelpers.deleteUser otherUser >> go
go

data One2OneConvState = Established | Connect

-- | Converts to an integer corresponding to the numeric representation of the
-- 'Wire.API.Conversation.ConvType' type.
toConvType :: One2OneConvState -> Int
toConvType = \case
Established -> 2
Connect -> 3

-- | Fetch the one-to-one conversation between the two users that is in one of
-- two possible states.
getOne2OneConversation :: HasCallStack => Value -> Value -> One2OneConvState -> App Value
getOne2OneConversation user1 user2 cnvState = do
l <- getAllConvs user1
let isWith users c = do
-- The conversation type 2 is for 1-to-1 conversations. Type 3 is for
-- the connection conversation, which is the state of the conversation
-- before the connection is fully established.
t <- (== toConvType cnvState) <$> (c %. "type" & asInt)
others <- c %. "members.others" & asList
qIds <- for others (%. "qualified_id")
pure $ qIds == users && t
head <$> filterM (isWith [user2]) l
Loading