Can do authentication again
This commit is contained in:
parent
abe8b16cfd
commit
0c6493f5f5
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user