|
| 1 | +{-# OPTIONS_GHC -Wno-ambiguous-fields #-} |
| 2 | + |
1 | 3 | module Test.User where
|
2 | 4 |
|
3 | 5 | import API.Brig
|
4 | 6 | import API.BrigInternal
|
| 7 | +import API.GalleyInternal |
| 8 | +import API.Spar |
| 9 | +import qualified Data.UUID as UUID |
| 10 | +import qualified Data.UUID.V4 as UUID |
5 | 11 | import SetupHelpers
|
6 | 12 | import Testlib.Prelude
|
7 | 13 |
|
@@ -47,3 +53,120 @@ testCreateUserSupportedProtocols = do
|
47 | 53 | bindResponse (createUser OwnDomain def {supportedProtocols = Just ["proteus", "mixed"]}) $ \resp -> do
|
48 | 54 | resp.status `shouldMatchInt` 400
|
49 | 55 | resp.json %. "label" `shouldMatch` "bad-request"
|
| 56 | + |
| 57 | +-- | For now this only tests attempts to update /self/handle in E2EId-enabled teams. More |
| 58 | +-- tests can be found under `/services/brig/test/integration` (and should be moved here). |
| 59 | +testUpdateHandle :: HasCallStack => App () |
| 60 | +testUpdateHandle = do |
| 61 | + -- create team with one member, without scim, but with `mlsE2EId` enabled. |
| 62 | + (owner, team, [mem1]) <- createTeam OwnDomain 2 |
| 63 | + mem1id <- asString $ mem1 %. "id" |
| 64 | + |
| 65 | + let featureName = "mlsE2EId" |
| 66 | + bindResponse (getTeamFeature owner featureName team) $ \resp -> do |
| 67 | + resp.status `shouldMatchInt` 200 |
| 68 | + resp.json %. "status" `shouldMatch` "disabled" |
| 69 | + setTeamFeatureStatus owner team featureName "enabled" |
| 70 | + bindResponse (getTeamFeature owner featureName team) $ \resp -> do |
| 71 | + resp.status `shouldMatchInt` 200 |
| 72 | + resp.json %. "status" `shouldMatch` "enabled" |
| 73 | + |
| 74 | + -- all as expected here. (see the second time we check this at the end of the test for an |
| 75 | + -- explanation why we care.) |
| 76 | + bindResponse (getSelf mem1) $ \resp -> do |
| 77 | + resp.status `shouldMatchInt` 200 |
| 78 | + resp.json %. "managed_by" `shouldMatch` "wire" |
| 79 | + bindResponse (getUsersId owner [mem1id]) $ \resp -> do |
| 80 | + resp.status `shouldMatchInt` 200 |
| 81 | + mb <- (assertOne =<< asList resp.json) %. "managed_by" |
| 82 | + mb `shouldMatch` "wire" |
| 83 | + |
| 84 | + -- mem1 attempts to update handle for the first time => success |
| 85 | + -- |
| 86 | + -- this is desired, because without SCIM users need to pick their own handles initially. |
| 87 | + -- moreover it is fine, because if `handle == NULL`, no mls E2Eid client certs can be |
| 88 | + -- created. |
| 89 | + handle <- UUID.toString <$> liftIO UUID.nextRandom |
| 90 | + bindResponse (putHandle mem1 handle) $ \resp -> do |
| 91 | + resp.status `shouldMatchInt` 200 |
| 92 | + bindResponse (putHandle mem1 handle) $ \resp -> do |
| 93 | + -- idempotency |
| 94 | + resp.status `shouldMatchInt` 200 |
| 95 | + |
| 96 | + -- mem1 attempts to update handle again => failure |
| 97 | + handle2 <- UUID.toString <$> liftIO UUID.nextRandom |
| 98 | + bindResponse (putHandle mem1 handle2) $ \resp -> do |
| 99 | + resp.status `shouldMatchInt` 403 |
| 100 | + resp.json %. "label" `shouldMatch` "managed-by-scim" |
| 101 | + |
| 102 | + -- now self thinks it is managed by "scim", so clients can block change attempts to handle, |
| 103 | + -- display name without adding E2EId-specific logic. this is just a hack, though: `GET |
| 104 | + -- /self` is the only place where this is happening, other end-points still report the truth |
| 105 | + -- that is still stored correctly in the DB. |
| 106 | + -- |
| 107 | + -- details: https://wearezeta.atlassian.net/browse/WPB-6189. |
| 108 | + -- FUTUREWORK: figure out a better way for clients to detect E2EId (V6?) |
| 109 | + bindResponse (getSelf mem1) $ \resp -> do |
| 110 | + resp.status `shouldMatchInt` 200 |
| 111 | + resp.json %. "managed_by" `shouldMatch` "scim" |
| 112 | + bindResponse (getUsersId owner [mem1id]) $ \resp -> do |
| 113 | + resp.status `shouldMatchInt` 200 |
| 114 | + mb <- (assertOne =<< asList resp.json) %. "managed_by" |
| 115 | + mb `shouldMatch` "wire" |
| 116 | + bindResponse (getScimTokens owner) $ \resp -> do |
| 117 | + resp.status `shouldMatchInt` 200 |
| 118 | + resp.json %. "tokens" `shouldMatch` ([] @String) |
| 119 | + |
| 120 | +-- | For now this only tests attempts to update one's own display name, email address, or |
| 121 | +-- language in E2EId-enabled teams (ie., everything except handle). More tests can be found |
| 122 | +-- under `/services/brig/test/integration` (and should be moved here). |
| 123 | +testUpdateSelf :: HasCallStack => TestUpdateSelfMode -> App () |
| 124 | +testUpdateSelf mode = do |
| 125 | + -- create team with one member, without scim, but with `mlsE2EId` enabled. |
| 126 | + (owner, team, [mem1]) <- createTeam OwnDomain 2 |
| 127 | + |
| 128 | + let featureName = "mlsE2EId" |
| 129 | + bindResponse (getTeamFeature owner featureName team) $ \resp -> do |
| 130 | + resp.status `shouldMatchInt` 200 |
| 131 | + resp.json %. "status" `shouldMatch` "disabled" |
| 132 | + setTeamFeatureStatus owner team featureName "enabled" |
| 133 | + bindResponse (getTeamFeature owner featureName team) $ \resp -> do |
| 134 | + resp.status `shouldMatchInt` 200 |
| 135 | + resp.json %. "status" `shouldMatch` "enabled" |
| 136 | + |
| 137 | + case mode of |
| 138 | + TestUpdateDisplayName -> do |
| 139 | + -- blocked unconditionally |
| 140 | + someDisplayName <- UUID.toString <$> liftIO UUID.nextRandom |
| 141 | + before <- getSelf mem1 |
| 142 | + bindResponse (putSelf mem1 def {name = Just someDisplayName}) $ \resp -> do |
| 143 | + resp.status `shouldMatchInt` 403 |
| 144 | + resp.json %. "label" `shouldMatch` "managed-by-scim" |
| 145 | + after <- getSelf mem1 |
| 146 | + void $ (before.json %. "name") `shouldMatch` (after.json %. "name") |
| 147 | + TestUpdateEmailAddress -> do |
| 148 | + -- allowed unconditionally *for owner* (this is a bit off-topic: team members can't |
| 149 | + -- change their email addresses themselves under any conditions) |
| 150 | + someEmail <- (<> "@example.com") . UUID.toString <$> liftIO UUID.nextRandom |
| 151 | + bindResponse (putSelfEmail owner someEmail) $ \resp -> do |
| 152 | + resp.status `shouldMatchInt` 200 |
| 153 | + TestUpdateLocale -> do |
| 154 | + -- scim maps "User.preferredLanguage" to brig's locale field. allowed unconditionally. |
| 155 | + -- we try two languages to make sure it doesn't work because it's already the active |
| 156 | + -- locale. |
| 157 | + forM_ ["uk", "he"] $ \someLocale -> |
| 158 | + bindResponse (putSelfLocale mem1 someLocale) $ \resp -> do |
| 159 | + resp.status `shouldMatchInt` 200 |
| 160 | + |
| 161 | +data TestUpdateSelfMode |
| 162 | + = TestUpdateDisplayName |
| 163 | + | TestUpdateEmailAddress |
| 164 | + | TestUpdateLocale |
| 165 | + deriving (Eq, Show, Bounded, Enum) |
| 166 | + |
| 167 | +instance HasTests x => HasTests (TestUpdateSelfMode -> x) where |
| 168 | + mkTests m n s f x = |
| 169 | + mconcat |
| 170 | + [ mkTests m (n <> "[mode=" <> show mode <> "]") s f (x mode) |
| 171 | + | mode <- [minBound ..] |
| 172 | + ] |
0 commit comments