82 lines
2.8 KiB
Haskell
82 lines
2.8 KiB
Haskell
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>
|
|
--
|
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
module Model.Tokens.Session
|
|
( SessionToken(..)
|
|
, _sessionIdentifier, _sessionId, _sessionIssuedBy, _sessionIssuedAt, _sessionExpiresAt, _sessionStartsAt
|
|
) where
|
|
|
|
import ClassyPrelude.Yesod
|
|
|
|
import Model.Tokens.Lens
|
|
import Model
|
|
import Utils.Lens
|
|
|
|
import Web.ServerSession.Core
|
|
|
|
import Jose.Jwt (IntDate(..))
|
|
import qualified Jose.Jwt as Jose
|
|
|
|
import Data.Time.Clock.POSIX
|
|
|
|
import Control.Monad.Fail
|
|
|
|
|
|
data SessionToken sess = SessionToken
|
|
{ sessionIdentifier :: TokenId
|
|
, sessionId :: SessionId sess
|
|
, sessionIssuedAt :: UTCTime
|
|
, sessionIssuedBy :: InstanceId
|
|
, sessionIssuedFor :: ClusterId
|
|
, sessionExpiresAt
|
|
, sessionStartsAt :: Maybe UTCTime
|
|
} deriving (Eq, Ord, Read, Show, Generic)
|
|
|
|
makeLenses_ ''SessionToken
|
|
instance HasTokenIdentifier (SessionToken sess) TokenId where
|
|
_tokenIdentifier = _sessionIdentifier
|
|
instance HasTokenIssuedBy (SessionToken sess) InstanceId where
|
|
_tokenIssuedBy = _sessionIssuedBy
|
|
instance HasTokenIssuedFor (SessionToken sess) ClusterId where
|
|
_tokenIssuedFor = _sessionIssuedFor
|
|
instance HasTokenIssuedAt (SessionToken sess) UTCTime where
|
|
_tokenIssuedAt = _sessionIssuedAt
|
|
instance HasTokenExpiresAt (SessionToken sess) (Maybe UTCTime) where
|
|
_tokenExpiresAt = _sessionExpiresAt
|
|
instance HasTokenStartsAt (SessionToken sess) (Maybe UTCTime) where
|
|
_tokenStartsAt = _sessionStartsAt
|
|
|
|
instance ToJSON (SessionToken sess) where
|
|
toJSON SessionToken{..} = toJSON Jose.JwtClaims{..}
|
|
where jwtIss = Just $ toPathPiece sessionIssuedBy
|
|
jwtSub = Just $ toPathPiece sessionId
|
|
jwtAud = Just . pure $ toPathPiece sessionIssuedFor
|
|
jwtExp = IntDate . utcTimeToPOSIXSeconds <$> sessionExpiresAt
|
|
jwtNbf = IntDate . utcTimeToPOSIXSeconds <$> sessionStartsAt
|
|
jwtIat = Just . IntDate $ utcTimeToPOSIXSeconds sessionIssuedAt
|
|
jwtJti = Just $ toPathPiece sessionIdentifier
|
|
|
|
instance FromJSON (SessionToken sess) where
|
|
parseJSON val = do
|
|
Jose.JwtClaims{..} <- parseJSON val
|
|
|
|
sessionIdentifier <- parseMaybe "sessionIdentfier" $
|
|
fromPathPiece =<< jwtJti
|
|
sessionId <- parseMaybe "sessionId" $
|
|
fromPathPiece =<< jwtSub
|
|
sessionIssuedAt <- parseMaybe "sessionIssuedAt" $
|
|
unIntDate <$> jwtIat
|
|
sessionIssuedBy <- parseMaybe "sessionIssuedBy" $
|
|
fromPathPiece =<< jwtIss
|
|
sessionIssuedFor <- parseMaybe "sessionIssuedFor" $ do
|
|
[aud] <- jwtAud
|
|
fromPathPiece aud
|
|
let sessionExpiresAt = unIntDate <$> jwtExp
|
|
sessionStartsAt = unIntDate <$> jwtNbf
|
|
|
|
return SessionToken{..}
|
|
where
|
|
parseMaybe errId = maybe (fail $ "Could not parse " <> errId) return
|
|
unIntDate (IntDate posix) = posixSecondsToUTCTime posix
|