authIdentifier (automatic login redirection)
This commit is contained in:
parent
13d3444881
commit
4087573088
@ -16,9 +16,9 @@
|
|||||||
module Yesod.Helpers.Auth
|
module Yesod.Helpers.Auth
|
||||||
( authHandler
|
( authHandler
|
||||||
, YesodAuth (..)
|
, YesodAuth (..)
|
||||||
|
, authIdentifier
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Hack
|
|
||||||
import Web.Encodings
|
import Web.Encodings
|
||||||
import qualified Web.Authenticate.Rpxnow as Rpxnow
|
import qualified Web.Authenticate.Rpxnow as Rpxnow
|
||||||
import qualified Web.Authenticate.OpenId as OpenId
|
import qualified Web.Authenticate.OpenId as OpenId
|
||||||
@ -31,10 +31,27 @@ import Control.Monad.Attempt
|
|||||||
|
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
class Yesod a => YesodAuth a where
|
class YesodApproot a => YesodAuth a where
|
||||||
|
-- | The following breaks DRY, but I cannot think of a better solution
|
||||||
|
-- right now.
|
||||||
|
--
|
||||||
|
-- The root relative to the application root. Should not begin with a slash
|
||||||
|
-- and should end with one.
|
||||||
|
authRoot :: a -> String
|
||||||
|
authRoot _ = "auth/"
|
||||||
|
|
||||||
|
defaultLoginPath :: a -> String
|
||||||
|
defaultLoginPath a = authRoot a ++ "openid/"
|
||||||
|
|
||||||
rpxnowApiKey :: a -> Maybe String
|
rpxnowApiKey :: a -> Maybe String
|
||||||
rpxnowApiKey _ = Nothing
|
rpxnowApiKey _ = Nothing
|
||||||
|
|
||||||
|
getFullAuthRoot :: YesodAuth y => Handler y String
|
||||||
|
getFullAuthRoot = do
|
||||||
|
y <- getYesod
|
||||||
|
let (Approot ar) = approot y
|
||||||
|
return $ ar ++ authRoot y
|
||||||
|
|
||||||
data AuthResource =
|
data AuthResource =
|
||||||
Check
|
Check
|
||||||
| Logout
|
| Logout
|
||||||
@ -85,13 +102,11 @@ authOpenidForm = do
|
|||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
return $ cs html
|
return $ cs html
|
||||||
|
|
||||||
authOpenidForward :: Handler y HtmlObject
|
authOpenidForward :: YesodAuth y => Handler y HtmlObject
|
||||||
authOpenidForward = do
|
authOpenidForward = do
|
||||||
oid <- getParam "openid"
|
oid <- getParam "openid"
|
||||||
env <- parseEnv
|
authroot <- getFullAuthRoot
|
||||||
let complete = "http://" ++ Hack.serverName env ++ ":" ++
|
let complete = authroot ++ "/openid/complete/"
|
||||||
show (Hack.serverPort env) ++
|
|
||||||
"/auth/openid/complete/"
|
|
||||||
res <- runAttemptT $ OpenId.getForwardUrl oid complete
|
res <- runAttemptT $ OpenId.getForwardUrl oid complete
|
||||||
attempt
|
attempt
|
||||||
(\err -> redirect $ "/auth/openid/?message=" ++ encodeUrl (show err))
|
(\err -> redirect $ "/auth/openid/?message=" ++ encodeUrl (show err))
|
||||||
@ -145,15 +160,24 @@ rpxnowLogin = do
|
|||||||
|
|
||||||
authCheck :: Handler y HtmlObject
|
authCheck :: Handler y HtmlObject
|
||||||
authCheck = do
|
authCheck = do
|
||||||
ident <- maybeIdentifier
|
ident <- identifier
|
||||||
case ident of
|
return $ toHtmlObject [("identifier", fromMaybe "" ident)]
|
||||||
Nothing -> return $ toHtmlObject [("status", "notloggedin")]
|
|
||||||
Just i -> return $ toHtmlObject
|
|
||||||
[ ("status", "loggedin")
|
|
||||||
, ("ident", i)
|
|
||||||
]
|
|
||||||
|
|
||||||
authLogout :: Handler y HtmlObject
|
authLogout :: Handler y HtmlObject
|
||||||
authLogout = do
|
authLogout = do
|
||||||
deleteCookie authCookieName
|
deleteCookie authCookieName
|
||||||
return $ toHtmlObject [("status", "loggedout")]
|
return $ toHtmlObject [("status", "loggedout")]
|
||||||
|
|
||||||
|
authIdentifier :: YesodAuth y => Handler y String
|
||||||
|
authIdentifier = do
|
||||||
|
mi <- identifier
|
||||||
|
Approot ar <- getApproot
|
||||||
|
case mi of
|
||||||
|
Nothing -> do
|
||||||
|
rp <- requestPath
|
||||||
|
let dest = ar ++ rp
|
||||||
|
liftIO $ print ("authIdentifier", dest, ar, rp)
|
||||||
|
lp <- defaultLoginPath `fmap` getYesod
|
||||||
|
addCookie 120 "DEST" dest
|
||||||
|
redirect $ ar ++ lp
|
||||||
|
Just x -> return x
|
||||||
|
|||||||
@ -36,7 +36,6 @@ module Yesod.Request
|
|||||||
, anyParam
|
, anyParam
|
||||||
, cookieParam
|
, cookieParam
|
||||||
, identifier
|
, identifier
|
||||||
, maybeIdentifier
|
|
||||||
, acceptedLanguages
|
, acceptedLanguages
|
||||||
, requestPath
|
, requestPath
|
||||||
, parseEnv
|
, parseEnv
|
||||||
@ -164,19 +163,10 @@ anyParam = genParam anyParams PostParam -- FIXME
|
|||||||
cookieParam :: (Parameter a, MonadRequestReader m) => ParamName -> m a
|
cookieParam :: (Parameter a, MonadRequestReader m) => ParamName -> m a
|
||||||
cookieParam = genParam cookies CookieParam
|
cookieParam = genParam cookies CookieParam
|
||||||
|
|
||||||
-- | Extract the cookie which specifies the identifier for a logged in
|
|
||||||
-- user.
|
|
||||||
identifier :: MonadRequestReader m => m String
|
|
||||||
identifier = do
|
|
||||||
mi <- maybeIdentifier
|
|
||||||
case mi of
|
|
||||||
Nothing -> authRequired
|
|
||||||
Just x -> return x
|
|
||||||
|
|
||||||
-- | Extract the cookie which specifies the identifier for a logged in
|
-- | Extract the cookie which specifies the identifier for a logged in
|
||||||
-- user, if available.
|
-- user, if available.
|
||||||
maybeIdentifier :: MonadRequestReader m => m (Maybe String)
|
identifier :: MonadRequestReader m => m (Maybe String)
|
||||||
maybeIdentifier = do
|
identifier = do
|
||||||
env <- parseEnv
|
env <- parseEnv
|
||||||
case lookup authCookieName $ Hack.hackHeaders env of
|
case lookup authCookieName $ Hack.hackHeaders env of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
@ -203,7 +193,10 @@ requestPath = do
|
|||||||
"" -> ""
|
"" -> ""
|
||||||
q'@('?':_) -> q'
|
q'@('?':_) -> q'
|
||||||
q' -> q'
|
q' -> q'
|
||||||
return $! Hack.pathInfo env ++ q
|
return $! dropSlash (Hack.pathInfo env) ++ q
|
||||||
|
where
|
||||||
|
dropSlash ('/':x) = x
|
||||||
|
dropSlash x = x
|
||||||
|
|
||||||
type PathInfo = [String]
|
type PathInfo = [String]
|
||||||
|
|
||||||
@ -285,9 +278,10 @@ instance Parameter Day where
|
|||||||
then Right $ fromGregorian y m d
|
then Right $ fromGregorian y m d
|
||||||
else Left $ "Invalid date: " ++ s
|
else Left $ "Invalid date: " ++ s
|
||||||
|
|
||||||
-- for checkboxes; checks for presence
|
-- for checkboxes; checks for presence or a "false" value
|
||||||
instance Parameter Bool where
|
instance Parameter Bool where
|
||||||
readParams [] = Right False
|
readParams [] = Right False
|
||||||
|
readParams [RawParam _ _ "false"] = Right False
|
||||||
readParams [_] = Right True
|
readParams [_] = Right True
|
||||||
readParams x = Left $ "Invalid Bool parameter: " ++ show (map paramValue x)
|
readParams x = Left $ "Invalid Bool parameter: " ++ show (map paramValue x)
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
module Yesod.Yesod
|
module Yesod.Yesod
|
||||||
( Yesod (..)
|
( Yesod (..)
|
||||||
, YesodApproot (..)
|
, YesodApproot (..)
|
||||||
|
, getApproot
|
||||||
, toHackApp
|
, toHackApp
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -50,6 +51,9 @@ class Yesod a => YesodApproot a where
|
|||||||
-- | An absolute URL to the root of the application.
|
-- | An absolute URL to the root of the application.
|
||||||
approot :: a -> Approot
|
approot :: a -> Approot
|
||||||
|
|
||||||
|
getApproot :: YesodApproot y => Handler y Approot
|
||||||
|
getApproot = approot `fmap` getYesod
|
||||||
|
|
||||||
defaultErrorHandler :: Yesod y
|
defaultErrorHandler :: Yesod y
|
||||||
=> ErrorResult
|
=> ErrorResult
|
||||||
-> Handler y RepChooser
|
-> Handler y RepChooser
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user