@@ -64,9 +64,15 @@ import qualified Spar.Intra.Brig as Brig
64
64
import qualified Spar.Intra.Galley as Galley
65
65
import Spar.Orphans ()
66
66
import Spar.Scim
67
+ import Spar.Sem.DefaultSsoCode (DefaultSsoCode )
68
+ import qualified Spar.Sem.DefaultSsoCode as DefaultSsoCode
67
69
import qualified Spar.Sem.IdP as IdPEffect
68
- import Spar.Sem.SAMLUser (SAMLUser )
69
- import qualified Spar.Sem.SAMLUser as SAMLUser
70
+ import Spar.Sem.SAMLUserStore (SAMLUserStore )
71
+ import qualified Spar.Sem.SAMLUserStore as SAMLUserStore
72
+ import Spar.Sem.ScimExternalIdStore (ScimExternalIdStore )
73
+ import Spar.Sem.ScimTokenStore (ScimTokenStore )
74
+ import qualified Spar.Sem.ScimTokenStore as ScimTokenStore
75
+ import Spar.Sem.ScimUserTimesStore (ScimUserTimesStore )
70
76
import qualified URI.ByteString as URI
71
77
import Wire.API.Cookie
72
78
import Wire.API.Routes.Public.Spar
@@ -78,7 +84,7 @@ app ctx =
78
84
SAML. setHttpCachePolicy $
79
85
serve (Proxy @ API ) (hoistServer (Proxy @ API ) (SAML. nt @ SparError @ (Spar _ ) ctx) (api $ sparCtxOpts ctx) :: Server API )
80
86
81
- api :: Members [ IdPEffect. IdP , SAMLUser ] r => Opts -> ServerT API (Spar r )
87
+ api :: Members '[ ScimExternalIdStore , ScimUserTimesStore , ScimTokenStore , DefaultSsoCode , IdPEffect. IdP , SAMLUserStore ] r => Opts -> ServerT API (Spar r )
82
88
api opts =
83
89
apiSSO opts
84
90
:<|> authreqPrecheck
@@ -87,7 +93,7 @@ api opts =
87
93
:<|> apiScim
88
94
:<|> apiINTERNAL
89
95
90
- apiSSO :: Members [ IdPEffect. IdP , SAMLUser ] r => Opts -> ServerT APISSO (Spar r )
96
+ apiSSO :: Members '[ ScimTokenStore , DefaultSsoCode , IdPEffect. IdP , SAMLUserStore ] r => Opts -> ServerT APISSO (Spar r )
91
97
apiSSO opts =
92
98
SAML. meta appName (sparSPIssuer Nothing ) (sparResponseURI Nothing )
93
99
:<|> (\ tid -> SAML. meta appName (sparSPIssuer (Just tid)) (sparResponseURI (Just tid)))
@@ -97,7 +103,7 @@ apiSSO opts =
97
103
:<|> authresp . Just
98
104
:<|> ssoSettings
99
105
100
- apiIDP :: Members [ IdPEffect. IdP , SAMLUser ] r => ServerT APIIDP (Spar r )
106
+ apiIDP :: Members '[ ScimTokenStore , IdPEffect. IdP , SAMLUserStore ] r => ServerT APIIDP (Spar r )
101
107
apiIDP =
102
108
idpGet
103
109
:<|> idpGetRaw
@@ -106,7 +112,7 @@ apiIDP =
106
112
:<|> idpUpdate
107
113
:<|> idpDelete
108
114
109
- apiINTERNAL :: Members [ IdPEffect. IdP , SAMLUser ] r => ServerT APIINTERNAL (Spar r )
115
+ apiINTERNAL :: Members '[ ScimTokenStore , DefaultSsoCode , IdPEffect. IdP , SAMLUserStore ] r => ServerT APIINTERNAL (Spar r )
110
116
apiINTERNAL =
111
117
internalStatus
112
118
:<|> internalDeleteTeam
@@ -181,7 +187,7 @@ validateRedirectURL uri = do
181
187
unless ((SBS. length $ URI. serializeURIRef' uri) <= redirectURLMaxLength) $ do
182
188
throwSpar $ SparBadInitiateLoginQueryParams " url-too-long"
183
189
184
- authresp :: forall r . Members [ IdPEffect. IdP , SAMLUser ] r => Maybe TeamId -> Maybe ST -> SAML. AuthnResponseBody -> Spar r Void
190
+ authresp :: forall r . Members '[ ScimTokenStore , IdPEffect. IdP , SAMLUserStore ] r => Maybe TeamId -> Maybe ST -> SAML. AuthnResponseBody -> Spar r Void
185
191
authresp mbtid ckyraw arbody = logErrors $ SAML. authresp mbtid (sparSPIssuer mbtid) (sparResponseURI mbtid) go arbody
186
192
where
187
193
cky :: Maybe BindCookie
@@ -202,9 +208,9 @@ authresp mbtid ckyraw arbody = logErrors $ SAML.authresp mbtid (sparSPIssuer mbt
202
208
(Multipart. inputs (SAML. authnResponseBodyRaw arbody))
203
209
ckyraw
204
210
205
- ssoSettings :: Spar r SsoSettings
211
+ ssoSettings :: Member DefaultSsoCode r => Spar r SsoSettings
206
212
ssoSettings = do
207
- SsoSettings <$> wrapMonadClient Data. getDefaultSsoCode
213
+ SsoSettings <$> wrapMonadClientSem DefaultSsoCode. get
208
214
209
215
----------------------------------------------------------------------------
210
216
-- IdP API
@@ -237,20 +243,20 @@ idpGetAll zusr = withDebugLog "idpGetAll" (const Nothing) $ do
237
243
-- matter what the team size, it shouldn't choke any servers, just the client (which is
238
244
-- probably curl running locally on one of the spar instances).
239
245
-- https://github.com/zinfra/backend-issues/issues/1314
240
- idpDelete :: forall r . Members [ SAMLUser , IdPEffect. IdP ] r => Maybe UserId -> SAML. IdPId -> Maybe Bool -> Spar r NoContent
246
+ idpDelete :: forall r . Members '[ ScimTokenStore , SAMLUserStore , IdPEffect. IdP ] r => Maybe UserId -> SAML. IdPId -> Maybe Bool -> Spar r NoContent
241
247
idpDelete zusr idpid (fromMaybe False -> purge) = withDebugLog " idpDelete" (const Nothing ) $ do
242
248
idp <- SAML. getIdPConfig idpid
243
249
_ <- authorizeIdP zusr idp
244
250
let issuer = idp ^. SAML. idpMetadata . SAML. edIssuer
245
251
team = idp ^. SAML. idpExtraInfo . wiTeam
246
252
-- if idp is not empty: fail or purge
247
- idpIsEmpty <- wrapMonadClientSem $ isNothing <$> SAMLUser . getAnyByIssuer issuer
253
+ idpIsEmpty <- wrapMonadClientSem $ isNothing <$> SAMLUserStore . getAnyByIssuer issuer
248
254
let doPurge :: Spar r ()
249
255
doPurge = do
250
- some <- wrapMonadClientSem (SAMLUser . getSomeByIssuer issuer)
256
+ some <- wrapMonadClientSem (SAMLUserStore . getSomeByIssuer issuer)
251
257
forM_ some $ \ (uref, uid) -> do
252
258
Brig. deleteBrigUser uid
253
- wrapMonadClientSem (SAMLUser . delete uid uref)
259
+ wrapMonadClientSem (SAMLUserStore . delete uid uref)
254
260
unless (null some) doPurge
255
261
when (not idpIsEmpty) $ do
256
262
if purge
@@ -262,9 +268,9 @@ idpDelete zusr idpid (fromMaybe False -> purge) = withDebugLog "idpDelete" (cons
262
268
-- Delete tokens associated with given IdP (we rely on the fact that
263
269
-- each IdP has exactly one team so we can look up all tokens
264
270
-- associated with the team and then filter them)
265
- tokens <- liftMonadClient $ Data. getScimTokens team
271
+ tokens <- liftSem $ ScimTokenStore. getByTeam team
266
272
for_ tokens $ \ ScimTokenInfo {.. } ->
267
- when (stiIdP == Just idpid) $ liftMonadClient $ Data. deleteScimToken team stiId
273
+ when (stiIdP == Just idpid) $ liftSem $ ScimTokenStore. delete team stiId
268
274
-- Delete IdP config
269
275
liftSem $ do
270
276
IdPEffect. deleteConfig idpid issuer team
@@ -292,11 +298,11 @@ idpDelete zusr idpid (fromMaybe False -> purge) = withDebugLog "idpDelete" (cons
292
298
293
299
-- | This handler only does the json parsing, and leaves all authorization checks and
294
300
-- application logic to 'idpCreateXML'.
295
- idpCreate :: Member IdPEffect. IdP r => Maybe UserId -> IdPMetadataInfo -> Maybe SAML. IdPId -> Maybe WireIdPAPIVersion -> Spar r IdP
301
+ idpCreate :: Members '[ ScimTokenStore , IdPEffect. IdP] r => Maybe UserId -> IdPMetadataInfo -> Maybe SAML. IdPId -> Maybe WireIdPAPIVersion -> Spar r IdP
296
302
idpCreate zusr (IdPMetadataValue raw xml) midpid apiversion = idpCreateXML zusr raw xml midpid apiversion
297
303
298
304
-- | We generate a new UUID for each IdP used as IdPConfig's path, thereby ensuring uniqueness.
299
- idpCreateXML :: Member IdPEffect. IdP r => Maybe UserId -> Text -> SAML. IdPMetadata -> Maybe SAML. IdPId -> Maybe WireIdPAPIVersion -> Spar r IdP
305
+ idpCreateXML :: Members '[ ScimTokenStore , IdPEffect. IdP] r => Maybe UserId -> Text -> SAML. IdPMetadata -> Maybe SAML. IdPId -> Maybe WireIdPAPIVersion -> Spar r IdP
300
306
idpCreateXML zusr raw idpmeta mReplaces (fromMaybe defWireIdPAPIVersion -> apiversion) = withDebugLog " idpCreate" (Just . show . (^. SAML. idpId)) $ do
301
307
teamid <- Brig. getZUsrCheckPerm zusr CreateUpdateDeleteIdp
302
308
Galley. assertSSOEnabled teamid
@@ -312,9 +318,9 @@ idpCreateXML zusr raw idpmeta mReplaces (fromMaybe defWireIdPAPIVersion -> apive
312
318
-- data contains no information about the idp issuer, only the user name, so no valid saml
313
319
-- credentials can be created. To fix this, we need to implement a way to associate scim
314
320
-- tokens with IdPs. https://wearezeta.atlassian.net/browse/SQSERVICES-165
315
- assertNoScimOrNoIdP :: Member IdPEffect. IdP r => TeamId -> Spar r ()
321
+ assertNoScimOrNoIdP :: Members '[ ScimTokenStore , IdPEffect. IdP] r => TeamId -> Spar r ()
316
322
assertNoScimOrNoIdP teamid = do
317
- numTokens <- length <$> wrapMonadClient ( Data. getScimTokens teamid)
323
+ numTokens <- length <$> wrapMonadClientSem ( ScimTokenStore. getByTeam teamid)
318
324
numIdps <- length <$> wrapMonadClientSem (IdPEffect. getConfigsByTeam teamid)
319
325
when (numTokens > 0 && numIdps > 0 ) $ do
320
326
throwSpar $
@@ -482,14 +488,14 @@ internalStatus = pure NoContent
482
488
483
489
-- | Cleanup handler that is called by Galley whenever a team is about to
484
490
-- get deleted.
485
- internalDeleteTeam :: Members [ IdPEffect. IdP , SAMLUser ] r => TeamId -> Spar r NoContent
491
+ internalDeleteTeam :: Members '[ ScimTokenStore , IdPEffect. IdP , SAMLUserStore ] r => TeamId -> Spar r NoContent
486
492
internalDeleteTeam team = do
487
493
wrapSpar $ deleteTeam team
488
494
pure NoContent
489
495
490
- internalPutSsoSettings :: Member IdPEffect. IdP r => SsoSettings -> Spar r NoContent
496
+ internalPutSsoSettings :: Members '[ DefaultSsoCode , IdPEffect. IdP] r => SsoSettings -> Spar r NoContent
491
497
internalPutSsoSettings SsoSettings {defaultSsoCode = Nothing } = do
492
- wrapMonadClient $ Data. deleteDefaultSsoCode
498
+ wrapMonadClientSem $ DefaultSsoCode. delete
493
499
pure NoContent
494
500
internalPutSsoSettings SsoSettings {defaultSsoCode = Just code} = do
495
501
wrapMonadClientSem (IdPEffect. getConfig code) >>= \ case
@@ -499,5 +505,5 @@ internalPutSsoSettings SsoSettings {defaultSsoCode = Just code} = do
499
505
-- "Could not find IdP".
500
506
throwSpar $ SparIdPNotFound mempty
501
507
Just _ -> do
502
- wrapMonadClient $ Data. storeDefaultSsoCode code
508
+ wrapMonadClientSem $ DefaultSsoCode. store code
503
509
pure NoContent
0 commit comments