@@ -31,14 +31,15 @@ import Network.HTTP.Types (Status (..), hAccept, hContentType,
3131 methodHead, methodPatch,
3232 methodPost, methodPut, ok200,
3333 parseQuery)
34−import Network.Wai (Application, Request, pathInfo,
34+import Network.Wai (Application, Request, requestHeaders, pathInfo,
3535 queryString, rawQueryString,
3636 responseBuilder, responseLBS)
3737import Network.Wai.Internal (Response (ResponseBuilder))
3838import Network.Wai.Test (defaultRequest, request,
3939 runSession, simpleBody,
4040 simpleHeaders, simpleStatus)
41−import Servant.API ((:<|>) (..), (:>), BasicAuth, BasicAuthData(BasicAuthData),
41+import Servant.API ((:<|>) (..), (:>), AuthProtect,
42+ BasicAuth, BasicAuthData(BasicAuthData),
4243 Capture, Delete, Get, Header (..),
4344 Headers, HttpVersion,
4445 IsSecure (..), JSON,
@@ -59,6 +60,9 @@ import Test.Hspec.Wai (get, liftIO, matchHeaders,
5960
6061import Servant.Server.Internal.BasicAuth (BasicAuthCheck(BasicAuthCheck),
6162 BasicAuthResult(Authorized,Unauthorized))
63+import Servant.Server.Internal.Auth
64+ (AuthHandler, AuthServerData,
65+ mkAuthHandler)
6266import Servant.Server.Internal.RoutingApplication
6367 (toApplication, RouteResult(..))
6468import Servant.Server.Internal.Router
@@ -90,6 +94,7 @@ spec = do
9094 routerSpec
9195 miscCombinatorSpec
9296 basicAuthSpec
97+ genAuthSpec
9398
9499------------------------------------------------------------------------------
95100-- * verbSpec {{{
@@ -534,7 +539,7 @@ miscCombinatorSpec = with (return $ serve miscApi miscServ) $
534539
535540-- }}}
536541------------------------------------------------------------------------------
537−-- * Authentication {{{
542+-- * Basic Authentication {{{
538543------------------------------------------------------------------------------
539544
540545type BasicAuthAPI = BasicAuth "foo" () :> "basic" :> Get '[JSON] Animal
@@ -564,6 +569,39 @@ basicAuthSpec = do
564569 it "returns 200 with the right password" $ do
565570 THW.request methodGet "/basic" [("Authorization","Basic c2VydmFudDpzZXJ2ZXI=")] "" `shouldRespondWith` 200
566571
572+-- }}}
573+------------------------------------------------------------------------------
574+-- * General Authentication {{{
575+------------------------------------------------------------------------------
576+
577+type GenAuthAPI = AuthProtect "auth" :> "auth" :> Get '[JSON] Animal
578+authApi :: Proxy GenAuthAPI
579+authApi = Proxy
580+authServer :: Server GenAuthAPI
581+authServer = const (return tweety)
582+
583+type instance AuthServerData (AuthProtect "auth") = ()
584+
585+genAuthContext :: Context '[ AuthHandler Request () ]
586+genAuthContext =
587+ let authHandler = (\req ->
588+ if elem ("Auth", "secret") (requestHeaders req)
589+ then return ()
590+ else throwE err401
591+ )
592+ in mkAuthHandler authHandler :. EmptyContext
593+
594+genAuthSpec :: Spec
595+genAuthSpec = do
596+ describe "Servant.API.Auth" $ do
597+ with (return (serveWithContext authApi genAuthContext authServer)) $ do
598+
599+ context "Custom Auth Protection" $ do
600+ it "returns 401 when missing headers" $ do
601+ get "/auth" `shouldRespondWith` 401
602+ it "returns 200 with the right header" $ do
603+ THW.request methodGet "/auth" [("Auth","secret")] "" `shouldRespondWith` 200
604+
567605-- }}}
568606------------------------------------------------------------------------------
569607-- * Test data types {{{