packages feed

hoauth2-2.15.0: src/Network/OAuth2/Experiment/Flows/TokenRequest.hs

{-# LANGUAGE FlexibleContexts #-}

module Network.OAuth2.Experiment.Flows.TokenRequest where

import Data.Text.Encoding qualified as T
import Data.Text.Lazy qualified as TL
import Network.HTTP.Conduit
import Network.OAuth2 (
  ClientAuthenticationMethod (..),
 )
import Network.OAuth2.Experiment.Types (
  ClientId (unClientId),
  ClientSecret (unClientSecret),
 )

addSecretToHeader :: ClientId -> ClientSecret -> Request -> Request
addSecretToHeader cid csecret =
  applyBasicAuth
    (T.encodeUtf8 $ TL.toStrict $ unClientId cid)
    (T.encodeUtf8 $ TL.toStrict $ unClientSecret csecret)

class HasClientAuthenticationMethod a where
  getClientAuthenticationMethod :: a -> ClientAuthenticationMethod
  addClientAuthToHeader :: a -> Request -> Request
  addClientAuthToHeader _ = id

-- | Only Authorization Code Grant involves a Exchange Token (Authorization Code).
-- ResourceOwnerPassword and Client Credentials make token request directly.
data NoNeedExchangeToken = NoNeedExchangeToken

class HasClientAuthenticationMethod a => HasTokenRequest a where
  -- Each GrantTypeFlow has slightly different request parameter to /token endpoint.
  data TokenRequest a
  type ExchangeTokenInfo a

  -- | Only 'AuthorizationCode flow (but not resource owner password nor client credentials) will use 'ExchangeToken' in the token request
  -- create type family to be explicit on it.
  -- with 'type instance WithExchangeToken a b = b' implies no exchange token
  -- v.s. 'type instance WithExchangeToken a b = ExchangeToken -> b' implies needing an exchange token
  -- type WithExchangeToken a b
  mkTokenRequestParam :: a -> ExchangeTokenInfo a -> TokenRequest a