diff options
author | William Carroll <wpcarro@gmail.com> | 2021-01-22T10·49+0000 |
---|---|---|
committer | William Carroll <wpcarro@gmail.com> | 2021-01-22T11·00+0000 |
commit | e326b0da45a948668f523d5f715660981a9874c2 (patch) | |
tree | 34c425b23d122aa63b3a15d97b08298ee1db00c7 /assessments/tt/src/Auth.hs | |
parent | 67e0f93b3bbc386421a276cbd5675f5ac51625ae (diff) | |
parent | ee8e75231cd9d3d4aa3ffbbfa0e3b8511712e1ee (diff) |
Add 'assessments/tt/' from commit 'ee8e75231cd9d3d4aa3ffbbfa0e3b8511712e1ee'
git-subtree-dir: assessments/tt git-subtree-mainline: 67e0f93b3bbc386421a276cbd5675f5ac51625ae git-subtree-split: ee8e75231cd9d3d4aa3ffbbfa0e3b8511712e1ee
Diffstat (limited to 'assessments/tt/src/Auth.hs')
-rw-r--r-- | assessments/tt/src/Auth.hs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/assessments/tt/src/Auth.hs b/assessments/tt/src/Auth.hs new file mode 100644 index 000000000000..f1bff23257e0 --- /dev/null +++ b/assessments/tt/src/Auth.hs @@ -0,0 +1,64 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +-------------------------------------------------------------------------------- +module Auth where +-------------------------------------------------------------------------------- +import Control.Monad.IO.Class (liftIO) +import Web.Cookie +import Servant + +import qualified Data.UUID as UUID +import qualified Sessions as Sessions +import qualified Accounts as Accounts +import qualified Types as T +-------------------------------------------------------------------------------- + +-- | Return the UUID from a Session cookie. +uuidFromCookie :: T.SessionCookie -> Maybe T.SessionUUID +uuidFromCookie (T.SessionCookie cookies) = do + auth <- lookup "auth" cookies + uuid <- UUID.fromASCIIBytes auth + pure $ T.SessionUUID uuid + +-- | Attempt to return the account associated with `cookie`. +accountFromCookie :: FilePath -> T.SessionCookie -> IO (Maybe T.Account) +accountFromCookie dbFile cookie = + case uuidFromCookie cookie of + Nothing -> pure Nothing + Just uuid -> do + mSession <- Sessions.get dbFile uuid + case mSession of + Nothing -> pure Nothing + Just T.StoredSession{..} -> do + mAccount <- Accounts.lookup dbFile storedSessionUsername + case mAccount of + Nothing -> pure Nothing + Just x -> pure (Just x) + +-- | Create a new session cookie. +mkCookie :: T.SessionUUID -> SetCookie +mkCookie (T.SessionUUID uuid) = + defaultSetCookie + { setCookieName = "auth" + , setCookieValue = UUID.toASCIIBytes uuid + } + +-- | Use this to clear out the session cookie. +emptyCookie :: SetCookie +emptyCookie = + defaultSetCookie + { setCookieName = "auth" + , setCookieValue = "" + } + +-- | Throw a 401 error if the `predicate` fails. +assert :: FilePath -> T.SessionCookie -> (T.Account -> Bool) -> Handler a -> Handler a +assert dbFile cookie predicate handler = do + mRole <- liftIO $ accountFromCookie dbFile cookie + case mRole of + Nothing -> throwError err401 { errBody = "Missing valid session cookie" } + Just account -> + if predicate account then + handler + else + throwError err401 { errBody = "You are not authorized to access this resource" } |