data LoginRequest
= LoginRequest
{ loginUser :: Text,
LoginRequest <$> o .: "username" <*> o .: "password"
parseLoginRequest val = fail $ "Value " <> show val <> " is not a JSON object."
do
requireLoginWith (const throwChallenge)
do
req <- getRequest
rawHeader <- maybe (throwMissingAuth ()) pure $ getHeader "Authorization" req
(uname, pwd) <-
either (throwDenied . AU.AuthError) pure $
parseOnly authHeaderParser rawHeader
authResult <- with auth $ AU.loginByUsername uname (AU.ClearText pwd) False
either throwDenied pure authResult
do
requestBody <- readRequestBody 4096
credentials <-
case A.eitherDecode requestBody >>= A.parseEither parseLoginRequest of
Left _ -> snapError 400 $ "Unable to parse login credentials object."
Right creds -> pure creds
authResult <-
with auth $
AU.loginByUsername
(loginUser credentials)
(AU.ClearText (encodeUtf8 $ loginPass credentials))
False
either throwDenied pure authResult
do
currentUser <- with auth AU.currentUser
maybe
(requireLoginWith $ const (throwDenied $ AU.AuthError "Not Authenticated"))
pure
currentUser
do
currentUser <- UserName . AU.userLogin <$> requireUser
maybeT
(snapError 500 "Unable to retrieve user record for authenticated user")
(pure . (^. _1))
(mapMaybeT snapEval $ findUserByName currentUser)
do
modifyResponse $
(setResponseStatus 401 "Unauthorized")
. (setHeader "WWW-Authenticate" "Basic realm=aftok")
getResponse >>= finishWith
do
modifyResponse $ setResponseStatus 403 "Access Denied"
logError (encodeUtf8 $ "Access Denied: " <> show @Text failure)
getResponse >>= finishWith