Merge pull request #1531 from gdeest/servant-auth-named-routes

servant-auth-server: Support NamedRoutes
This commit is contained in:
Gaël Deest 2022-02-14 14:57:19 +01:00 committed by GitHub
commit 002fa2107a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 1 deletions

View file

@ -11,6 +11,8 @@ import Data.Tagged (Tagged (..))
import qualified Network.HTTP.Types as HTTP import qualified Network.HTTP.Types as HTTP
import Network.Wai (mapResponseHeaders) import Network.Wai (mapResponseHeaders)
import Servant import Servant
import Servant.API.Generic
import Servant.Server.Generic
import Web.Cookie import Web.Cookie
-- What are we doing here? Well, the idea is to add headers to the response, -- What are we doing here? Well, the idea is to add headers to the response,
@ -34,6 +36,7 @@ type family AddSetCookieApiVerb a where
type family AddSetCookieApi a :: * type family AddSetCookieApi a :: *
type instance AddSetCookieApi (a :> b) = a :> AddSetCookieApi b type instance AddSetCookieApi (a :> b) = a :> AddSetCookieApi b
type instance AddSetCookieApi (a :<|> b) = AddSetCookieApi a :<|> AddSetCookieApi b type instance AddSetCookieApi (a :<|> b) = AddSetCookieApi a :<|> AddSetCookieApi b
type instance AddSetCookieApi (NamedRoutes api) = AddSetCookieApi (ToServantApi api)
type instance AddSetCookieApi (Verb method stat ctyps a) type instance AddSetCookieApi (Verb method stat ctyps a)
= Verb method stat ctyps (AddSetCookieApiVerb a) = Verb method stat ctyps (AddSetCookieApiVerb a)
type instance AddSetCookieApi Raw = Raw type instance AddSetCookieApi Raw = Raw
@ -72,6 +75,15 @@ instance {-# OVERLAPS #-}
=> AddSetCookies ('S n) (a :<|> b) (a' :<|> b') where => AddSetCookies ('S n) (a :<|> b) (a' :<|> b') where
addSetCookies cookies (a :<|> b) = addSetCookies cookies a :<|> addSetCookies cookies b addSetCookies cookies (a :<|> b) = addSetCookies cookies a :<|> addSetCookies cookies b
instance {-# OVERLAPS #-}
( AddSetCookies ('S n) (ServerT (ToServantApi api) m) cookiedApi
, Generic (api (AsServerT m))
, GServantProduct (Rep (api (AsServerT m)))
, ToServant api (AsServerT m) ~ ServerT (ToServantApi api) m
)
=> AddSetCookies ('S n) (api (AsServerT m)) cookiedApi where
addSetCookies cookies = addSetCookies cookies . toServant
-- | for @servant <0.11@ -- | for @servant <0.11@
instance instance
AddSetCookies ('S n) Application Application where AddSetCookies ('S n) Application Application where

View file

@ -8,7 +8,10 @@ module Servant.Auth.Server.Internal.ThrowAll where
import Control.Monad.Error.Class import Control.Monad.Error.Class
import Data.Tagged (Tagged (..)) import Data.Tagged (Tagged (..))
import Servant ((:<|>) (..), ServerError(..)) import Servant ((:<|>) (..), ServerError(..), NamedRoutes(..))
import Servant.API.Generic
import Servant.Server.Generic
import Servant.Server
import Network.HTTP.Types import Network.HTTP.Types
import Network.Wai import Network.Wai
@ -26,6 +29,12 @@ class ThrowAll a where
instance (ThrowAll a, ThrowAll b) => ThrowAll (a :<|> b) where instance (ThrowAll a, ThrowAll b) => ThrowAll (a :<|> b) where
throwAll e = throwAll e :<|> throwAll e throwAll e = throwAll e :<|> throwAll e
instance
( ThrowAll (ToServant api (AsServerT m)) , GenericServant api (AsServerT m)) =>
ThrowAll (api (AsServerT m)) where
throwAll = fromServant . throwAll
-- Really this shouldn't be necessary - ((->) a) should be an instance of -- Really this shouldn't be necessary - ((->) a) should be an instance of
-- MonadError, no? -- MonadError, no?
instance {-# OVERLAPPING #-} ThrowAll b => ThrowAll (a -> b) where instance {-# OVERLAPPING #-} ThrowAll b => ThrowAll (a -> b) where

View file

@ -50,6 +50,7 @@ import Network.Wreq (Options, auth, basicAuth,
import Network.Wreq.Types (Postable(..)) import Network.Wreq.Types (Postable(..))
import Servant hiding (BasicAuth, import Servant hiding (BasicAuth,
IsSecure (..), header) IsSecure (..), header)
import Servant.API.Generic ((:-))
import Servant.Auth.Server import Servant.Auth.Server
import Servant.Auth.Server.Internal.Cookie (expireTime) import Servant.Auth.Server.Internal.Cookie (expireTime)
import Servant.Auth.Server.SetCookieOrphan () import Servant.Auth.Server.SetCookieOrphan ()
@ -405,6 +406,7 @@ type API auths
= Auth auths User :> = Auth auths User :>
( Get '[JSON] Int ( Get '[JSON] Int
:<|> ReqBody '[JSON] Int :> Post '[JSON] Int :<|> ReqBody '[JSON] Int :> Post '[JSON] Int
:<|> NamedRoutes DummyRoutes
:<|> "header" :> Get '[JSON] (Headers '[Header "Blah" Int] Int) :<|> "header" :> Get '[JSON] (Headers '[Header "Blah" Int] Int)
#if MIN_VERSION_servant_server(0,15,0) #if MIN_VERSION_servant_server(0,15,0)
:<|> "stream" :> StreamGet NoFraming OctetStream (SourceIO BS.ByteString) :<|> "stream" :> StreamGet NoFraming OctetStream (SourceIO BS.ByteString)
@ -416,6 +418,10 @@ type API auths
:<|> "logout" :> Get '[JSON] (Headers '[ Header "Set-Cookie" SetCookie :<|> "logout" :> Get '[JSON] (Headers '[ Header "Set-Cookie" SetCookie
, Header "Set-Cookie" SetCookie ] NoContent) , Header "Set-Cookie" SetCookie ] NoContent)
data DummyRoutes mode = DummyRoutes
{ dummyInt :: mode :- "dummy" :> Get '[JSON] Int
} deriving Generic
jwtOnlyApi :: Proxy (API '[Servant.Auth.Server.JWT]) jwtOnlyApi :: Proxy (API '[Servant.Auth.Server.JWT])
jwtOnlyApi = Proxy jwtOnlyApi = Proxy
@ -476,6 +482,7 @@ server ccfg =
(\authResult -> case authResult of (\authResult -> case authResult of
Authenticated usr -> getInt usr Authenticated usr -> getInt usr
:<|> postInt usr :<|> postInt usr
:<|> DummyRoutes { dummyInt = getInt usr }
:<|> getHeaderInt :<|> getHeaderInt
#if MIN_VERSION_servant_server(0,15,0) #if MIN_VERSION_servant_server(0,15,0)
:<|> return (S.source ["bytestring"]) :<|> return (S.source ["bytestring"])