fix: don't set user-last-authentication during ldap sync
This commit is contained in:
parent
2553b92f62
commit
fdaad16e71
@ -1,5 +1,6 @@
|
|||||||
module Auth.Dummy
|
module Auth.Dummy
|
||||||
( dummyLogin
|
( apDummy
|
||||||
|
, dummyLogin
|
||||||
, DummyMessage(..)
|
, DummyMessage(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -32,6 +33,9 @@ dummyForm = do
|
|||||||
userList = fmap mkOptionList . runDB $ withReaderT projectBackend (map toOption <$> selectList [] [Asc UserIdent] :: ReaderT SqlBackend _ [Option UserIdent])
|
userList = fmap mkOptionList . runDB $ withReaderT projectBackend (map toOption <$> selectList [] [Asc UserIdent] :: ReaderT SqlBackend _ [Option UserIdent])
|
||||||
toOption (Entity _ User{..}) = Option userDisplayName userIdent (CI.original userIdent)
|
toOption (Entity _ User{..}) = Option userDisplayName userIdent (CI.original userIdent)
|
||||||
|
|
||||||
|
apDummy :: Text
|
||||||
|
apDummy = "dummy"
|
||||||
|
|
||||||
dummyLogin :: forall site.
|
dummyLogin :: forall site.
|
||||||
( YesodAuth site
|
( YesodAuth site
|
||||||
, YesodPersist site
|
, YesodPersist site
|
||||||
@ -44,7 +48,7 @@ dummyLogin :: forall site.
|
|||||||
dummyLogin = AuthPlugin{..}
|
dummyLogin = AuthPlugin{..}
|
||||||
where
|
where
|
||||||
apName :: Text
|
apName :: Text
|
||||||
apName = "dummy"
|
apName = apDummy
|
||||||
|
|
||||||
apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent
|
apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent
|
||||||
apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do
|
apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
module Auth.PWHash
|
module Auth.PWHash
|
||||||
( hashLogin
|
( apHash
|
||||||
|
, hashLogin
|
||||||
, PWHashMessage(..)
|
, PWHashMessage(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ hashForm = do
|
|||||||
<$> areq ciField (fslpI MsgPWHashIdent (mr MsgPWHashIdentPlaceholder)) Nothing
|
<$> areq ciField (fslpI MsgPWHashIdent (mr MsgPWHashIdentPlaceholder)) Nothing
|
||||||
<*> areq passwordField (fslpI MsgPWHashPassword (mr MsgPWHashPasswordPlaceholder)) Nothing
|
<*> areq passwordField (fslpI MsgPWHashPassword (mr MsgPWHashPasswordPlaceholder)) Nothing
|
||||||
|
|
||||||
|
apHash :: Text
|
||||||
|
apHash = "PWHash"
|
||||||
|
|
||||||
hashLogin :: forall site.
|
hashLogin :: forall site.
|
||||||
( YesodAuth site
|
( YesodAuth site
|
||||||
@ -53,7 +56,7 @@ hashLogin :: forall site.
|
|||||||
hashLogin pwHashAlgo = AuthPlugin{..}
|
hashLogin pwHashAlgo = AuthPlugin{..}
|
||||||
where
|
where
|
||||||
apName :: Text
|
apName :: Text
|
||||||
apName = "PWHash"
|
apName = apHash
|
||||||
|
|
||||||
apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent
|
apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent
|
||||||
apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do
|
apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
module Foundation.Types
|
module Foundation.Types
|
||||||
( UpsertCampusUserMode(..)
|
( UpsertCampusUserMode(..)
|
||||||
, _UpsertCampusUser, _UpsertCampusUserDummy, _UpsertCampusUserOther
|
, _UpsertCampusUserLoginLdap, _UpsertCampusUserLoginDummy, _UpsertCampusUserLoginOther, _UpsertCampusUserLdapSync, _UpsertCampusUserGuessUser
|
||||||
, _upsertCampusUserIdent
|
, _upsertCampusUserIdent
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -8,9 +8,11 @@ import Import.NoFoundation
|
|||||||
|
|
||||||
|
|
||||||
data UpsertCampusUserMode
|
data UpsertCampusUserMode
|
||||||
= UpsertCampusUser
|
= UpsertCampusUserLoginLdap
|
||||||
| UpsertCampusUserDummy { upsertCampusUserIdent :: UserIdent }
|
| UpsertCampusUserLoginDummy { upsertCampusUserIdent :: UserIdent }
|
||||||
| UpsertCampusUserOther { uspertCampusUserIdent :: UserIdent }
|
| UpsertCampusUserLoginOther { upsertCampusUserIdent :: UserIdent }
|
||||||
|
| UpsertCampusUserLdapSync { upsertCampusUserIdent :: UserIdent }
|
||||||
|
| UpsertCampusUserGuessUser
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||||
|
|
||||||
makeLenses_ ''UpsertCampusUserMode
|
makeLenses_ ''UpsertCampusUserMode
|
||||||
|
|||||||
@ -18,10 +18,11 @@ import Handler.Utils.LdapSystemFunctions
|
|||||||
|
|
||||||
import Yesod.Auth.Message
|
import Yesod.Auth.Message
|
||||||
import Auth.LDAP
|
import Auth.LDAP
|
||||||
|
import Auth.PWHash (apHash)
|
||||||
|
import Auth.Dummy (apDummy)
|
||||||
|
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
import qualified Control.Monad.Catch as C (Handler(..))
|
import qualified Control.Monad.Catch as C (Handler(..))
|
||||||
import qualified Data.List.NonEmpty as NonEmpty
|
|
||||||
import qualified Ldap.Client as Ldap
|
import qualified Ldap.Client as Ldap
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import qualified Data.Text.Encoding as Text
|
import qualified Data.Text.Encoding as Text
|
||||||
@ -55,8 +56,8 @@ authenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend
|
|||||||
uAuth = UniqueAuthentication $ CI.mk credsIdent
|
uAuth = UniqueAuthentication $ CI.mk credsIdent
|
||||||
upsertMode = creds ^? _upsertCampusUserMode
|
upsertMode = creds ^? _upsertCampusUserMode
|
||||||
|
|
||||||
isDummy = is (_Just . _UpsertCampusUserDummy) upsertMode
|
isDummy = is (_Just . _UpsertCampusUserLoginDummy) upsertMode
|
||||||
isOther = is (_Just . _UpsertCampusUserOther) upsertMode
|
isOther = is (_Just . _UpsertCampusUserLoginOther) upsertMode
|
||||||
|
|
||||||
excRecovery res
|
excRecovery res
|
||||||
| isDummy || isOther
|
| isDummy || isOther
|
||||||
@ -129,25 +130,30 @@ data CampusUserConversionException
|
|||||||
|
|
||||||
_upsertCampusUserMode :: Traversal' (Creds UniWorX) UpsertCampusUserMode
|
_upsertCampusUserMode :: Traversal' (Creds UniWorX) UpsertCampusUserMode
|
||||||
_upsertCampusUserMode mMode cs@Creds{..}
|
_upsertCampusUserMode mMode cs@Creds{..}
|
||||||
| credsPlugin == "dummy" = setMode <$> mMode (UpsertCampusUserDummy $ CI.mk credsIdent)
|
| credsPlugin == apDummy = setMode <$> mMode (UpsertCampusUserLoginDummy $ CI.mk credsIdent)
|
||||||
| credsPlugin `elem` others = setMode <$> mMode (UpsertCampusUserOther $ CI.mk credsIdent)
|
| credsPlugin == apLdap = setMode <$> mMode UpsertCampusUserLoginLdap
|
||||||
| otherwise = setMode <$> mMode UpsertCampusUser
|
| otherwise = setMode <$> mMode (UpsertCampusUserLoginOther $ CI.mk credsIdent)
|
||||||
where
|
where
|
||||||
setMode UpsertCampusUser
|
setMode UpsertCampusUserLoginLdap
|
||||||
= cs{ credsPlugin = "LDAP" }
|
= cs{ credsPlugin = apLdap }
|
||||||
setMode (UpsertCampusUserDummy ident)
|
setMode (UpsertCampusUserLoginDummy ident)
|
||||||
= cs{ credsPlugin = "dummy", credsIdent = CI.original ident }
|
= cs{ credsPlugin = apDummy
|
||||||
setMode (UpsertCampusUserOther ident)
|
, credsIdent = CI.original ident
|
||||||
= cs{ credsPlugin = bool (NonEmpty.head others) credsPlugin (credsPlugin `elem` others), credsIdent = CI.original ident }
|
}
|
||||||
|
setMode (UpsertCampusUserLoginOther ident)
|
||||||
|
= cs{ credsPlugin = bool defaultOther credsPlugin (credsPlugin /= apDummy && credsPlugin /= apLdap)
|
||||||
|
, credsIdent = CI.original ident
|
||||||
|
}
|
||||||
|
setMode _ = cs
|
||||||
|
|
||||||
others = "PWHash" :| []
|
defaultOther = apHash
|
||||||
|
|
||||||
upsertCampusUser :: forall m.
|
upsertCampusUser :: forall m.
|
||||||
( MonadHandler m, HandlerSite m ~ UniWorX
|
( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
)
|
)
|
||||||
=> UpsertCampusUserMode -> Ldap.AttrList [] -> SqlPersistT m (Entity User)
|
=> UpsertCampusUserMode -> Ldap.AttrList [] -> SqlPersistT m (Entity User)
|
||||||
upsertCampusUser plugin ldapData = do
|
upsertCampusUser upsertMode ldapData = do
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
UserDefaultConf{..} <- getsYesod $ view _appUserDefaults
|
UserDefaultConf{..} <- getsYesod $ view _appUserDefaults
|
||||||
|
|
||||||
@ -166,17 +172,18 @@ upsertCampusUser plugin ldapData = do
|
|||||||
userSex' = fold [ v | (k, v) <- ldapData, k == ldapSex ]
|
userSex' = fold [ v | (k, v) <- ldapData, k == ldapSex ]
|
||||||
|
|
||||||
userAuthentication
|
userAuthentication
|
||||||
| is _UpsertCampusUserOther plugin
|
| is _UpsertCampusUserLoginOther upsertMode
|
||||||
= error "PWHash should only work for users that are already known"
|
= error "Non-LDAP logins should only work for users that are already known"
|
||||||
| otherwise = AuthLDAP
|
| otherwise = AuthLDAP
|
||||||
userLastAuthentication = now <$ guard (isn't _UpsertCampusUserDummy plugin)
|
userLastAuthentication = guardOn isLogin now
|
||||||
|
isLogin = has (_UpsertCampusUserLoginLdap <> _UpsertCampusUserLoginOther . united) upsertMode
|
||||||
|
|
||||||
userIdent <- if
|
userIdent <- if
|
||||||
| [bs] <- userIdent''
|
| [bs] <- userIdent''
|
||||||
, Right userIdent' <- CI.mk <$> Text.decodeUtf8' bs
|
, Right userIdent' <- CI.mk <$> Text.decodeUtf8' bs
|
||||||
, hasn't _upsertCampusUserIdent plugin || has (_upsertCampusUserIdent . only userIdent') plugin
|
, hasn't _upsertCampusUserIdent upsertMode || has (_upsertCampusUserIdent . only userIdent') upsertMode
|
||||||
-> return userIdent'
|
-> return userIdent'
|
||||||
| Just userIdent' <- plugin ^? _upsertCampusUserIdent
|
| Just userIdent' <- upsertMode ^? _upsertCampusUserIdent
|
||||||
-> return userIdent'
|
-> return userIdent'
|
||||||
| otherwise
|
| otherwise
|
||||||
-> throwM CampusUserInvalidIdent
|
-> throwM CampusUserInvalidIdent
|
||||||
@ -260,7 +267,7 @@ upsertCampusUser plugin ldapData = do
|
|||||||
, UserSex =. userSex
|
, UserSex =. userSex
|
||||||
, UserLastLdapSynchronisation =. Just now
|
, UserLastLdapSynchronisation =. Just now
|
||||||
] ++
|
] ++
|
||||||
[ UserLastAuthentication =. Just now | isn't _UpsertCampusUserDummy plugin ]
|
[ UserLastAuthentication =. Just now | isLogin ]
|
||||||
|
|
||||||
user@(Entity userId userRec) <- upsertBy (UniqueAuthentication userIdent) newUser userUpdate
|
user@(Entity userId userRec) <- upsertBy (UniqueAuthentication userIdent) newUser userUpdate
|
||||||
unless (validDisplayName userTitle userFirstName userSurname $ userDisplayName userRec) $
|
unless (validDisplayName userTitle userFirstName userSurname $ userDisplayName userRec) $
|
||||||
|
|||||||
@ -37,6 +37,8 @@ import qualified Data.Conduit.List as C
|
|||||||
|
|
||||||
import qualified Data.HashSet as HashSet
|
import qualified Data.HashSet as HashSet
|
||||||
|
|
||||||
|
import Auth.Dummy (apDummy)
|
||||||
|
|
||||||
|
|
||||||
hijackUserForm :: Form ()
|
hijackUserForm :: Form ()
|
||||||
hijackUserForm csrf = do
|
hijackUserForm csrf = do
|
||||||
@ -251,7 +253,7 @@ postUsersR = do
|
|||||||
hijackUser :: UserId -> Handler TypedContent
|
hijackUser :: UserId -> Handler TypedContent
|
||||||
hijackUser uid = do
|
hijackUser uid = do
|
||||||
User{userIdent} <- runDB $ get404 uid
|
User{userIdent} <- runDB $ get404 uid
|
||||||
setCredsRedirect $ Creds "dummy" (CI.original userIdent) []
|
setCredsRedirect $ Creds apDummy (CI.original userIdent) []
|
||||||
|
|
||||||
postAdminHijackUserR :: CryptoUUIDUser -> Handler TypedContent
|
postAdminHijackUserR :: CryptoUUIDUser -> Handler TypedContent
|
||||||
postAdminHijackUserR cID = do
|
postAdminHijackUserR cID = do
|
||||||
|
|||||||
@ -135,7 +135,7 @@ guessUser (((Set.toList . toNullable) <$>) . Set.toList . dnfTerms -> criteria)
|
|||||||
ldapPool' <- getsYesod $ view _appLdapPool
|
ldapPool' <- getsYesod $ view _appLdapPool
|
||||||
fmap join . for ldapPool' $ \ldapPool -> do
|
fmap join . for ldapPool' $ \ldapPool -> do
|
||||||
ldapData <- campusUserMatr' ldapPool FailoverUnlimited userMatr
|
ldapData <- campusUserMatr' ldapPool FailoverUnlimited userMatr
|
||||||
for ldapData $ upsertCampusUser UpsertCampusUser
|
for ldapData $ upsertCampusUser UpsertCampusUserGuessUser
|
||||||
|
|
||||||
let
|
let
|
||||||
getTermMatr :: [PredLiteral GuessUserInfo] -> Maybe UserMatriculation
|
getTermMatr :: [PredLiteral GuessUserInfo] -> Maybe UserMatriculation
|
||||||
|
|||||||
@ -49,7 +49,7 @@ dispatchJobSynchroniseLdapUser jUser = JobHandlerException $ do
|
|||||||
|
|
||||||
reTestAfter <- getsYesod $ view _appLdapReTestFailover
|
reTestAfter <- getsYesod $ view _appLdapReTestFailover
|
||||||
ldapAttrs <- MaybeT $ campusUserReTest' ldapPool ((>= reTestAfter) . realToFrac) FailoverUnlimited user
|
ldapAttrs <- MaybeT $ campusUserReTest' ldapPool ((>= reTestAfter) . realToFrac) FailoverUnlimited user
|
||||||
void . lift $ upsertCampusUser UpsertCampusUser ldapAttrs
|
void . lift $ upsertCampusUser (UpsertCampusUserLdapSync userIdent) ldapAttrs
|
||||||
Nothing ->
|
Nothing ->
|
||||||
throwM SynchroniseLdapNoLdap
|
throwM SynchroniseLdapNoLdap
|
||||||
where
|
where
|
||||||
|
|||||||
@ -106,7 +106,7 @@ dispatchHealthCheckLDAPAdmins = fmap HealthLDAPAdmins . yesodTimeout (^. _appHea
|
|||||||
Sum numResolved <- fmap fold . forM ldapAdminUsers $ \(CI.original -> adminIdent) ->
|
Sum numResolved <- fmap fold . forM ldapAdminUsers $ \(CI.original -> adminIdent) ->
|
||||||
let hCampusExc :: CampusUserException -> Handler (Sum Integer)
|
let hCampusExc :: CampusUserException -> Handler (Sum Integer)
|
||||||
hCampusExc err = mempty <$ $logErrorS "healthCheckLDAPAdmins" (adminIdent <> ": " <> tshow err)
|
hCampusExc err = mempty <$ $logErrorS "healthCheckLDAPAdmins" (adminIdent <> ": " <> tshow err)
|
||||||
in handle hCampusExc $ Sum 1 <$ campusUserReTest ldapPool ((>= reTestAfter) . realToFrac) FailoverUnlimited (Creds "LDAP" adminIdent [])
|
in handle hCampusExc $ Sum 1 <$ campusUserReTest ldapPool ((>= reTestAfter) . realToFrac) FailoverUnlimited (Creds apLdap adminIdent [])
|
||||||
return $ numResolved % numAdmins
|
return $ numResolved % numAdmins
|
||||||
_other -> return Nothing
|
_other -> return Nothing
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user