chore: user sources

This commit is contained in:
Sarah Vaupel 2024-01-28 18:06:30 +01:00
parent e9bbeffd7e
commit d4a3459adf
5 changed files with 45 additions and 44 deletions

View File

@ -128,9 +128,9 @@ database:
auto-db-migrate: '_env:AUTO_DB_MIGRATE:true' auto-db-migrate: '_env:AUTO_DB_MIGRATE:true'
# External databases used for authentication and userdata lookups # External sources used for authentication and userdata lookups
user-database: user-source:
mode: single-source # mode: single-source
protocol: azureadv2 protocol: azureadv2
config: config:
client-id: "_env:AZURECLIENTID:00000000-0000-0000-0000-000000000000" client-id: "_env:AZURECLIENTID:00000000-0000-0000-0000-000000000000"
@ -149,14 +149,15 @@ user-database:
# timeout: "_env:LDAPTIMEOUT:5" # timeout: "_env:LDAPTIMEOUT:5"
# search-timeout: "_env:LDAPSEARCHTIME:5" # search-timeout: "_env:LDAPSEARCHTIME:5"
# TODO: might move later
ldap-pool: ldap-pool:
stripes: "_env:LDAPSTRIPES:1" stripes: "_env:LDAPSTRIPES:1"
timeout: "_env:LDAPTIMEOUT:20" timeout: "_env:LDAPTIMEOUT:20"
limit: "_env:LDAPLIMIT:10" limit: "_env:LDAPLIMIT:10"
# userdb-retest-failover: 60 # user-retest-failover: 60
userdb-sync-within: "_env:USERDB_SYNC_WITHIN:1209600" # 14 Tage in Sekunden user-sync-within: "_env:USER_SYNC_WITHIN:1209600" # 14 Tage in Sekunden
userdb-sync-interval: "_env:USERDB_SYNC_INTERVAL:3600" # jede Stunde user-sync-interval: "_env:USER_SYNC_INTERVAL:3600" # jede Stunde
lms-direct: lms-direct:
upload-header: "_env:LMSUPLOADHEADER:true" upload-header: "_env:LMSUPLOADHEADER:true"

View File

@ -246,7 +246,7 @@ makeFoundation appSettings''@AppSettings{..} = do
(error "appSettings' forced in tempFoundation") (error "appSettings' forced in tempFoundation")
(error "connPool forced in tempFoundation") (error "connPool forced in tempFoundation")
(error "smtpPool forced in tempFoundation") (error "smtpPool forced in tempFoundation")
(error "userdbPool forced in tempFoundation") (error "ldapPool forced in tempFoundation")
(error "cryptoIDKey forced in tempFoundation") (error "cryptoIDKey forced in tempFoundation")
(error "sessionStore forced in tempFoundation") (error "sessionStore forced in tempFoundation")
(error "secretBoxKey forced in tempFoundation") (error "secretBoxKey forced in tempFoundation")
@ -314,8 +314,8 @@ makeFoundation appSettings''@AppSettings{..} = do
-- TODO: reintroduce failover once UserDbFailover is implemented (see above) -- TODO: reintroduce failover once UserDbFailover is implemented (see above)
ldapPool <- forOf (traverse . traverse) appLdapPoolConf $ \RessourcePoolConf{..} -> if ldapPool <- forOf (traverse . traverse) appLdapPoolConf $ \RessourcePoolConf{..} -> if
| UserDbSingleSource{..} <- appUserDbConf | UserSourceConfSingleSource{..} <- appUserSourceConf
, UserDbLdap LdapConf{..} <- userdbSingleSource , UserSourceLdap LdapConf{..} <- usersrcSingleSource
-> do -- set up a singleton ldap pool with no failover -> do -- set up a singleton ldap pool with no failover
let ldapLabel = case ldapHost of let ldapLabel = case ldapHost of
Ldap.Plain str -> pack str <> ":" <> tshow ldapPort Ldap.Plain str -> pack str <> ":" <> tshow ldapPort
@ -421,7 +421,7 @@ makeFoundation appSettings''@AppSettings{..} = do
$logDebugS "Runtime configuration" $ tshowCrop appSettings' $logDebugS "Runtime configuration" $ tshowCrop appSettings'
-- TODO: reimplement user db failover -- TODO: reimplement user db failover
let foundation = mkFoundation appSettings' sqlPool smtpPool userdbPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery let foundation = mkFoundation appSettings' sqlPool smtpPool ldapPool appCryptoIDKey appSessionStore appSecretBoxKey appWidgetMemcached appJSONWebKeySet appClusterID appMemcached appMemcachedLocal appUploadCache appVerpSecret appAuthKey appAuthPlugins appPersonalisedSheetFilesSeedKey appVolatileClusterSettingsCache appAvsQuery
-- Return the foundation -- Return the foundation
$logInfoS "setup" "*** DONE ***" $logInfoS "setup" "*** DONE ***"

