Merge branch 'yesod1.2' of https://github.com/yesodweb/yesod into yesod1.2
This commit is contained in:
commit
09eecb8e79
@ -13,7 +13,7 @@ import Yesod.Routes.Class
|
|||||||
import Blaze.ByteString.Builder (Builder)
|
import Blaze.ByteString.Builder (Builder)
|
||||||
import Blaze.ByteString.Builder.Char.Utf8 (fromText)
|
import Blaze.ByteString.Builder.Char.Utf8 (fromText)
|
||||||
import Control.Arrow ((***))
|
import Control.Arrow ((***))
|
||||||
import Control.Monad (forM, when)
|
import Control.Monad (forM, when, void)
|
||||||
import Control.Monad.IO.Class (MonadIO (liftIO))
|
import Control.Monad.IO.Class (MonadIO (liftIO))
|
||||||
import Control.Monad.Logger (LogLevel (LevelInfo, LevelOther),
|
import Control.Monad.Logger (LogLevel (LevelInfo, LevelOther),
|
||||||
LogSource)
|
LogSource)
|
||||||
@ -291,10 +291,14 @@ authorizationCheck = do
|
|||||||
master <- getYesod
|
master <- getYesod
|
||||||
case authRoute master of
|
case authRoute master of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
permissionDenied "Authentication required"
|
void $ permissionDenied "Authentication required"
|
||||||
Just url' -> do
|
Just url' -> do
|
||||||
setUltDestCurrent
|
void $ selectRep $ do
|
||||||
redirect url'
|
provideRepType typeJson $ do
|
||||||
|
void $ permissionDenied "Authentication required"
|
||||||
|
provideRepType typeHtml $ do
|
||||||
|
setUltDestCurrent
|
||||||
|
void $ redirect url'
|
||||||
Unauthorized s' -> permissionDenied s'
|
Unauthorized s' -> permissionDenied s'
|
||||||
|
|
||||||
-- | Convert a widget to a 'PageContent'.
|
-- | Convert a widget to a 'PageContent'.
|
||||||
@ -407,6 +411,7 @@ defaultErrorHandler NotFound = selectRep $ do
|
|||||||
<p>#{path'}
|
<p>#{path'}
|
||||||
|]
|
|]
|
||||||
provideRep $ return $ object ["message" .= ("Not Found" :: Text)]
|
provideRep $ return $ object ["message" .= ("Not Found" :: Text)]
|
||||||
|
|
||||||
defaultErrorHandler (PermissionDenied msg) = selectRep $ do
|
defaultErrorHandler (PermissionDenied msg) = selectRep $ do
|
||||||
provideRep $ defaultLayout $ do
|
provideRep $ defaultLayout $ do
|
||||||
setTitle "Permission Denied"
|
setTitle "Permission Denied"
|
||||||
@ -414,7 +419,15 @@ defaultErrorHandler (PermissionDenied msg) = selectRep $ do
|
|||||||
<h1>Permission denied
|
<h1>Permission denied
|
||||||
<p>#{msg}
|
<p>#{msg}
|
||||||
|]
|
|]
|
||||||
provideRep $ return $ object ["message" .= ("Permission Denied" :: Text)]
|
provideRep $ do
|
||||||
|
site <- getYesod
|
||||||
|
rend <- getUrlRender
|
||||||
|
return $ object $ [
|
||||||
|
"message" .= ("Permission Denied. " <> msg)
|
||||||
|
] ++ case authRoute site of
|
||||||
|
Nothing -> []
|
||||||
|
Just url -> ["auth_url" .= rend url]
|
||||||
|
|
||||||
defaultErrorHandler (InvalidArgs ia) = selectRep $ do
|
defaultErrorHandler (InvalidArgs ia) = selectRep $ do
|
||||||
provideRep $ defaultLayout $ do
|
provideRep $ defaultLayout $ do
|
||||||
setTitle "Invalid Arguments"
|
setTitle "Invalid Arguments"
|
||||||
|
|||||||
@ -12,24 +12,30 @@ data App = App
|
|||||||
|
|
||||||
mkYesod "App" [parseRoutes|
|
mkYesod "App" [parseRoutes|
|
||||||
/no-auth NoAuthR
|
/no-auth NoAuthR
|
||||||
/needs-login NeedsLoginR
|
/needs-login-json NeedsLoginJsonR
|
||||||
|
/needs-login-html NeedsLoginHtmlR
|
||||||
/read-only ReadOnlyR
|
/read-only ReadOnlyR
|
||||||
/forbidden ForbiddenR
|
/forbidden ForbiddenR
|
||||||
|]
|
|]
|
||||||
|
|
||||||
instance Yesod App where
|
instance Yesod App where
|
||||||
isAuthorized NoAuthR _ = return Authorized
|
isAuthorized NoAuthR _ = return Authorized
|
||||||
isAuthorized NeedsLoginR _ = return AuthenticationRequired
|
isAuthorized NeedsLoginJsonR _ = return AuthenticationRequired
|
||||||
|
isAuthorized NeedsLoginHtmlR _ = return AuthenticationRequired
|
||||||
isAuthorized ReadOnlyR False = return Authorized
|
isAuthorized ReadOnlyR False = return Authorized
|
||||||
isAuthorized ReadOnlyR True = return $ Unauthorized "Read only"
|
isAuthorized ReadOnlyR True = return $ Unauthorized "Read only"
|
||||||
isAuthorized ForbiddenR _ = return $ Unauthorized "Forbidden"
|
isAuthorized ForbiddenR _ = return $ Unauthorized "Forbidden"
|
||||||
authRoute _ = Just NoAuthR
|
authRoute _ = Just NoAuthR
|
||||||
|
|
||||||
handleNoAuthR, handleNeedsLoginR, handleReadOnlyR, handleForbiddenR :: Handler ()
|
handleNoAuthR, handleReadOnlyR, handleForbiddenR :: Handler ()
|
||||||
handleNoAuthR = return ()
|
handleNoAuthR = return ()
|
||||||
handleNeedsLoginR = return ()
|
handleReadOnlyR = return ()
|
||||||
handleReadOnlyR = return ()
|
handleForbiddenR = return ()
|
||||||
handleForbiddenR = return ()
|
|
||||||
|
handleNeedsLoginJsonR :: Handler RepJson
|
||||||
|
handleNeedsLoginJsonR = return $ repJson $ object []
|
||||||
|
handleNeedsLoginHtmlR :: Handler RepHtml
|
||||||
|
handleNeedsLoginHtmlR = return ""
|
||||||
|
|
||||||
test :: String -- ^ method
|
test :: String -- ^ method
|
||||||
-> String -- ^ path
|
-> String -- ^ path
|
||||||
@ -48,8 +54,10 @@ specs :: Spec
|
|||||||
specs = describe "Auth" $ do
|
specs = describe "Auth" $ do
|
||||||
test "GET" "no-auth" $ \sres -> assertStatus 200 sres
|
test "GET" "no-auth" $ \sres -> assertStatus 200 sres
|
||||||
test "POST" "no-auth" $ \sres -> assertStatus 200 sres
|
test "POST" "no-auth" $ \sres -> assertStatus 200 sres
|
||||||
test "GET" "needs-login" $ \sres -> assertStatus 303 sres
|
test "GET" "needs-login-html" $ \sres -> assertStatus 303 sres
|
||||||
test "POST" "needs-login" $ \sres -> assertStatus 303 sres
|
test "POST" "needs-login-html" $ \sres -> assertStatus 303 sres
|
||||||
|
test "GET" "needs-login-json" $ \sres -> assertStatus 403 sres
|
||||||
|
test "POST" "needs-login-json" $ \sres -> assertStatus 403 sres
|
||||||
test "GET" "read-only" $ \sres -> assertStatus 200 sres
|
test "GET" "read-only" $ \sres -> assertStatus 200 sres
|
||||||
test "POST" "read-only" $ \sres -> assertStatus 403 sres
|
test "POST" "read-only" $ \sres -> assertStatus 403 sres
|
||||||
test "GET" "forbidden" $ \sres -> assertStatus 403 sres
|
test "GET" "forbidden" $ \sres -> assertStatus 403 sres
|
||||||
|
|||||||
@ -9,11 +9,15 @@ import Data.ByteString.Lazy (ByteString)
|
|||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import Data.String (IsString)
|
import Data.String (IsString)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
import Data.Maybe (fromJust)
|
||||||
|
import Data.Monoid (Endo (..))
|
||||||
|
import qualified Control.Monad.Trans.Writer as Writer
|
||||||
|
|
||||||
data App = App
|
data App = App
|
||||||
|
|
||||||
mkYesod "App" [parseRoutes|
|
mkYesod "App" [parseRoutes|
|
||||||
/ HomeR GET
|
/ HomeR GET
|
||||||
|
/json JsonR GET
|
||||||
|]
|
|]
|
||||||
|
|
||||||
instance Yesod App
|
instance Yesod App
|
||||||
@ -23,23 +27,39 @@ specialHtml = "text/html; charset=special"
|
|||||||
|
|
||||||
getHomeR :: Handler TypedContent
|
getHomeR :: Handler TypedContent
|
||||||
getHomeR = selectRep $ do
|
getHomeR = selectRep $ do
|
||||||
let go ct t = provideRepType ct $ return (t :: Text)
|
rep typeHtml "HTML"
|
||||||
go typeHtml "HTML"
|
rep specialHtml "HTMLSPECIAL"
|
||||||
go specialHtml "HTMLSPECIAL"
|
rep typeXml "XML"
|
||||||
go typeJson "JSON"
|
rep typeJson "JSON"
|
||||||
go typeXml "XML"
|
|
||||||
|
rep :: Monad m => ContentType -> Text -> Writer.Writer (Data.Monoid.Endo [ProvidedRep m]) ()
|
||||||
|
rep ct t = provideRepType ct $ return (t :: Text)
|
||||||
|
|
||||||
|
getJsonR :: Handler TypedContent
|
||||||
|
getJsonR = selectRep $ do
|
||||||
|
rep typeHtml "HTML"
|
||||||
|
provideRep $ return $ object ["message" .= ("Invalid Login" :: Text)]
|
||||||
|
|
||||||
|
testRequest :: Request
|
||||||
|
-> ByteString -- ^ expected body
|
||||||
|
-> Spec
|
||||||
|
testRequest req expected = it (S8.unpack $ fromJust $ lookup "Accept" $ requestHeaders req) $ do
|
||||||
|
app <- toWaiApp App
|
||||||
|
flip runSession app $ do
|
||||||
|
sres <- request req
|
||||||
|
assertBody expected sres
|
||||||
|
assertStatus 200 sres
|
||||||
|
|
||||||
test :: String -- ^ accept header
|
test :: String -- ^ accept header
|
||||||
-> ByteString -- ^ expected body
|
-> ByteString -- ^ expected body
|
||||||
-> Spec
|
-> Spec
|
||||||
test accept expected = it accept $ do
|
test accept expected =
|
||||||
app <- toWaiApp App
|
testRequest (acceptRequest accept) expected
|
||||||
flip runSession app $ do
|
|
||||||
sres <- request defaultRequest
|
acceptRequest :: String -> Request
|
||||||
|
acceptRequest accept = defaultRequest
|
||||||
{ requestHeaders = [("Accept", S8.pack accept)]
|
{ requestHeaders = [("Accept", S8.pack accept)]
|
||||||
}
|
}
|
||||||
assertBody expected sres
|
|
||||||
assertStatus 200 sres
|
|
||||||
|
|
||||||
specs :: Spec
|
specs :: Spec
|
||||||
specs = describe "selectRep" $ do
|
specs = describe "selectRep" $ do
|
||||||
@ -53,3 +73,4 @@ specs = describe "selectRep" $ do
|
|||||||
test (S8.unpack typeHtml) "HTML"
|
test (S8.unpack typeHtml) "HTML"
|
||||||
test "text/html" "HTML"
|
test "text/html" "HTML"
|
||||||
test specialHtml "HTMLSPECIAL"
|
test specialHtml "HTMLSPECIAL"
|
||||||
|
testRequest (acceptRequest "application/json") { pathInfo = ["json"] } "{\"message\":\"Invalid Login\"}"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user