refactor(avs): rework fraport email recognition
This commit is contained in:
parent
890f8ad8b6
commit
234dd28f48
@ -21,7 +21,7 @@ User json -- Each Uni2work user has a corresponding row in this table; create
|
|||||||
lastAuthentication UTCTime Maybe -- last login date
|
lastAuthentication UTCTime Maybe -- last login date
|
||||||
created UTCTime default=now()
|
created UTCTime default=now()
|
||||||
lastLdapSynchronisation UTCTime Maybe
|
lastLdapSynchronisation UTCTime Maybe
|
||||||
ldapPrimaryKey UserEduPersonPrincipalName Maybe
|
ldapPrimaryKey UserEduPersonPrincipalName Maybe -- Fraport Personnel Number or Email-Prefix for @fraport.de work here
|
||||||
tokensIssuedAfter UTCTime Maybe -- do not accept bearer tokens issued before this time (accept all tokens if null)
|
tokensIssuedAfter UTCTime Maybe -- do not accept bearer tokens issued before this time (accept all tokens if null)
|
||||||
matrikelnummer UserMatriculation Maybe -- usually a number; AVS Personalnummer; nicht Fraport Personalnummer!
|
matrikelnummer UserMatriculation Maybe -- usually a number; AVS Personalnummer; nicht Fraport Personalnummer!
|
||||||
firstName Text -- For export in tables, pre-split firstName from displayName
|
firstName Text -- For export in tables, pre-split firstName from displayName
|
||||||
|
|||||||
@ -672,7 +672,7 @@ createAvsUserById api = do
|
|||||||
return $ seq userCompId $ seq userAvsId uid
|
return $ seq userCompId $ seq userAvsId uid
|
||||||
|
|
||||||
|
|
||||||
|
-- | upsert superior by eMail through LDAP only (currently no email search available in AVS)
|
||||||
repsertSuperiorSupervisor :: Maybe CompanyId -> AvsFirmInfo -> UserId -> DB ()
|
repsertSuperiorSupervisor :: Maybe CompanyId -> AvsFirmInfo -> UserId -> DB ()
|
||||||
repsertSuperiorSupervisor cid afi uid =
|
repsertSuperiorSupervisor cid afi uid =
|
||||||
whenIsJust (afi ^. _avsFirmEMailSuperior) $ \supemail -> forMM_
|
whenIsJust (afi ^. _avsFirmEMailSuperior) $ \supemail -> forMM_
|
||||||
@ -762,7 +762,7 @@ guessAvsUser someid = do
|
|||||||
other -> do -- attempt to recover by trying other ids
|
other -> do -- attempt to recover by trying other ids
|
||||||
whenIsLeft other (\(err::SomeException) -> $logInfoS "AVS" $ "upsertAvsUser LDAP error " <> tshow err) -- this line primarily forces exception type to catch-all
|
whenIsLeft other (\(err::SomeException) -> $logInfoS "AVS" $ "upsertAvsUser LDAP error " <> tshow err) -- this line primarily forces exception type to catch-all
|
||||||
runDB . runMaybeT $
|
runDB . runMaybeT $
|
||||||
let someIdent = stripCI someid
|
let someIdent = stripCI someid -- also see Handler.Utils.guessUserByEmail for a similar function, this one is more lenient, since a unique email is acceptable, even it would not be unique as DisplayEmail
|
||||||
in MaybeT (getKeyBy $ UniqueEmail someIdent) -- recall that monadic actions are only executed until first success here
|
in MaybeT (getKeyBy $ UniqueEmail someIdent) -- recall that monadic actions are only executed until first success here
|
||||||
<|> MaybeT (getKeyBy $ UniqueAuthentication someIdent)
|
<|> MaybeT (getKeyBy $ UniqueAuthentication someIdent)
|
||||||
<|> MaybeT (getKeyByFilter [UserDisplayEmail ==. someIdent])
|
<|> MaybeT (getKeyByFilter [UserDisplayEmail ==. someIdent])
|
||||||
|
|||||||
@ -201,17 +201,13 @@ computeUserAuthenticationDigest :: AuthenticationMode -> Digest SHA3_256
|
|||||||
computeUserAuthenticationDigest = hashlazy . JSON.encode
|
computeUserAuthenticationDigest = hashlazy . JSON.encode
|
||||||
|
|
||||||
guessUserByEmail :: UserEmail -> DB (Maybe UserId)
|
guessUserByEmail :: UserEmail -> DB (Maybe UserId)
|
||||||
guessUserByEmail eml = listToMaybe <$> selectKeysList
|
guessUserByEmail eml = getKeyByFilter $ ofoldl1Ex' (||.) $
|
||||||
(ofoldl1Ex' (||.)
|
mcons (getFraportLogin (CI.original eml) <&> (\lgi ->
|
||||||
[ [UserDisplayEmail ==. eml]
|
[UserLdapPrimaryKey ==. Just lgi])) -- Note that we must exclude `==. Nothing` here!
|
||||||
, [UserEmail ==. eml]
|
[ [UserDisplayEmail ==. eml]
|
||||||
, [UserIdent ==. eml]
|
, [UserEmail ==. eml]
|
||||||
-- , [UserLdapPrimaryKey ==. Text.stripSuffix "@fraport.de" $ CI.foldedCase eml]
|
, [UserIdent ==. eml]
|
||||||
]
|
]
|
||||||
)
|
|
||||||
[ Asc UserEmail -- Unique, to ensure reproducable results
|
|
||||||
, LimitTo 1
|
|
||||||
]
|
|
||||||
|
|
||||||
data GuessUserInfo
|
data GuessUserInfo
|
||||||
= GuessUserMatrikelnummer
|
= GuessUserMatrikelnummer
|
||||||
|
|||||||
@ -1039,6 +1039,14 @@ altM ma mb = ma >>= \case
|
|||||||
Nothing -> mb
|
Nothing -> mb
|
||||||
res -> return res
|
res -> return res
|
||||||
|
|
||||||
|
-- | Map f and get the first Just
|
||||||
|
firstJust :: MonoFoldable mono => (Element mono -> Maybe a) -> mono -> Maybe a
|
||||||
|
firstJust f = foldr go Nothing
|
||||||
|
where
|
||||||
|
-- go :: a -> Maybe b -> Maybe b
|
||||||
|
go x Nothing = f x
|
||||||
|
go _ res = res
|
||||||
|
|
||||||
-- Takes computations returnings @Maybe@; tries each one in order.
|
-- Takes computations returnings @Maybe@; tries each one in order.
|
||||||
-- The first one to return a @Just@ wins. Returns @Nothing@ if all computations
|
-- The first one to return a @Just@ wins. Returns @Nothing@ if all computations
|
||||||
-- return @Nothing@.
|
-- return @Nothing@.
|
||||||
|
|||||||
@ -13,12 +13,29 @@ import qualified Data.CaseInsensitive as CI
|
|||||||
|
|
||||||
import qualified Text.Email.Validate as Email
|
import qualified Text.Email.Validate as Email
|
||||||
|
|
||||||
|
-- | domains used by LDAP accounts
|
||||||
|
fraportMailDomains :: [Text]
|
||||||
|
fraportMailDomains = ["@fraport.de"] -- <&> foldCase only!
|
||||||
|
|
||||||
|
-- | returns the part before the @ symbol of an email address that ends with a fraport domain, preserving case
|
||||||
|
-- eg. getFraportLogin "E1234@fraport.de" == Just "E1234"
|
||||||
|
-- getFraportLogin "S.Guy@fraport.de" == Just "S.Guy"
|
||||||
|
-- getFraportLogin "S.Guy@elsewhere.com" == Nothing
|
||||||
|
-- Use CI.traverse getFraportLogin :: CI Text -> Maybe (CI Text)
|
||||||
|
-- CI.traverse getFraportLogin "S.Jost@Fraport.de" == Just "S.Jost"
|
||||||
|
getFraportLogin :: Text -> Maybe Text
|
||||||
|
getFraportLogin email = orgCase <$> lowerCaseLogin
|
||||||
|
where
|
||||||
|
orgCase = flip Text.take email . Text.length
|
||||||
|
lowerCaseLogin = firstJust (flip Text.stripSuffix $ foldCase email) fraportMailDomains
|
||||||
|
|
||||||
|
-- | check that an email is valid and that it is not an E-account that nobody reads
|
||||||
-- also see `Handler.Utils.Users.getUserEmail` for Tests accepting User Type
|
-- also see `Handler.Utils.Users.getUserEmail` for Tests accepting User Type
|
||||||
validEmail :: Text -> Bool -- Email = Text
|
validEmail :: Text -> Bool -- Email = Text
|
||||||
validEmail email = validRFC5322 && not invalidFraport
|
validEmail email = validRFC5322 && not invalidFraport
|
||||||
where
|
where
|
||||||
validRFC5322 = Email.isValid $ encodeUtf8 email
|
validRFC5322 = Email.isValid $ encodeUtf8 email
|
||||||
invalidFraport = case Text.stripSuffix "@fraport.de" (foldCase email) of
|
invalidFraport = case getFraportLogin email of
|
||||||
Just fralogin -> Text.all Char.isDigit $ Text.drop 1 fralogin -- Emails like E1234@fraport.de or 012345!fraport.de are not read
|
Just fralogin -> Text.all Char.isDigit $ Text.drop 1 fralogin -- Emails like E1234@fraport.de or 012345!fraport.de are not read
|
||||||
Nothing -> False
|
Nothing -> False
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user