Can do authentication again

This commit is contained in:
Michael Snoyman 2009-12-25 02:22:24 +02:00
parent abe8b16cfd
commit 0c6493f5f5
4 changed files with 32 additions and 45 deletions

View File

@ -12,7 +12,7 @@ import Hack
import Web.Encodings import Web.Encodings
import Data.List (partition, intercalate) import Data.List (partition, intercalate)
import Data.Function.Predicate (is, isn't, equals) import Data.Function.Predicate (is, isn't, equals)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Web.ClientSession import Web.ClientSession
import Data.Time.Clock (getCurrentTime, UTCTime, addUTCTime) import Data.Time.Clock (getCurrentTime, UTCTime, addUTCTime)
import Data.Time.LocalTime () -- Show instance of UTCTime import Data.Time.LocalTime () -- Show instance of UTCTime
@ -62,8 +62,7 @@ clientsession cnames key app env = do
remoteHost' = remoteHost env remoteHost' = remoteHost env
now <- getCurrentTime now <- getCurrentTime
let convertedCookies = let convertedCookies =
takeJusts $ mapMaybe (decodeCookie key now remoteHost') interceptCookies
map (decodeCookie key now remoteHost') interceptCookies
let env' = env { http = ("Cookie", cookiesRaw) let env' = env { http = ("Cookie", cookiesRaw)
: filter (fst `equals` "Cookie") (http env) : filter (fst `equals` "Cookie") (http env)
++ nonCookies ++ nonCookies
@ -82,11 +81,6 @@ clientsession cnames key app env = do
let res' = res { headers = newCookies ++ headers' } let res' = res { headers = newCookies ++ headers' }
return res' return res'
takeJusts :: [Maybe a] -> [a]
takeJusts [] = []
takeJusts (Just x:rest) = x : takeJusts rest
takeJusts (Nothing:rest) = takeJusts rest
setCookie :: Word256 setCookie :: Word256
-> UTCTime -- ^ expiration time -> UTCTime -- ^ expiration time
-> String -- ^ formatted expiration time -> String -- ^ formatted expiration time

View File

@ -103,8 +103,9 @@ runHandler (Handler handler) eh rr y cts = do
HCContent a -> Right a HCContent a -> Right a
case contents' of case contents' of
Left e -> do Left e -> do
-- FIXME doesn't look right
Response _ hs ct c <- runHandler (eh e) specialEh rr y cts Response _ hs ct c <- runHandler (eh e) specialEh rr y cts
let hs' = hs ++ getHeaders e let hs' = headers ++ hs ++ getHeaders e
return $ Response (getStatus e) hs' ct c return $ Response (getStatus e) hs' ct c
Right a -> do Right a -> do
(ct, c) <- a cts (ct, c) <- a cts

View File

@ -14,10 +14,8 @@
-- --
--------------------------------------------------------- ---------------------------------------------------------
module Yesod.Helpers.Auth module Yesod.Helpers.Auth
( AuthResource ( authHandler
, authHandler , YesodAuth (..)
, authResourcePattern
, RpxnowApiKey (..)
) where ) where
import qualified Hack import qualified Hack
@ -33,6 +31,10 @@ import Control.Monad.Attempt
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
class Yesod a => YesodAuth a where
rpxnowApiKey :: a -> Maybe String
rpxnowApiKey _ = Nothing
data AuthResource = data AuthResource =
Check Check
| Logout | Logout
@ -42,27 +44,19 @@ data AuthResource =
| LoginRpxnow | LoginRpxnow
deriving (Show, Eq, Enum, Bounded) deriving (Show, Eq, Enum, Bounded)
newtype RpxnowApiKey = RpxnowApiKey String rc :: HasReps x => Handler y x -> Handler y RepChooser
rc = fmap chooseRep
authHandler :: Maybe RpxnowApiKey -> AuthResource -> Verb -> Handler y HtmlObject
authHandler _ Check Get = authCheck
authHandler _ Logout Get = authLogout
authHandler _ Openid Get = authOpenidForm
authHandler _ OpenidForward Get = authOpenidForward
authHandler _ OpenidComplete Get = authOpenidComplete
-- two different versions of RPX protocol apparently...
authHandler (Just (RpxnowApiKey key)) LoginRpxnow Get = rpxnowLogin key
authHandler (Just (RpxnowApiKey key)) LoginRpxnow Post = rpxnowLogin key
authHandler _ _ _ = notFound
authResourcePattern :: AuthResource -> String -- FIXME supply prefix as well
authResourcePattern Check = "/auth/check/"
authResourcePattern Logout = "/auth/logout/"
authResourcePattern Openid = "/auth/openid/"
authResourcePattern OpenidForward = "/auth/openid/forward/"
authResourcePattern OpenidComplete = "/auth/openid/complete/"
authResourcePattern LoginRpxnow = "/auth/login/rpxnow/"
authHandler :: YesodAuth y => Verb -> [String] -> Handler y RepChooser
authHandler Get ["check"] = rc authCheck
authHandler Get ["logout"] = rc authLogout
authHandler Get ["openid"] = rc authOpenidForm
authHandler Get ["openid", "forward"] = rc authOpenidForward
authHandler Get ["openid", "complete"] = rc authOpenidComplete
-- two different versions of RPX protocol apparently, so just accepting all
-- verbs
authHandler _ ["login", "rpxnow"] = rc rpxnowLogin
authHandler _ _ = notFound
data OIDFormReq = OIDFormReq (Maybe String) (Maybe String) data OIDFormReq = OIDFormReq (Maybe String) (Maybe String)
instance Request OIDFormReq where instance Request OIDFormReq where
@ -80,6 +74,8 @@ authOpenidForm = do
[ cs m [ cs m
, Tag "form" [("method", "get"), ("action", "forward/")] , Tag "form" [("method", "get"), ("action", "forward/")]
[ Tag "label" [("for", "openid")] [cs "OpenID: "] [ Tag "label" [("for", "openid")] [cs "OpenID: "]
, EmptyTag "input" [("type", "text"), ("id", "openid"),
("name", "openid")]
, EmptyTag "input" [("type", "submit"), ("value", "Login")] , EmptyTag "input" [("type", "submit"), ("value", "Login")]
] ]
] ]
@ -126,9 +122,12 @@ chopHash :: String -> String
chopHash ('#':rest) = rest chopHash ('#':rest) = rest
chopHash x = x chopHash x = x
rpxnowLogin :: String -- ^ api key rpxnowLogin :: YesodAuth y => Handler y HtmlObject
-> Handler y HtmlObject rpxnowLogin = do
rpxnowLogin apiKey = do ay <- getYesod
apiKey <- case rpxnowApiKey ay of
Just x -> return x
Nothing -> notFound
token <- anyParam "token" token <- anyParam "token"
postDest <- postParam "dest" postDest <- postParam "dest"
dest' <- case postDest of dest' <- case postDest of

View File

@ -64,15 +64,8 @@ toHackApp :: Yesod y => y -> Hack.Application
toHackApp a env = do toHackApp a env = do
key <- encryptKey a key <- encryptKey a
let app' = toHackApp' a let app' = toHackApp' a
middleware = (gzip $ cleanPath $ jsonp $ methodOverride
[ gzip $ clientsession [authCookieName] key $ app') env
, cleanPath
, jsonp
, methodOverride
, clientsession [authCookieName] key
]
app = foldr ($) app' middleware
app env
toHackApp' :: Yesod y => y -> Hack.Application toHackApp' :: Yesod y => y -> Hack.Application
toHackApp' y env = do toHackApp' y env = do