prodapi-userauth-0.1.0.0: src/Prod/UserAuth/Runtime.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE StrictData #-}
module Prod.UserAuth.Runtime (
Counters (..),
initRuntime,
Runtime,
AugmentSession,
augmentSession,
AugmentWhoAmI,
augmentWhoAmI,
augmentLoggedInCookieClaims,
AugmentCookieClaims,
counters,
secretstring,
baseClaimsSet,
withConn,
Connection,
tokenValidityDuration,
trace,
traceTransaction,
traceAttempt,
traceVerification,
traceOptionalVerification,
traceRegistration,
traceRecoveryRequest,
traceRecoveryApplication,
traceAllowed,
traceDisallowed,
traceLimited,
traceJWT,
traceJWTSigned,
traceAugmentCookie,
)
where
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Aeson (Value)
import Data.ByteString (ByteString)
import Data.Text (Text)
import Database.PostgreSQL.Simple (Connection, Only (..), close, connectPostgreSQL, execute, query, rollback, withTransaction)
import Prod.Tracer (Tracer (..))
import Prod.UserAuth.Base (ApplyRecoveryRequest, ErrorMessage, LoggedInCookie, LoginAttempt, LoginResult, Minutes, RecoveryRequest, RecoveryRequestNotification, RecoveryResult, RegistrationRequest, RegistrationResult, SessionData, UserId, WhoAmI)
import Prod.UserAuth.Counters (Counters (..), initCounters)
import Prod.UserAuth.Trace (BackendTrack (..), BehaviourTrack (..), CallbackTrack (..), JwtTrack (..), Track (..))
import Web.JWT
data Runtime info
= Runtime
{ counters :: !Counters
, secretstring :: !Text
, baseClaimsSet :: !JWTClaimsSet
, connstring :: !ByteString
, augmentSession :: AugmentSession info
, augmentWhoAmI :: AugmentWhoAmI info
, augmentLoggedInCookieClaims :: AugmentCookieClaims
, tracer :: Tracer IO (Track info)
}
type AugmentSession info = Connection -> SessionData () -> IO (Maybe info)
type AugmentWhoAmI info = Connection -> WhoAmI UserId -> IO (Maybe info)
type AugmentCookieClaims = UserId -> IO (Either ErrorMessage [(Text, Value)])
trace :: (MonadIO m) => Runtime a -> Track a -> m ()
trace rt v = liftIO $ runTracer (tracer rt) $ v
initRuntime ::
Text ->
JWTClaimsSet ->
ByteString ->
AugmentSession info ->
AugmentWhoAmI info ->
AugmentCookieClaims ->
Tracer IO (Track info) ->
IO (Runtime info)
initRuntime skret claims cstring augSession augWhoAmI augCookie tracer =
Runtime
<$> initCounters
<*> pure skret
<*> pure claims
<*> pure cstring
<*> pure augSession
<*> pure augWhoAmI
<*> pure augCookie
<*> pure tracer
withConn :: Runtime b -> (Connection -> IO a) -> IO a
withConn runtime act = do
conn <- connectPostgreSQL (connstring runtime)
trace runtime (Backend SQLConnect)
!ret <- act conn
close conn
pure ret
traceTransaction :: Runtime a -> Connection -> IO b -> IO b
traceTransaction runtime conn act =
withTransaction conn $ do
trace runtime (Backend SQLTransaction)
act
traceAttempt :: (MonadIO m) => Runtime a -> LoginAttempt -> LoginResult a -> m ()
traceAttempt runtime l r =
liftIO $ trace runtime $ Behaviour $ Attempt l r
traceVerification :: (MonadIO m) => Runtime a -> Bool -> m ()
traceVerification runtime bool =
liftIO $ trace runtime $ Behaviour $ Verification bool
traceOptionalVerification :: (MonadIO m) => Runtime a -> Bool -> m ()
traceOptionalVerification runtime bool =
liftIO $ trace runtime $ Behaviour $ OptionalVerification bool
traceRegistration :: (MonadIO m) => Runtime a -> RegistrationRequest -> RegistrationResult a -> m ()
traceRegistration runtime req res =
liftIO $ trace runtime $ Behaviour $ Registration req res
traceRecoveryRequest :: (MonadIO m) => Runtime a -> RecoveryRequest -> RecoveryRequestNotification -> m ()
traceRecoveryRequest runtime req res =
liftIO $ trace runtime $ Behaviour $ Recovery req res
traceRecoveryApplication :: (MonadIO m) => Runtime a -> ApplyRecoveryRequest -> RecoveryResult -> m ()
traceRecoveryApplication runtime req res =
liftIO $ trace runtime $ Behaviour $ ApplyRecovery req res
traceAllowed, traceDisallowed, traceLimited :: (MonadIO m) => Runtime a -> m ()
traceAllowed runtime =
liftIO $ trace runtime $ Bearer $ Allowed (Just True)
traceDisallowed runtime =
liftIO $ trace runtime $ Bearer $ Allowed (Just False)
traceLimited runtime =
liftIO $ trace runtime $ Bearer $ Allowed Nothing
traceJWT :: (MonadIO m) => (Runtime a) -> Maybe (JWT (VerifiedJWT)) -> m ()
traceJWT runtime jwt =
liftIO $ trace runtime $ Bearer $ Extracted jwt
traceJWTSigned :: (MonadIO m) => (Runtime a) -> UserId -> [(Text, Value)] -> m ()
traceJWTSigned runtime uid claims =
liftIO $ trace runtime $ Bearer $ Signed uid claims
traceAugmentCookie :: (MonadIO m) => (Runtime a) -> Either ErrorMessage LoggedInCookie -> m ()
traceAugmentCookie runtime c =
liftIO $ trace runtime $ Callbacks $ AugmentCookie c
tokenValidityDuration :: Minutes
tokenValidityDuration = 30