Master/Sub bikeshedding

This commit is contained in:
Michael Snoyman 2010-05-09 02:15:15 +03:00
parent db5b82f74d
commit 32465f4e97
6 changed files with 51 additions and 42 deletions

View File

@ -45,7 +45,7 @@ data PageContent url = PageContent
-- Yesod 'Response'. -- Yesod 'Response'.
hamletToContent :: Hamlet (Routes master) IO () -> GHandler sub master Content hamletToContent :: Hamlet (Routes master) IO () -> GHandler sub master Content
hamletToContent h = do hamletToContent h = do
render <- getUrlRenderMaster render <- getUrlRender
return $ ContentEnum $ go render return $ ContentEnum $ go render
where where
go render iter seed = do go render iter seed = do

View File

@ -26,20 +26,23 @@ module Yesod.Handler
, GHandler , GHandler
-- ** Read information from handler -- ** Read information from handler
, getYesod , getYesod
, getYesodMaster , getYesodSub
, getUrlRender , getUrlRender
, getUrlRenderMaster
, getRoute , getRoute
, getRouteToMaster , getRouteToMaster
-- * Special responses -- * Special responses
-- ** Redirecting
, RedirectType (..) , RedirectType (..)
, redirect , redirect
, redirectParams
, redirectString , redirectString
, sendFile -- ** Errors
, notFound , notFound
, badMethod , badMethod
, permissionDenied , permissionDenied
, invalidArgs , invalidArgs
-- ** Sending static files
, sendFile
-- * Setting headers -- * Setting headers
, addCookie , addCookie
, deleteCookie , deleteCookie
@ -59,6 +62,7 @@ import Yesod.Internal
import Web.Mime import Web.Mime
import Web.Routes.Quasi (Routes) import Web.Routes.Quasi (Routes)
import Data.List (foldl') import Data.List (foldl')
import Web.Encodings (encodeUrlPairs)
import Control.Exception hiding (Handler, catch) import Control.Exception hiding (Handler, catch)
import qualified Control.Exception as E import qualified Control.Exception as E
@ -153,23 +157,17 @@ instance RequestReader (GHandler sub master) where
getData :: GHandler sub master (HandlerData sub master) getData :: GHandler sub master (HandlerData sub master)
getData = Handler $ \r -> return ([], [], HCContent r) getData = Handler $ \r -> return ([], [], HCContent r)
-- | Get the application argument. -- | Get the sub application argument.
getYesod :: GHandler sub master sub getYesodSub :: GHandler sub master sub
getYesod = handlerSub <$> getData getYesodSub = handlerSub <$> getData
-- | Get the master site appliation argument. -- | Get the master site appliation argument.
getYesodMaster :: GHandler sub master master getYesod :: GHandler sub master master
getYesodMaster = handlerMaster <$> getData getYesod = handlerMaster <$> getData
-- | Get the URL rendering function. -- | Get the URL rendering function.
getUrlRender :: GHandler sub master (Routes sub -> String) getUrlRender :: GHandler sub master (Routes master -> String)
getUrlRender = do getUrlRender = handlerRender <$> getData
d <- getData
return $ handlerRender d . handlerToMaster d
-- | Get the URL rendering function for the master site.
getUrlRenderMaster :: GHandler sub master (Routes master -> String)
getUrlRenderMaster = handlerRender <$> getData
-- | Get the route requested by the user. If this is a 404 response- where the -- | Get the route requested by the user. If this is a 404 response- where the
-- user requested an invalid route- this function will return 'Nothing'. -- user requested an invalid route- this function will return 'Nothing'.
@ -243,9 +241,16 @@ safeEh er = YesodApp $ \_ _ _ -> do
-- | Redirect to the given route. -- | Redirect to the given route.
redirect :: RedirectType -> Routes master -> GHandler sub master a redirect :: RedirectType -> Routes master -> GHandler sub master a
redirect rt url = do redirect rt url = do
r <- getUrlRenderMaster r <- getUrlRender
redirectString rt $ r url redirectString rt $ r url
-- | Redirects to the given route with the associated query-string parameters.
redirectParams :: RedirectType -> Routes master -> [(String, String)]
-> GHandler sub master a
redirectParams rt url params = do
r <- getUrlRender
redirectString rt $ r url ++ '?' : encodeUrlPairs params
-- | Redirect to the given URL. -- | Redirect to the given URL.
redirectString :: RedirectType -> String -> GHandler sub master a redirectString :: RedirectType -> String -> GHandler sub master a
redirectString rt url = Handler $ \_ -> return ([], [], HCRedirect rt url) redirectString rt url = Handler $ \_ -> return ([], [], HCRedirect rt url)

View File

