Add auth support for servant-client
This commit is contained in:
parent
970af450dd
commit
ffeeffe745
3 changed files with 57 additions and 0 deletions
|
@ -27,6 +27,7 @@ source-repository head
|
|||
library
|
||||
exposed-modules:
|
||||
Servant.Client
|
||||
Servant.Common.Auth
|
||||
Servant.Common.BaseUrl
|
||||
Servant.Common.Req
|
||||
build-depends:
|
||||
|
@ -34,6 +35,7 @@ library
|
|||
, aeson
|
||||
, attoparsec
|
||||
, bytestring
|
||||
, base64-bytestring
|
||||
, exceptions
|
||||
, http-api-data >= 0.1 && < 0.3
|
||||
, http-client
|
||||
|
@ -68,6 +70,7 @@ test-suite spec
|
|||
, transformers-compat
|
||||
, aeson
|
||||
, bytestring
|
||||
, base64-bytestring
|
||||
, deepseq
|
||||
, hspec == 2.*
|
||||
, http-client
|
||||
|
|
|
@ -37,6 +37,7 @@ import Network.HTTP.Media
|
|||
import qualified Network.HTTP.Types as H
|
||||
import qualified Network.HTTP.Types.Header as HTTP
|
||||
import Servant.API
|
||||
import Servant.Common.Auth
|
||||
import Servant.Common.BaseUrl
|
||||
import Servant.Common.Req
|
||||
|
||||
|
@ -407,6 +408,21 @@ instance HasClient api => HasClient (IsSecure :> api) where
|
|||
clientWithRoute Proxy req baseurl manager =
|
||||
clientWithRoute (Proxy :: Proxy api) req baseurl manager
|
||||
|
||||
instance HasClient api => HasClient (BasicAuth tag realm usr :> api) where
|
||||
type Client (BasicAuth tag realm usr :> api) = BasicAuthData -> Client api
|
||||
|
||||
clientWithRoute Proxy req baseurl manager val =
|
||||
clientWithRoute (Proxy :: Proxy api) (basicAuthReq val req) baseurl manager
|
||||
|
||||
instance ( HasClient api
|
||||
, AuthenticateClientRequest (AuthProtect tag)
|
||||
) => HasClient (AuthProtect tag :> api) where
|
||||
type Client (AuthProtect tag :> api)
|
||||
= ClientAuthType (AuthProtect tag) -> Client api
|
||||
|
||||
clientWithRoute Proxy req baseurl manager val =
|
||||
clientWithRoute (Proxy :: Proxy api) (authReq val req) baseurl manager
|
||||
|
||||
|
||||
{- Note [Non-Empty Content Types]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
38
servant-client/src/Servant/Common/Auth.hs
Normal file
38
servant-client/src/Servant/Common/Auth.hs
Normal file
|
@ -0,0 +1,38 @@
|
|||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TypeSynonymInstances #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
-- | Authentication for clients
|
||||
|
||||
module Servant.Common.Auth (
|
||||
AuthenticateClientRequest ( ClientAuthType, authReq )
|
||||
, BasicAuthData (BasicAuthData, username, password)
|
||||
, basicAuthReq
|
||||
) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.ByteString.Base64 (encode)
|
||||
import Data.Monoid ((<>))
|
||||
import Data.Text.Encoding (decodeUtf8)
|
||||
import Servant.Common.Req (addHeader, Req)
|
||||
|
||||
|
||||
-- | A simple datatype to hold data required to decorate a request
|
||||
data BasicAuthData = BasicAuthData { username :: ByteString
|
||||
, password :: ByteString
|
||||
}
|
||||
|
||||
-- | Authenticate a request using Basic Authentication
|
||||
basicAuthReq :: BasicAuthData -> Req -> Req
|
||||
basicAuthReq (BasicAuthData user pass) req =
|
||||
let authText = decodeUtf8 ("Basic " <> encode (user <> ":" <> pass))
|
||||
in addHeader "Authorization" authText req
|
||||
|
||||
-- | Class to represent the ability to authenticate a 'Request'
|
||||
-- object. For example, we may add special headers to the 'Request'.
|
||||
class AuthenticateClientRequest a where
|
||||
data ClientAuthType a :: *
|
||||
authReq :: ClientAuthType a -> Req -> Req
|
Loading…
Reference in a new issue