View File

@ -101,14 +101,14 @@ authenticate creds@Creds{..} = liftHandler . runDB . withReaderT projectBackend
$logDebugS "auth" $ tshow Creds{..} $logDebugS "auth" $ tshow Creds{..}
userdbConf <- getsYesod $ view _appUserDbConf userSourceConf <- getsYesod $ view _appUserSourceConf
flip catches excHandlers $ case userdbConf of flip catches excHandlers $ case userSourceConf of
UserDbSingleSource (UserDbAzureAdV2 azureConf) UserSourceConfSingleSource (UserSourceAzureAdV2 azureConf)
| Just upsertMode' <- upsertMode -> do | Just upsertMode' <- upsertMode -> do
azureData <- oauth2User azureConf Creds{..} azureData <- azureUser azureConf Creds{..}
$logDebugS "AuthAzure" $ "Successful Azure lookup: " <> tshow azureData $logDebugS "AuthAzure" $ "Successful Azure lookup: " <> tshow azureData
Authenticated . entityKey <$> upsertAzureUser upsertMode' azureData Authenticated . entityKey <$> upsertAzureUser upsertMode' azureData
UserDbSingleSource (UserDbLdap _) UserSourceConfSingleSource (UserSourceLdap _)
| Just upsertMode' <- upsertMode -> do | Just upsertMode' <- upsertMode -> do
-- TODO WIP -- TODO WIP
ldapPool <- fmap (fromMaybe $ error "No LDAP Pool") . getsYesod $ view _appLdapPool ldapPool <- fmap (fromMaybe $ error "No LDAP Pool") . getsYesod $ view _appLdapPool

View File

