hoauth2-2.9.0: src/Network/OAuth2/Experiment/Grants/ClientCredentials.hs
{-# LANGUAGE FlexibleInstances #-}
module Network.OAuth2.Experiment.Grants.ClientCredentials where
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Set (Set)
import Data.Text.Lazy (Text)
import Network.OAuth.OAuth2 (ClientAuthenticationMethod (..), OAuth2)
import Network.OAuth2.Experiment.Flows.TokenRequest
import Network.OAuth2.Experiment.Types
import Network.OAuth2.Experiment.Utils
-- | An Application that supports "Client Credentials" flow
--
-- https://www.rfc-editor.org/rfc/rfc6749#section-4.4
data ClientCredentialsApplication = ClientCredentialsApplication
{ ccClientId :: ClientId
, ccClientSecret :: ClientSecret
, ccName :: Text
, ccScope :: Set Scope
, ccTokenRequestExtraParams :: Map Text Text
, ccTokenRequestAuthenticationMethod :: ClientAuthenticationMethod
}
instance HasOAuth2Key ClientCredentialsApplication where
mkOAuth2Key :: ClientCredentialsApplication -> OAuth2
mkOAuth2Key ClientCredentialsApplication {..} = toOAuth2Key ccClientId ccClientSecret
instance HasTokenRequestClientAuthenticationMethod ClientCredentialsApplication where
getClientAuthenticationMethod :: ClientCredentialsApplication -> ClientAuthenticationMethod
getClientAuthenticationMethod ClientCredentialsApplication {..} = ccTokenRequestAuthenticationMethod
-- | https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2
instance HasTokenRequest ClientCredentialsApplication where
type ExchangeTokenInfo ClientCredentialsApplication = NoNeedExchangeToken
data TokenRequest ClientCredentialsApplication = ClientCredentialsTokenRequest
{ trScope :: Set Scope
, trGrantType :: GrantTypeValue
, trClientSecret :: ClientSecret
, trClientId :: ClientId
, trExtraParams :: Map Text Text
, trClientAuthenticationMethod :: ClientAuthenticationMethod
}
mkTokenRequestParam :: ClientCredentialsApplication -> NoNeedExchangeToken -> TokenRequest ClientCredentialsApplication
mkTokenRequestParam ClientCredentialsApplication {..} _ =
ClientCredentialsTokenRequest
{ trScope = ccScope
, trGrantType = GTClientCredentials
, trClientSecret = ccClientSecret
, trClientAuthenticationMethod = ccTokenRequestAuthenticationMethod
, trExtraParams = ccTokenRequestExtraParams
, trClientId = ccClientId
}
instance ToQueryParam (TokenRequest ClientCredentialsApplication) where
toQueryParam :: TokenRequest ClientCredentialsApplication -> Map Text Text
toQueryParam ClientCredentialsTokenRequest {..} =
let jwtAssertionBody =
if trClientAuthenticationMethod == ClientAssertionJwt
then
[ toQueryParam trClientId
, Map.fromList
[ ("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer")
, ("client_assertion", bs8ToLazyText $ tlToBS $ unClientSecret trClientSecret)
]
]
else []
in Map.unions $
[ toQueryParam trGrantType
, toQueryParam trScope
, trExtraParams
]
++ jwtAssertionBody