Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion changelog.d/3-bug-fixes/fix-saml-corner-case

This file was deleted.

54 changes: 22 additions & 32 deletions services/brig/src/Brig/API/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -607,42 +607,32 @@ changeSelfEmail u email allowScim = do
-- | Prepare changing the email (checking a number of invariants).
changeEmail :: UserId -> Email -> AllowSCIMUpdates -> ExceptT ChangeEmailError (AppT r) ChangeEmailResult
changeEmail u email allowScim = do
eml <- either (throwE . InvalidNewEmail email) pure (validateEmail email)
let eky = userEmailKey eml

blacklisted <- lift . wrapClient $ Blacklist.exists eky
em <-
either
(throwE . InvalidNewEmail email)
pure
(validateEmail email)
let ek = userEmailKey em
blacklisted <- lift . wrapClient $ Blacklist.exists ek
when blacklisted $
throwE (ChangeBlacklistedEmail email)

available <- lift . wrapClient $ Data.keyAvailable eky (Just u)
available <- lift . wrapClient $ Data.keyAvailable ek (Just u)
unless available $
throwE (EmailExists email)

usr <-
maybe (throwM $ UserProfileNotFound u) pure
=<< lift (wrapClient $ Data.lookupUser WithPendingInvitations u)

if (emailIdentity =<< userIdentity usr) == Just eml
then do
-- The user already has an email address and the new one is exactly the same
pure ChangeEmailIdempotent
else do
-- case 2: No or different old email address
let changeAllowed =
( userManagedBy usr /= ManagedByScim
|| allowScim == AllowSCIMUpdates -- spar is always allowed to call this function (from the scim handlers)
)
&& not
( -- user is auto-provisioned by saml (deprecated use case)
userManagedBy usr /= ManagedByScim && userHasSAML usr
)

unless changeAllowed $
throwE EmailManagedByScim

throwE $
EmailExists email
usr <- maybe (throwM $ UserProfileNotFound u) pure =<< lift (wrapClient $ Data.lookupUser WithPendingInvitations u)
case emailIdentity =<< userIdentity usr of
-- The user already has an email address and the new one is exactly the same
Just current | current == em -> pure ChangeEmailIdempotent
_ -> do
unless
( userManagedBy usr /= ManagedByScim
|| allowScim == AllowSCIMUpdates
)
$ throwE EmailManagedByScim
timeout <- setActivationTimeout <$> view settings
act <- lift . wrapClient $ Data.newActivation eky timeout (Just u)
pure $ ChangeEmailNeedsActivation (usr, act, eml)
act <- lift . wrapClient $ Data.newActivation ek timeout (Just u)
pure $ ChangeEmailNeedsActivation (usr, act, em)

-------------------------------------------------------------------------------
-- Change Phone
Expand Down
20 changes: 8 additions & 12 deletions services/brig/src/Brig/Data/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ module Brig.Data.User
reauthenticate,
filterActive,
isActivated,
userIdHasSAML,
userHasSAML,
isSamlUser,

-- * Lookups
lookupAccount,
Expand Down Expand Up @@ -213,20 +212,17 @@ reauthenticate u pw =
Just (Just pw', Ephemeral) -> maybeReAuth pw'
where
maybeReAuth pw' = case pw of
Nothing -> unlessM (userIdHasSAML u) $ throwE ReAuthMissingPassword
Nothing -> unlessM (isSamlUser u) $ throwE ReAuthMissingPassword
Just p ->
unless (verifyPassword p pw') $
throwE (ReAuthError AuthInvalidCredentials)

userIdHasSAML :: (MonadClient m, MonadReader Env m) => UserId -> m Bool
userIdHasSAML uid = do
maybe False (userHasSAML . accountUser) <$> lookupAccount uid

userHasSAML :: User -> Bool
userHasSAML user = do
case userIdentity user of
Just (SSOIdentity (UserSSOId _) _ _) -> True
_ -> False
isSamlUser :: (MonadClient m, MonadReader Env m) => UserId -> m Bool
isSamlUser uid = do
account <- lookupAccount uid
case userIdentity . accountUser =<< account of
Just (SSOIdentity (UserSSOId _) _ _) -> pure True
_ -> pure False

insertAccount ::
MonadClient m =>
Expand Down
2 changes: 1 addition & 1 deletion services/brig/src/Brig/User/Auth.hs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ revokeAccess ::
ExceptT AuthError m ()
revokeAccess u pw cc ll = do
lift $ Log.debug $ field "user" (toByteString u) . field "action" (Log.val "User.revokeAccess")
unlessM (Data.userIdHasSAML u) $ Data.authenticate u pw
unlessM (Data.isSamlUser u) $ Data.authenticate u pw
lift $ revokeCookies u cc ll

--------------------------------------------------------------------------------
Expand Down