@ -45,8 +45,8 @@ dispatchJobSynchroniseUserdb numIterations epoch iteration
dispatchJobSynchroniseUserdbUser :: UserId -> JobHandler UniWorX dispatchJobSynchroniseUserdbUser :: UserId -> JobHandler UniWorX
dispatchJobSynchroniseUserdbUser jUser = JobHandlerException $ do dispatchJobSynchroniseUserdbUser jUser = JobHandlerException $ do
UniWorX{..} <- getYesod UniWorX{..} <- getYesod
case appUserDbConf of case appUserSourceConf of
UserDbSingleSource (UserDbLdap ldapConf) -> UserSourceConfSingleSource (UserSourceLdap ldapConf) ->
runDB . void . runMaybeT . handleExc $ do runDB . void . runMaybeT . handleExc $ do
user@User{userIdent,userLdapPrimaryKey} <- MaybeT $ get jUser user@User{userIdent,userLdapPrimaryKey} <- MaybeT $ get jUser
let upsertIdent = maybe userIdent CI.mk userLdapPrimaryKey let upsertIdent = maybe userIdent CI.mk userLdapPrimaryKey
@ -55,12 +55,12 @@ dispatchJobSynchroniseUserdbUser jUser = JobHandlerException $ do
-- ldapAttrs <- MaybeT $ campusUserReTest' ldapConf ((>= reTestAfter) . realToFrac) FailoverUnlimited user -- ldapAttrs <- MaybeT $ campusUserReTest' ldapConf ((>= reTestAfter) . realToFrac) FailoverUnlimited user
ldapAttrs <- MaybeT $ campusUserReTest' ldapConf ((>= reTestAfter) . realToFrac) FailoverUnlimited user ldapAttrs <- MaybeT $ campusUserReTest' ldapConf ((>= reTestAfter) . realToFrac) FailoverUnlimited user
void . lift $ upsertLdapUser (UpsertLdapUserLdapSync upsertIdent) ldapAttrs void . lift $ upsertLdapUser (UpsertLdapUserLdapSync upsertIdent) ldapAttrs
UserDbSingleSource (UserDbOAuth2 oauth2Conf) -> UserSourceConfSingleSource (UserSourceAzure azureConf) ->
runDB . void . runMaybeT . handleExc $ do runDB . void . runMaybeT . handleExc $ do
user@User{userIdent,userAzurePrimaryKey} <- MaybeT $ get jUser user@User{userIdent,userAzurePrimaryKey} <- MaybeT $ get jUser
let upsertIdent = maybe userIdent CI.mk userAzurePrimaryKey let upsertIdent = maybe userIdent CI.mk userAzurePrimaryKey
$logInfoS "SynchroniseUserdb" [st|Synchronising #{upsertIdent} with Azure|] $logInfoS "SynchroniseUserdb" [st|Synchronising #{upsertIdent} with Azure|]
void . lift $ upsertAzureUser (UpsertAzureUserSync upsertIdent) oauth2Conf void . lift $ upsertAzureUser (UpsertAzureUserSync upsertIdent) azureConf
where where
handleExc :: MaybeT DB a -> MaybeT DB a handleExc :: MaybeT DB a -> MaybeT DB a
handleExc handleExc

View File

@ -142,20 +142,20 @@ instance FromJSON PWHashConf where
return PWHashConf{..} return PWHashConf{..}
data UserDbConf' = UserDbLdap LdapConf | UserDbAzureAdV2 AzureConf data UserSource = UserSourceLdap LdapConf | UserSourceAzureAdV2 AzureConf
deriving (Show) deriving (Show)
data UserDbConf = data UserSourceConf =
UserDbSingleSource -- ^ use only one specific source UserSourceConfSingleSource -- ^ use only one specific source
{ userdbSingleSource :: UserDbConf' { usersrcSingleSource :: UserSource
} }
-- TODO: other modes yet to be implemented -- TODO: other modes yet to be implemented
-- | UserDbFailover -- ^ use only one user source at a time, but failover to the next-best database if the current source is unavailable -- | UserFailover -- ^ use only one user source at a time, but failover to the next-best database if the current source is unavailable
-- { userdbFailoverSources :: PointedList UserDbConf -- { usersrcFailoverSources :: PointedList UserSource
-- , userDbFailoverRetest :: NominalDiffTime -- , usersrcFailoverRetest :: NominalDiffTime
-- } -- }
-- | UserDbMultiSource -- ^ Multiple coequal user sources -- | UserMultiSource -- ^ Multiple coequal user sources
-- { userdbMultiSources :: Set UserDbConf -- { usersrcMultiSources :: Set UserSource
-- } -- }
deriving (Show) deriving (Show)
@ -309,21 +309,21 @@ pathPieceJSONKey ''SettingBotMitigation
makePrisms ''JobMode makePrisms ''JobMode
makeLenses_ ''JobMode makeLenses_ ''JobMode
makePrisms ''UserDbConf' makePrisms ''UserSource
makeLenses_ ''UserDbConf makeLenses_ ''UserSourceConf
makePrisms ''UserDbConf makePrisms ''UserSourceConf
deriveFromJSON defaultOptions deriveFromJSON defaultOptions
{ constructorTagModifier = toLower . dropPrefix "UserDb" { constructorTagModifier = toLower . dropPrefix "UserSource"
, sumEncoding = TaggedObject "protocol" "config" , sumEncoding = TaggedObject "protocol" "config"
} ''UserDbConf' } ''UserSource
deriveFromJSON defaultOptions deriveFromJSON defaultOptions
{ constructorTagModifier = camelToPathPiece' 1 { constructorTagModifier = camelToPathPiece' 3
, fieldLabelModifier = camelToPathPiece' 1 , fieldLabelModifier = camelToPathPiece' 1
, sumEncoding = TaggedObject "mode" "config" , sumEncoding = UntaggedValue -- TaggedObject "mode" "config"
, unwrapUnaryRecords = True , unwrapUnaryRecords = True
} ''UserDbConf } ''UserSourceConf
instance FromJSON HaskellNet.PortNumber where instance FromJSON HaskellNet.PortNumber where
parseJSON = withScientific "PortNumber" $ \sciNum -> case Scientific.toBoundedInteger sciNum of parseJSON = withScientific "PortNumber" $ \sciNum -> case Scientific.toBoundedInteger sciNum of
@ -451,7 +451,7 @@ data AppSettings = AppSettings
, appDatabaseConf :: PostgresConf , appDatabaseConf :: PostgresConf
-- ^ Configuration settings for accessing the database. -- ^ Configuration settings for accessing the database.
, appAutoDbMigrate :: Bool , appAutoDbMigrate :: Bool
, appUserDbConf :: UserDbConf , appUserSourceConf :: UserSourceConf
-- ^ Configuration settings for CSV export/import to LMS (= Learn Management System) -- ^ Configuration settings for CSV export/import to LMS (= Learn Management System)
, appLmsConf :: LmsConf , appLmsConf :: LmsConf
-- ^ Configuration settings for accessing the LDAP-directory -- ^ Configuration settings for accessing the LDAP-directory
@ -517,9 +517,9 @@ data AppSettings = AppSettings
, appHealthCheckHTTPReachableTimeout :: NominalDiffTime , appHealthCheckHTTPReachableTimeout :: NominalDiffTime
, appHealthCheckMatchingClusterConfigTimeout :: NominalDiffTime , appHealthCheckMatchingClusterConfigTimeout :: NominalDiffTime
-- , appUserdbRetestFailover :: DiffTime -- , appUserRetestFailover :: DiffTime
, appUserdbSyncWithin :: Maybe NominalDiffTime , appUserSyncWithin :: Maybe NominalDiffTime
, appUserdbSyncInterval :: NominalDiffTime , appUserSyncInterval :: NominalDiffTime
, appLdapPoolConf :: Maybe ResourcePoolConf , appLdapPoolConf :: Maybe ResourcePoolConf
@ -628,7 +628,7 @@ instance FromJSON AppSettings where
-- Ldap.Tls host _ -> not $ null host -- Ldap.Tls host _ -> not $ null host
-- Ldap.Plain host -> not $ null host -- Ldap.Plain host -> not $ null host
-- nonEmptyHost (UserDbOAuth2 OAuth2Conf{..}) = not $ or [ null oauth2TenantId, null oauth2ClientId, null oauth2ClientSecret ] -- nonEmptyHost (UserDbOAuth2 OAuth2Conf{..}) = not $ or [ null oauth2TenantId, null oauth2ClientId, null oauth2ClientSecret ]
appUserDbConf <- o .: "user-database" appUserSourceConf <- o .: "user-source"
-- P.fromList . mapMaybe (assertM nonEmptyHost) <$> o .:? "user-database" .!= [] -- P.fromList . mapMaybe (assertM nonEmptyHost) <$> o .:? "user-database" .!= []
appLdapPoolConf <- o .:? "ldap-pool" appLdapPoolConf <- o .:? "ldap-pool"
appLmsConf <- o .: "lms-direct" appLmsConf <- o .: "lms-direct"
@ -695,9 +695,9 @@ instance FromJSON AppSettings where
appSessionTimeout <- o .: "session-timeout" appSessionTimeout <- o .: "session-timeout"
-- appUserdbRetestFailover <- o .: "userdb-retest-failover" -- appUserRetestFailover <- o .: "userdb-retest-failover"
appUserdbSyncWithin <- o .:? "userdb-sync-within" appUserSyncWithin <- o .:? "user-sync-within"
appUserdbSyncInterval <- o .: "userdb-sync-interval" appUserSyncInterval <- o .: "user-sync-interval"
appSynchroniseAvsUsersWithin <- o .:? "synchronise-avs-users-within" appSynchroniseAvsUsersWithin <- o .:? "synchronise-avs-users-within"
appSynchroniseAvsUsersInterval <- o .: "synchronise-avs-users-interval" appSynchroniseAvsUsersInterval <- o .: "synchronise-avs-users-interval"