@ -108,11 +108,12 @@ getOpenIdForward = do
[x] -> return x [x] -> return x
_ -> invalidArgs [("openid", show ExpectedSingleParam)] _ -> invalidArgs [("openid", show ExpectedSingleParam)]
render <- getUrlRender render <- getUrlRender
let complete = render OpenIdComplete toMaster <- getRouteToMaster
let complete = render $ toMaster OpenIdComplete
res <- runAttemptT $ OpenId.getForwardUrl oid complete res <- runAttemptT $ OpenId.getForwardUrl oid complete
let errurl err = render OpenIdR ++ "?message=" ++ encodeUrl (show err)
attempt attempt
(\err -> redirectString RedirectTemporary $ errurl err) (\err -> redirectParams RedirectTemporary (toMaster OpenIdR)
[("message", show err)])
(redirectString RedirectTemporary) (redirectString RedirectTemporary)
res res
@ -121,19 +122,20 @@ getOpenIdComplete = do
rr <- getRequest rr <- getRequest
let gets' = reqGetParams rr let gets' = reqGetParams rr
res <- runAttemptT $ OpenId.authenticate gets' res <- runAttemptT $ OpenId.authenticate gets'
render <- getUrlRender renderm <- getUrlRender
renderm <- getUrlRenderMaster toMaster <- getRouteToMaster
let render = renderm . toMaster
let errurl err = render OpenIdR ++ "?message=" ++ encodeUrl (show err) let errurl err = render OpenIdR ++ "?message=" ++ encodeUrl (show err)
let onFailure err = redirectString RedirectTemporary $ errurl err let onFailure err = redirectString RedirectTemporary $ errurl err
let onSuccess (OpenId.Identifier ident) = do let onSuccess (OpenId.Identifier ident) = do
y <- getYesodMaster y <- getYesod
setSession identKey ident setSession identKey ident
redirectToDest RedirectTemporary $ renderm $ defaultDest y redirectToDest RedirectTemporary $ renderm $ defaultDest y
attempt onFailure onSuccess res attempt onFailure onSuccess res
handleRpxnowR :: YesodAuth master => GHandler Auth master () handleRpxnowR :: YesodAuth master => GHandler Auth master ()
handleRpxnowR = do handleRpxnowR = do
ay <- getYesodMaster ay <- getYesod
apiKey <- case rpxnowApiKey ay of apiKey <- case rpxnowApiKey ay of
Just x -> return x Just x -> return x
Nothing -> notFound Nothing -> notFound
@ -142,11 +144,11 @@ handleRpxnowR = do
let token = case getParams rr "token" ++ pp "token" of let token = case getParams rr "token" ++ pp "token" of
[] -> failure MissingToken [] -> failure MissingToken
(x:_) -> x (x:_) -> x
render <- getUrlRenderMaster renderm <- getUrlRender
let dest = case pp "dest" of let dest = case pp "dest" of
[] -> case getParams rr "dest" of [] -> case getParams rr "dest" of
[] -> render $ defaultDest ay [] -> renderm $ defaultDest ay
("":_) -> render $ defaultDest ay ("":_) -> renderm $ defaultDest ay
(('#':rest):_) -> rest (('#':rest):_) -> rest
(s:_) -> s (s:_) -> s
(d:_) -> d (d:_) -> d
@ -189,9 +191,9 @@ getCheck = do
getLogout :: YesodAuth master => GHandler Auth master () getLogout :: YesodAuth master => GHandler Auth master ()
getLogout = do getLogout = do
y <- getYesodMaster y <- getYesod
clearSession identKey clearSession identKey
render <- getUrlRenderMaster render <- getUrlRender
redirectToDest RedirectTemporary $ render $ defaultDest y redirectToDest RedirectTemporary $ render $ defaultDest y
-- | Gets the identifier for a user if available. -- | Gets the identifier for a user if available.
@ -215,7 +217,7 @@ authIdentifier = maybeIdentifier >>= maybe redirectLogin return
-- appropriately. -- appropriately.
redirectLogin :: YesodAuth master => GHandler sub master a redirectLogin :: YesodAuth master => GHandler sub master a
redirectLogin = do redirectLogin = do
y <- getYesodMaster y <- getYesod
let r = case defaultLoginType y of let r = case defaultLoginType y of
OpenId -> OpenIdR OpenId -> OpenIdR
Rpxnow -> RpxnowR -- FIXME this doesn't actually show a login page? Rpxnow -> RpxnowR -- FIXME this doesn't actually show a login page?
@ -228,9 +230,10 @@ redirectSetDest :: RedirectType
-> GHandler sub master a -> GHandler sub master a
redirectSetDest rt dest = do redirectSetDest rt dest = do
ur <- getUrlRender ur <- getUrlRender
tm <- getRouteToMaster
curr <- getRoute curr <- getRoute
let curr' = case curr of let curr' = case curr of
Just x -> ur x Just x -> ur $ tm x
Nothing -> "/" -- should never happen anyway Nothing -> "/" -- should never happen anyway
addCookie destCookieTimeout destCookieName curr' addCookie destCookieTimeout destCookieName curr'
redirect rt dest redirect rt dest

View File

