chore(model)!: separate user authentication data from User table; add ExternalAuth and InternalAuth models
This commit is contained in:
parent
2e47df00b9
commit
54f2430b3e
@ -13,13 +13,11 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
User json -- Each Uni2work user has a corresponding row in this table; created upon first login.
|
User json -- Each Uni2work user has a corresponding row in this table; created upon first login.
|
||||||
|
ident UserIdent -- Case-insensitive user-identifier
|
||||||
surname UserSurname -- Display user names always through 'nameWidget displayName surname'
|
surname UserSurname -- Display user names always through 'nameWidget displayName surname'
|
||||||
displayName UserDisplayName
|
displayName UserDisplayName
|
||||||
displayEmail UserEmail
|
displayEmail UserEmail
|
||||||
email UserEmail -- Case-insensitive eMail address, used for sending TODO: make this nullable
|
email UserEmail -- Case-insensitive eMail address, used for sending TODO: make this nullable
|
||||||
ident UserIdent -- Case-insensitive user-identifier
|
|
||||||
authentication AuthenticationMode -- 'AuthLDAP' or ('AuthPWHash'+password-hash) -- TODO: redo (add InternalUser table for password hash)
|
|
||||||
lastAuthentication UTCTime Maybe -- last login date
|
|
||||||
created UTCTime default=now()
|
created UTCTime default=now()
|
||||||
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!
|
||||||
@ -49,18 +47,33 @@ User json -- Each Uni2work user has a corresponding row in this table; create
|
|||||||
prefersPostal Bool default=false -- user prefers letters by post instead of email
|
prefersPostal Bool default=false -- user prefers letters by post instead of email
|
||||||
examOfficeGetSynced Bool default=true -- whether synced status should be displayed for exam results by default
|
examOfficeGetSynced Bool default=true -- whether synced status should be displayed for exam results by default
|
||||||
examOfficeGetLabels Bool default=true -- whether labels should be displayed for exam results by default
|
examOfficeGetLabels Bool default=true -- whether labels should be displayed for exam results by default
|
||||||
UniqueAuthentication ident -- Column 'ident' can be used as a row-key in this table
|
UniqueUser ident -- Column 'ident' can be used as a row-key in this table
|
||||||
UniqueEmail email -- Column 'email' can be used as a row-key in this table
|
UniqueEmail email -- Column 'email' can be used as a row-key in this table
|
||||||
deriving Show Eq Ord Generic -- Haskell-specific settings for runtime-value representing a row in memory
|
deriving Show Eq Ord Generic -- Haskell-specific settings for runtime-value representing a row in memory
|
||||||
|
|
||||||
-- User authentication data fetched from external sources
|
-- | User authentication data, source-agnostic data
|
||||||
ExternalUser
|
UserAuth
|
||||||
source Text -- External source ID
|
ident UserIdent -- Human-readable text uniquely identifying a user
|
||||||
ident UserIdent -- External user ID
|
lastLogin UTCTime -- When did the corresponding User last authenticate using this entry?
|
||||||
data Value "default='{}'::jsonb" -- Raw user data from external source
|
Primary ident
|
||||||
lastSourceSync UTCTime -- When was the entry last synced with the external source?
|
UniqueAuthentication ident
|
||||||
lastUserSync UTCTime Maybe -- When was the corresponding User entry last synced with this entry? TODO: maybe move to User instead
|
deriving Show Eq Ord Generic
|
||||||
UniqueExternalUser source ident
|
|
||||||
|
-- | User authentication data fetched from external user sources
|
||||||
|
ExternalAuth
|
||||||
|
ident UserIdent
|
||||||
|
source AuthenticationSourceIdent -- Identifier of the external source in the config
|
||||||
|
data Value "default='{}'::jsonb" -- Raw user data from external source
|
||||||
|
lastSync UTCTime -- When was the corresponding User entry last synced with this external source?
|
||||||
|
UniqueExternalAuth ident source -- At most one entry of this user per source
|
||||||
|
deriving Show Eq Ord Generic
|
||||||
|
|
||||||
|
-- | FraDrive-specific user authentication data, internal logins have precedence over external authentication
|
||||||
|
InternalAuth
|
||||||
|
ident UserIdent
|
||||||
|
hash Text -- Hashed password
|
||||||
|
Primary ident
|
||||||
|
UniqueInternalAuth ident
|
||||||
deriving Show Eq Ord Generic
|
deriving Show Eq Ord Generic
|
||||||
|
|
||||||
UserFunction -- Administratively assigned functions (lecturer, admin, evaluation, ...)
|
UserFunction -- Administratively assigned functions (lecturer, admin, evaluation, ...)
|
||||||
|
|||||||
@ -15,61 +15,51 @@ module Model.Types.Auth
|
|||||||
|
|
||||||
import ClassyPrelude.Yesod hiding (derivePersistFieldJSON, Proxy(..))
|
import ClassyPrelude.Yesod hiding (derivePersistFieldJSON, Proxy(..))
|
||||||
|
|
||||||
import Utils
|
|
||||||
|
|
||||||
import Data.Aeson
|
|
||||||
import Data.Aeson.TH
|
|
||||||
import Model.Types.TH.JSON
|
import Model.Types.TH.JSON
|
||||||
import Data.Universe
|
import Model.Types.TH.PathPiece
|
||||||
import Data.Universe.Instances.Reverse ()
|
|
||||||
import Data.Proxy
|
import Utils
|
||||||
import Data.Data (Data)
|
import Utils.Lens.TH
|
||||||
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
import qualified Data.Set as Set
|
import Data.Aeson
|
||||||
|
import Data.Aeson.TH
|
||||||
import qualified Data.Text as Text
|
|
||||||
|
|
||||||
import qualified Data.HashMap.Strict as HashMap
|
|
||||||
|
|
||||||
import qualified Data.Aeson.Types as Aeson
|
import qualified Data.Aeson.Types as Aeson
|
||||||
|
import qualified Data.Binary as Binary
|
||||||
import Data.CaseInsensitive (CI)
|
import Data.Binary (Binary)
|
||||||
|
import Data.Binary.Instances.UnorderedContainers ()
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
|
import Data.CaseInsensitive (CI)
|
||||||
import Data.CaseInsensitive.Instances ()
|
import Data.CaseInsensitive.Instances ()
|
||||||
|
import Data.Data (Data)
|
||||||
import Data.Set.Instances ()
|
import qualified Data.HashMap.Strict as HashMap
|
||||||
import Data.NonNull.Instances ()
|
import Data.NonNull.Instances ()
|
||||||
|
import Data.Proxy
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
import Data.Set.Instances ()
|
||||||
|
import qualified Data.Text as Text
|
||||||
|
import Data.Universe
|
||||||
|
import Data.Universe.Instances.Reverse ()
|
||||||
import Data.Universe.Instances.Reverse.MonoTraversable ()
|
import Data.Universe.Instances.Reverse.MonoTraversable ()
|
||||||
|
|
||||||
import Model.Types.TH.PathPiece
|
|
||||||
import Database.Persist.Sql
|
import Database.Persist.Sql
|
||||||
|
|
||||||
import Servant.Docs (ToSample(..), samples)
|
import Servant.Docs (ToSample(..), samples)
|
||||||
import Utils.Lens.TH
|
|
||||||
|
|
||||||
import Data.Binary (Binary)
|
|
||||||
import qualified Data.Binary as Binary
|
|
||||||
import Data.Binary.Instances.UnorderedContainers ()
|
|
||||||
|
|
||||||
|
|
||||||
data AuthenticationMode = AuthLDAP
|
-- | Supported protocols for external user sources used for authentication queries
|
||||||
| AuthAzure
|
data AuthenticationProtocol
|
||||||
| AuthPWHash { authPWHash :: Text }
|
= AuthAzure -- ^ Azure ADv2 (OAuth2)
|
||||||
| AuthNoLogin
|
| AuthLdap -- ^ LDAP
|
||||||
deriving (Eq, Ord, Read, Show, Generic)
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Data, Generic)
|
||||||
|
deriving anyclass (Universe, Finite, Hashable, NFData)
|
||||||
|
|
||||||
instance Hashable AuthenticationMode
|
nullaryPathPiece ''AuthenticationProtocol $ camelToPathPiece' 1
|
||||||
instance NFData AuthenticationMode
|
pathPieceJSON ''AuthenticationProtocol
|
||||||
|
|
||||||
deriveJSON defaultOptions
|
|
||||||
{ constructorTagModifier = camelToPathPiece' 1
|
|
||||||
, fieldLabelModifier = camelToPathPiece' 1
|
|
||||||
, sumEncoding = UntaggedValue
|
|
||||||
} ''AuthenticationMode
|
|
||||||
|
|
||||||
derivePersistFieldJSON ''AuthenticationMode
|
type AuthenticationSourceIdent = Text
|
||||||
|
|
||||||
|
|
||||||
data AuthTag -- sortiert nach gewünschter Reihenfolge auf /authpreds, d.h. Prädikate sind sortier nach Relevanz für Benutzer
|
data AuthTag -- sortiert nach gewünschter Reihenfolge auf /authpreds, d.h. Prädikate sind sortier nach Relevanz für Benutzer
|
||||||
@ -106,8 +96,8 @@ data AuthTag -- sortiert nach gewünschter Reihenfolge auf /authpreds, d.h. Prä
|
|||||||
| AuthRegisterGroup
|
| AuthRegisterGroup
|
||||||
| AuthEmpty
|
| AuthEmpty
|
||||||
| AuthSelf
|
| AuthSelf
|
||||||
| AuthIsLDAP
|
| AuthIsExternal -- TODO: maybe distinguish between AuthenticationProtocols
|
||||||
| AuthIsPWHash
|
| AuthIsInternal
|
||||||
| AuthAuthentication
|
| AuthAuthentication
|
||||||
| AuthNoEscalation
|
| AuthNoEscalation
|
||||||
| AuthRead
|
| AuthRead
|
||||||
|
|||||||
Reference in New Issue
Block a user