@ -80,7 +80,7 @@ getRegisterR = do
postRegisterR :: YesodEmailAuth master => GHandler EmailAuth master RepHtml postRegisterR :: YesodEmailAuth master => GHandler EmailAuth master RepHtml
postRegisterR = do postRegisterR = do
email <- runFormPost $ checkEmail $ required $ input "email" email <- runFormPost $ checkEmail $ required $ input "email"
y <- getYesodMaster y <- getYesod
creds <- liftIO $ getCreds y email creds <- liftIO $ getCreds y email
(lid, verKey) <- (lid, verKey) <-
case creds of case creds of
@ -90,7 +90,8 @@ postRegisterR = do
return (lid, key) return (lid, key)
Just (lid, _, _, key) -> return (lid, key) Just (lid, _, _, key) -> return (lid, key)
render <- getUrlRender render <- getUrlRender
let verUrl = render $ VerifyR lid verKey tm <- getRouteToMaster
let verUrl = render $ tm $ VerifyR lid verKey
liftIO $ sendVerifyEmail y email verKey verUrl liftIO $ sendVerifyEmail y email verKey verUrl
applyLayout "Confirmation e-mail sent" $ [$hamlet| applyLayout "Confirmation e-mail sent" $ [$hamlet|
%p A confirmation e-mail has been sent to $cs.email$. %p A confirmation e-mail has been sent to $cs.email$.
@ -102,7 +103,7 @@ checkEmail = notEmpty -- FIXME
getVerifyR :: YesodEmailAuth master getVerifyR :: YesodEmailAuth master
=> Integer -> String -> GHandler EmailAuth master RepHtml => Integer -> String -> GHandler EmailAuth master RepHtml
getVerifyR lid key = do getVerifyR lid key = do
y <- getYesodMaster y <- getYesod
realKey <- liftIO $ getVerifyKey y lid realKey <- liftIO $ getVerifyKey y lid
memail <- liftIO $ getEmail y lid memail <- liftIO $ getEmail y lid
case (realKey == Just key, memail) of case (realKey == Just key, memail) of
@ -157,7 +158,7 @@ postLoginR = do
(email, pass) <- runFormPost $ (,) (email, pass) <- runFormPost $ (,)
<$> checkEmail (required $ input "email") <$> checkEmail (required $ input "email")
<*> required (input "password") <*> required (input "password")
y <- getYesodMaster y <- getYesod
creds <- liftIO $ getCreds y email creds <- liftIO $ getCreds y email
let mlid = let mlid =
case creds of case creds of
@ -216,7 +217,7 @@ postPasswordR = do
setMessage "You must be logged in to set a password" setMessage "You must be logged in to set a password"
redirect RedirectTemporary $ toMaster LoginR redirect RedirectTemporary $ toMaster LoginR
salted <- liftIO $ saltPass new salted <- liftIO $ saltPass new
y <- getYesodMaster y <- getYesod
liftIO $ setPassword y lid salted liftIO $ setPassword y lid salted
setMessage "Password updated" setMessage "Password updated"
redirect RedirectTemporary $ toMaster LoginR redirect RedirectTemporary $ toMaster LoginR
@ -226,7 +227,7 @@ getLogoutR = do
clearSession identKey clearSession identKey
clearSession displayNameKey clearSession displayNameKey
clearSession emailAuthIdKey clearSession emailAuthIdKey
y <- getYesodMaster y <- getYesod
redirect RedirectTemporary $ onSuccessfulLogout y redirect RedirectTemporary $ onSuccessfulLogout y
saltLength :: Int saltLength :: Int
@ -257,7 +258,7 @@ setLoginSession email lid = do
setSession identKey email setSession identKey email
setSession displayNameKey email setSession displayNameKey email
setSession emailAuthIdKey $ show lid setSession emailAuthIdKey $ show lid
y <- getYesodMaster y <- getYesod
liftIO $ onEmailAuthLogin y email lid liftIO $ onEmailAuthLogin y email lid
isLoggedIn :: GHandler sub master (Maybe Integer) isLoggedIn :: GHandler sub master (Maybe Integer)

View File

@ -67,5 +67,5 @@ sitemap = fmap RepXml . hamletToContent . template
robots :: Routes sub -- ^ sitemap url robots :: Routes sub -- ^ sitemap url
-> GHandler sub master RepPlain -> GHandler sub master RepPlain
robots smurl = do robots smurl = do
r <- getUrlRender tm <- getRouteToMaster
return $ RepPlain $ cs $ "Sitemap: " ++ r smurl RepPlain `fmap` hamletToContent [$hamlet|Sitemap: @tm.smurl@|]

View File

@ -77,7 +77,7 @@ getStatic fl fp' = do
getStaticRoute :: [String] -> GHandler Static master [(ContentType, Content)] getStaticRoute :: [String] -> GHandler Static master [(ContentType, Content)]
getStaticRoute fp = do getStaticRoute fp = do
Static fl <- getYesod Static fl <- getYesodSub
getStatic fl fp getStatic fl fp
toStaticRoute :: [String] -> StaticRoutes toStaticRoute :: [String] -> StaticRoutes