-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Haskell OAuth2 authentication client
--   
--   Haskell OAuth2 authentication client.
--   
--   Tutorial
--   <a>https://github.com/freizl/hoauth2/tree/main/hoauth2-tutorial/</a>
--   
--   Demo application
--   <a>https://github.com/freizl/hoauth2-demo/tree/main/hoauth2-demo/</a>
@package hoauth2
@version 2.6.0

module Network.OAuth.OAuth2.Internal

-- | Query Parameter Representation
data OAuth2
OAuth2 :: Text -> Text -> URIRef Absolute -> URIRef Absolute -> URIRef Absolute -> OAuth2
[oauth2ClientId] :: OAuth2 -> Text
[oauth2ClientSecret] :: OAuth2 -> Text
[oauth2AuthorizeEndpoint] :: OAuth2 -> URIRef Absolute
[oauth2TokenEndpoint] :: OAuth2 -> URIRef Absolute
[oauth2RedirectUri] :: OAuth2 -> URIRef Absolute
newtype AccessToken
AccessToken :: Text -> AccessToken
[atoken] :: AccessToken -> Text
newtype RefreshToken
RefreshToken :: Text -> RefreshToken
[rtoken] :: RefreshToken -> Text
newtype IdToken
IdToken :: Text -> IdToken
[idtoken] :: IdToken -> Text

-- | Authorization Code
newtype ExchangeToken
ExchangeToken :: Text -> ExchangeToken
[extoken] :: ExchangeToken -> Text

-- | <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.4</a>
data OAuth2Token
OAuth2Token :: AccessToken -> Maybe RefreshToken -> Maybe Int -> Maybe Text -> Maybe IdToken -> OAuth2Token
[accessToken] :: OAuth2Token -> AccessToken

-- | Exists when <tt>offline_access</tt> scope is in the
--   <tt>authorizeUrl</tt> and the provider supports Refresh Access Token.
[refreshToken] :: OAuth2Token -> Maybe RefreshToken
[expiresIn] :: OAuth2Token -> Maybe Int

-- | See <a>https://www.rfc-editor.org/rfc/rfc6749#section-5.1</a>. It's
--   required per spec. But OAuth2 provider implementation are vary. Maybe
--   will remove <a>Maybe</a> in future release.
[tokenType] :: OAuth2Token -> Maybe Text

-- | Exists when <tt>openid</tt> scope is in the <tt>authorizeUrl</tt> and
--   the provider supports OpenID.
[idToken] :: OAuth2Token -> Maybe IdToken
data OAuth2Error a
OAuth2Error :: Either Text a -> Maybe Text -> Maybe (URIRef Absolute) -> OAuth2Error a
[error] :: OAuth2Error a -> Either Text a
[errorDescription] :: OAuth2Error a -> Maybe Text
[errorUri] :: OAuth2Error a -> Maybe (URIRef Absolute)
parseOAuth2Error :: FromJSON err => ByteString -> OAuth2Error err
mkDecodeOAuth2Error :: ByteString -> String -> OAuth2Error err

-- | <a>https://www.rfc-editor.org/rfc/rfc6749#section-2.3</a> According to
--   spec:
--   
--   The client MUST NOT use more than one authentication method in each
--   request.
--   
--   Which means use Authorization header or Post body.
--   
--   However, in reality, I always have to include authentication in the
--   header.
--   
--   In other words, <tt>ClientSecrectBasic</tt> is always assured.
--   <a>ClientSecretPost</a> is optional.
--   
--   Maybe consider an alternative implementation that boolean kind of data
--   type is good enough.
data ClientAuthenticationMethod
ClientSecretBasic :: ClientAuthenticationMethod
ClientSecretPost :: ClientAuthenticationMethod

-- | type synonym of post body content
type PostBody = [(ByteString, ByteString)]
type QueryParams = [(ByteString, ByteString)]
defaultRequestHeaders :: [(HeaderName, ByteString)]
appendQueryParams :: [(ByteString, ByteString)] -> URIRef a -> URIRef a
uriToRequest :: MonadThrow m => URI -> m Request
requestToUri :: Request -> URI
hostLens :: Lens' Request ByteString
portLens :: Lens' Request Int
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.OAuth2
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.OAuth2
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.Internal.AccessToken
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.Internal.AccessToken
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.AccessToken
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.AccessToken
instance Data.Binary.Class.Binary Network.OAuth.OAuth2.Internal.AccessToken
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.Internal.RefreshToken
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.Internal.RefreshToken
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.RefreshToken
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.RefreshToken
instance Data.Binary.Class.Binary Network.OAuth.OAuth2.Internal.RefreshToken
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.Internal.IdToken
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.Internal.IdToken
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.IdToken
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.IdToken
instance Data.Binary.Class.Binary Network.OAuth.OAuth2.Internal.IdToken
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.Internal.ExchangeToken
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.Internal.ExchangeToken
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.ExchangeToken
instance GHC.Generics.Generic Network.OAuth.OAuth2.Internal.OAuth2Token
instance GHC.Show.Show Network.OAuth.OAuth2.Internal.OAuth2Token
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.OAuth2Token
instance GHC.Generics.Generic (Network.OAuth.OAuth2.Internal.OAuth2Error a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Network.OAuth.OAuth2.Internal.OAuth2Error a)
instance GHC.Show.Show a => GHC.Show.Show (Network.OAuth.OAuth2.Internal.OAuth2Error a)
instance GHC.Classes.Ord Network.OAuth.OAuth2.Internal.ClientAuthenticationMethod
instance GHC.Classes.Eq Network.OAuth.OAuth2.Internal.ClientAuthenticationMethod
instance Data.Aeson.Types.FromJSON.FromJSON err => Data.Aeson.Types.FromJSON.FromJSON (Network.OAuth.OAuth2.Internal.OAuth2Error err)
instance Data.Aeson.Types.ToJSON.ToJSON err => Data.Aeson.Types.ToJSON.ToJSON (Network.OAuth.OAuth2.Internal.OAuth2Error err)
instance Data.Binary.Class.Binary Network.OAuth.OAuth2.Internal.OAuth2Token
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.Internal.OAuth2Token
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.Internal.OAuth2Token
instance Data.Default.Class.Default Network.OAuth.OAuth2.Internal.OAuth2


-- | Bindings for The OAuth 2.0 Authorization Framework: Bearer Token Usage
--   RFC6750 <a>https://www.rfc-editor.org/rfc/rfc6750</a>
module Network.OAuth.OAuth2.HttpClient

-- | Conduct an authorized GET request and return response as JSON. Inject
--   Access Token to Authorization Header.
authGetJSON :: (FromJSON a, MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Conduct an authorized GET request. Inject Access Token to
--   Authorization Header.
authGetBS :: MonadIO m => Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Same to <a>authGetBS</a> but set access token to query parameter
--   rather than header

-- | <i>Deprecated: use authGetBSWithAuthMethod</i>
authGetBS2 :: MonadIO m => Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Conduct an authorized GET request and return response as JSON. Allow
--   to specify how to append AccessToken.
authGetJSONWithAuthMethod :: (MonadIO m, FromJSON a) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | <i>Deprecated: use authGetJSONWithAuthMethod</i>
authGetJSONInternal :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Conduct an authorized GET request and return response as ByteString.
--   Allow to specify how to append AccessToken.
authGetBSWithAuthMethod :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | <i>Deprecated: use authGetBSWithAuthMethod</i>
authGetBSInternal :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | Conduct POST request and return response as JSON. Inject Access Token
--   to Authorization Header.
authPostJSON :: (FromJSON a, MonadIO m) => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Conduct POST request. Inject Access Token to http header
--   (Authorization)
authPostBS :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request with access token only in the request body but
--   header.

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
authPostBS2 :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request with access token only in the header and not in
--   body

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
authPostBS3 :: MonadIO m => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | Conduct POST request and return response as JSON. Allow to specify how
--   to append AccessToken.
authPostJSONWithAuthMethod :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | <i>Deprecated: use <a>authPostJSONWithAuthMethod</a></i>
authPostJSONInternal :: (FromJSON a, MonadIO m) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Conduct POST request and return response as ByteString. Allow to
--   specify how to append AccessToken.
authPostBSWithAuthMethod :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
authPostBSInternal :: MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | <a>https://www.rfc-editor.org/rfc/rfc6750#section-2</a>
data APIAuthenticationMethod

-- | Provides in Authorization header
AuthInRequestHeader :: APIAuthenticationMethod

-- | Provides in request body
AuthInRequestBody :: APIAuthenticationMethod

-- | Provides in request query parameter
AuthInRequestQuery :: APIAuthenticationMethod
instance GHC.Classes.Ord Network.OAuth.OAuth2.HttpClient.APIAuthenticationMethod
instance GHC.Classes.Eq Network.OAuth.OAuth2.HttpClient.APIAuthenticationMethod


-- | Bindings Authorization part of The OAuth 2.0 Authorization Framework
--   RFC6749 <a>https://www.rfc-editor.org/rfc/rfc6749</a>
module Network.OAuth.OAuth2.AuthorizationRequest

-- | Authorization Code Grant Error Responses
--   <a>https://tools.ietf.org/html/rfc6749#section-4.1.2.1</a> I found
--   hard time to figure a way to test the authorization error flow When
--   anything wrong in <tt>/authorize</tt> request (redirect to OAuth2
--   provider), it will end-up at the Provider page hence no way for this
--   library to parse error response. In other words, <tt>/authorize</tt>
--   ends up with 4xx or 5xx. Revisit this whenever find a case OAuth2
--   provider redirects back to Relying party with errors.
data Errors
InvalidRequest :: Errors
UnauthorizedClient :: Errors
AccessDenied :: Errors
UnsupportedResponseType :: Errors
InvalidScope :: Errors
ServerError :: Errors
TemporarilyUnavailable :: Errors

-- | See <a>authorizationUrlWithParams</a>
authorizationUrl :: OAuth2 -> URI

-- | Prepare the authorization URL. Redirect to this URL asking for user
--   interactive authentication.
authorizationUrlWithParams :: QueryParams -> OAuth2 -> URI
instance GHC.Generics.Generic Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance GHC.Classes.Eq Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance GHC.Show.Show Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.AuthorizationRequest.Errors
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.AuthorizationRequest.Errors


-- | Bindings Access Token and Refresh Token part of The OAuth 2.0
--   Authorization Framework RFC6749
--   <a>https://www.rfc-editor.org/rfc/rfc6749</a>
module Network.OAuth.OAuth2.TokenRequest

-- | Token Error Responses
--   <a>https://tools.ietf.org/html/rfc6749#section-5.2</a>
data Errors
InvalidRequest :: Errors
InvalidClient :: Errors
InvalidGrant :: Errors
UnauthorizedClient :: Errors
UnsupportedGrantType :: Errors
InvalidScope :: Errors

-- | Prepare the URL and the request body query for fetching an access
--   token.
accessTokenUrl :: OAuth2 -> ExchangeToken -> (URI, PostBody)

-- | Obtain a new access token by sending a Refresh Token to the
--   Authorization server.
refreshAccessTokenUrl :: OAuth2 -> RefreshToken -> (URI, PostBody)

-- | Exchange <tt>code</tt> for an Access Token with authenticate in
--   request header.
fetchAccessToken :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessToken2 :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Exchange <tt>code</tt> for an Access Token
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try <a>fetchAccessToken</a> which sends credential in
--   authorization http header, which is common case.
fetchAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token with authentication in
--   request header.
refreshAccessToken :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessToken2 :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token.
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try <a>refreshAccessToken</a> which sends credential in
--   authorization http header, which is common case.
refreshAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Conduct post request and return response as JSON.
doJSONPostRequest :: (MonadIO m, FromJSON err, FromJSON a) => Manager -> OAuth2 -> URI -> PostBody -> ExceptT (OAuth2Error err) m a

-- | Conduct post request.
doSimplePostRequest :: (MonadIO m, FromJSON err) => Manager -> OAuth2 -> URI -> PostBody -> ExceptT (OAuth2Error err) m ByteString

-- | Gets response body from a <tt>Response</tt> if 200 otherwise assume
--   <a>OAuth2Error</a>
handleOAuth2TokenResponse :: FromJSON err => Response ByteString -> Either (OAuth2Error err) ByteString

-- | Try to parses response as JSON, if failed, try to parse as like query
--   string.
parseResponseFlexible :: (FromJSON err, FromJSON a) => ByteString -> Either (OAuth2Error err) a

-- | Parses the response that contains not JSON but a Query String
parseResponseString :: (FromJSON err, FromJSON a) => ByteString -> Either (OAuth2Error err) a

-- | Set several header values: + userAgennt : <tt>hoauth2</tt> + accept :
--   `application/json`
addDefaultRequestHeaders :: Request -> Request

-- | Add Credential (client_id, client_secret) to the request post body.
clientSecretPost :: OAuth2 -> PostBody
instance GHC.Generics.Generic Network.OAuth.OAuth2.TokenRequest.Errors
instance GHC.Classes.Eq Network.OAuth.OAuth2.TokenRequest.Errors
instance GHC.Show.Show Network.OAuth.OAuth2.TokenRequest.Errors
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.TokenRequest.Errors
instance Data.Aeson.Types.ToJSON.ToJSON Network.OAuth.OAuth2.TokenRequest.Errors


-- | A lightweight oauth2 Haskell binding. See Readme for more details
module Network.OAuth.OAuth2

-- | See <a>authorizationUrlWithParams</a>
authorizationUrl :: OAuth2 -> URI

-- | Prepare the authorization URL. Redirect to this URL asking for user
--   interactive authentication.
authorizationUrlWithParams :: QueryParams -> OAuth2 -> URI

-- | Prepare the URL and the request body query for fetching an access
--   token.
accessTokenUrl :: OAuth2 -> ExchangeToken -> (URI, PostBody)

-- | Obtain a new access token by sending a Refresh Token to the
--   Authorization server.
refreshAccessTokenUrl :: OAuth2 -> RefreshToken -> (URI, PostBody)

-- | Exchange <tt>code</tt> for an Access Token with authenticate in
--   request header.
fetchAccessToken :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessToken2 :: MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Exchange <tt>code</tt> for an Access Token
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try <a>fetchAccessToken</a> which sends credential in
--   authorization http header, which is common case.
fetchAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token with authentication in
--   request header.
refreshAccessToken :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessToken2 :: MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessTokenInternal :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token.
--   
--   OAuth2 spec allows credential (<tt>client_id</tt>,
--   <tt>client_secret</tt>) to be sent either in the header (a.k.a
--   <a>ClientSecretBasic</a>). or as form/url params (a.k.a
--   <a>ClientSecretPost</a>).
--   
--   The OAuth provider can choose to implement only one, or both. Look for
--   API document from the OAuth provider you're dealing with. If you're
--   uncertain, try <a>refreshAccessToken</a> which sends credential in
--   authorization http header, which is common case.
refreshAccessTokenWithAuthMethod :: MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token

-- | Conduct post request and return response as JSON.
doJSONPostRequest :: (MonadIO m, FromJSON err, FromJSON a) => Manager -> OAuth2 -> URI -> PostBody -> ExceptT (OAuth2Error err) m a

-- | Conduct post request.
doSimplePostRequest :: (MonadIO m, FromJSON err) => Manager -> OAuth2 -> URI -> PostBody -> ExceptT (OAuth2Error err) m ByteString

-- | Gets response body from a <tt>Response</tt> if 200 otherwise assume
--   <a>OAuth2Error</a>
handleOAuth2TokenResponse :: FromJSON err => Response ByteString -> Either (OAuth2Error err) ByteString

-- | Try to parses response as JSON, if failed, try to parse as like query
--   string.
parseResponseFlexible :: (FromJSON err, FromJSON a) => ByteString -> Either (OAuth2Error err) a

-- | Parses the response that contains not JSON but a Query String
parseResponseString :: (FromJSON err, FromJSON a) => ByteString -> Either (OAuth2Error err) a

-- | Set several header values: + userAgennt : <tt>hoauth2</tt> + accept :
--   `application/json`
addDefaultRequestHeaders :: Request -> Request

-- | Add Credential (client_id, client_secret) to the request post body.
clientSecretPost :: OAuth2 -> PostBody

module Network.OAuth2.Experiment.Pkce
mkPkceParam :: MonadIO m => m PkceRequestParam
newtype CodeChallenge
CodeChallenge :: Text -> CodeChallenge
[unCodeChallenge] :: CodeChallenge -> Text
newtype CodeVerifier
CodeVerifier :: Text -> CodeVerifier
[unCodeVerifier] :: CodeVerifier -> Text
data CodeChallengeMethod
S256 :: CodeChallengeMethod
data PkceRequestParam
PkceRequestParam :: CodeVerifier -> CodeChallenge -> CodeChallengeMethod -> PkceRequestParam
[codeVerifier] :: PkceRequestParam -> CodeVerifier
[codeChallenge] :: PkceRequestParam -> CodeChallenge

-- | spec says optional but really it shall be s256 or can be omitted?
--   <a>https://datatracker.ietf.org/doc/html/rfc7636#section-4.3</a>
[codeChallengeMethod] :: PkceRequestParam -> CodeChallengeMethod
instance GHC.Show.Show Network.OAuth2.Experiment.Pkce.CodeVerifier
instance GHC.Show.Show Network.OAuth2.Experiment.Pkce.CodeChallengeMethod

module Network.OAuth2.Experiment.Utils
tlToBS :: Text -> ByteString
bs8ToLazyText :: ByteString -> Text
mapsToParams :: [Map Text Text] -> [(ByteString, ByteString)]

module Network.OAuth2.Experiment.Types
data GrantTypeFlow
AuthorizationCode :: GrantTypeFlow
ResourceOwnerPassword :: GrantTypeFlow
ClientCredentials :: GrantTypeFlow
class ToResponseTypeValue (a :: GrantTypeFlow)
toResponseTypeValue :: (ToResponseTypeValue a, IsString b) => b
toResponseTypeParam :: forall a b req. (ToResponseTypeValue a, IsString b) => req a -> Map b b

-- | Grant type query parameter has association with <a>GrantTypeFlow</a>
--   but not completely strict.
--   
--   e.g. Both <a>AuthorizationCode</a> and <a>ResourceOwnerPassword</a>
--   flow could support refresh token flow.
data GrantTypeValue
GTAuthorizationCode :: GrantTypeValue
GTPassword :: GrantTypeValue
GTClientCredentials :: GrantTypeValue
GTRefreshToken :: GrantTypeValue
newtype Scope
Scope :: Text -> Scope
[$sel:unScope:Scope] :: Scope -> Text
newtype ClientId
ClientId :: Text -> ClientId
[$sel:unClientId:ClientId] :: ClientId -> Text
newtype ClientSecret
ClientSecret :: Text -> ClientSecret
[$sel:unClientSecret:ClientSecret] :: ClientSecret -> Text

-- | In order to reuse some methods from legacy
--   <a>Network.OAuth.OAuth2</a>. Will be removed when Experiment module
--   becomes default.
toOAuth2Key :: ClientId -> ClientSecret -> OAuth2
newtype RedirectUri
RedirectUri :: URI -> RedirectUri
[$sel:unRedirectUri:RedirectUri] :: RedirectUri -> URI
newtype AuthorizeState
AuthorizeState :: Text -> AuthorizeState
[$sel:unAuthorizeState:AuthorizeState] :: AuthorizeState -> Text
newtype Username
Username :: Text -> Username
[$sel:unUsername:Username] :: Username -> Text
newtype Password
Password :: Text -> Password
[$sel:unPassword:Password] :: Password -> Text
class ToQueryParam a
toQueryParam :: ToQueryParam a => a -> Map Text Text
class HasIdpAppName (a :: GrantTypeFlow)
getIdpAppName :: HasIdpAppName a => IdpApplication a i -> Text
class HasAuthorizeRequest (a :: GrantTypeFlow) where {
    data AuthorizationRequest a;
    type MkAuthorizationRequestResponse a;
}
mkAuthorizeRequestParameter :: HasAuthorizeRequest a => IdpApplication a i -> AuthorizationRequest a
mkAuthorizeRequest :: HasAuthorizeRequest a => IdpApplication a i -> MkAuthorizationRequestResponse a
class HasTokenRequest (a :: GrantTypeFlow) where {
    
    -- | Each GrantTypeFlow has slightly different request parameter to /token
    --   endpoint.
    data TokenRequest a;
    
    -- | Only 'AuthorizationCode flow (but not resource owner password nor
    --   client credentials) will use <a>ExchangeToken</a> 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 -&gt; b' implies
    --   needing an exchange token
    type WithExchangeToken a b;
}
mkTokenRequest :: HasTokenRequest a => IdpApplication a i -> WithExchangeToken a (TokenRequest a)
conduitTokenRequest :: (HasTokenRequest a, MonadIO m) => IdpApplication a i -> Manager -> WithExchangeToken a (ExceptT (OAuth2Error Errors) m OAuth2Token)
class HasPkceAuthorizeRequest (a :: GrantTypeFlow)
mkPkceAuthorizeRequest :: (HasPkceAuthorizeRequest a, MonadIO m) => IdpApplication a i -> m (Text, CodeVerifier)
class HasPkceTokenRequest (b :: GrantTypeFlow)
conduitPkceTokenRequest :: (HasPkceTokenRequest b, MonadIO m) => IdpApplication b i -> Manager -> (ExchangeToken, CodeVerifier) -> ExceptT (OAuth2Error Errors) m OAuth2Token
class HasRefreshTokenRequest (a :: GrantTypeFlow) where {
    
    -- | <a>https://www.rfc-editor.org/rfc/rfc6749#page-47</a>
    data RefreshTokenRequest a;
}
mkRefreshTokenRequest :: HasRefreshTokenRequest a => IdpApplication a i -> RefreshToken -> RefreshTokenRequest a
conduitRefreshTokenRequest :: (HasRefreshTokenRequest a, MonadIO m) => IdpApplication a i -> Manager -> RefreshToken -> ExceptT (OAuth2Error Errors) m OAuth2Token
type family IdpUserInfo a
class HasUserInfoRequest (a :: GrantTypeFlow)
conduitUserInfoRequest :: (HasUserInfoRequest a, FromJSON (IdpUserInfo i)) => IdpApplication a i -> Manager -> AccessToken -> ExceptT ByteString IO (IdpUserInfo i)

-- | Shall IdpApplication has a field of 'Idp a'??
data Idp a
Idp :: URI -> URI -> URI -> (forall m. (FromJSON (IdpUserInfo a), MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m (IdpUserInfo a)) -> Idp a
[$sel:idpUserInfoEndpoint:Idp] :: Idp a -> URI
[$sel:idpAuthorizeEndpoint:Idp] :: Idp a -> URI
[$sel:idpTokenEndpoint:Idp] :: Idp a -> URI
[$sel:idpFetchUserInfo:Idp] :: Idp a -> forall m. (FromJSON (IdpUserInfo a), MonadIO m) => Manager -> AccessToken -> URI -> ExceptT ByteString m (IdpUserInfo a)
data family IdpApplication (a :: GrantTypeFlow) (i :: Type)
instance GHC.Show.Show Network.OAuth2.Experiment.Types.GrantTypeValue
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.GrantTypeValue
instance GHC.Classes.Ord Network.OAuth2.Experiment.Types.Scope
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Scope
instance GHC.Show.Show Network.OAuth2.Experiment.Types.Scope
instance Data.String.IsString Network.OAuth2.Experiment.Types.ClientId
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.ClientId
instance GHC.Show.Show Network.OAuth2.Experiment.Types.ClientId
instance Data.String.IsString Network.OAuth2.Experiment.Types.ClientSecret
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.ClientSecret
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.RedirectUri
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.AuthorizeState
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Username
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Password
instance Network.OAuth2.Experiment.Types.HasIdpAppName 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.HasIdpAppName 'Network.OAuth2.Experiment.Types.ResourceOwnerPassword
instance Network.OAuth2.Experiment.Types.HasIdpAppName 'Network.OAuth2.Experiment.Types.ClientCredentials
instance Network.OAuth2.Experiment.Types.HasAuthorizeRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.HasPkceAuthorizeRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Types.AuthorizationRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode)
instance Network.OAuth2.Experiment.Types.HasTokenRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.HasPkceTokenRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Types.TokenRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode)
instance Network.OAuth2.Experiment.Types.HasTokenRequest 'Network.OAuth2.Experiment.Types.ResourceOwnerPassword
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Types.TokenRequest 'Network.OAuth2.Experiment.Types.ResourceOwnerPassword)
instance Network.OAuth2.Experiment.Types.HasTokenRequest 'Network.OAuth2.Experiment.Types.ClientCredentials
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Types.TokenRequest 'Network.OAuth2.Experiment.Types.ClientCredentials)
instance Network.OAuth2.Experiment.Types.HasRefreshTokenRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Types.RefreshTokenRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode)
instance Network.OAuth2.Experiment.Types.HasRefreshTokenRequest 'Network.OAuth2.Experiment.Types.ResourceOwnerPassword
instance Network.OAuth2.Experiment.Types.HasUserInfoRequest 'Network.OAuth2.Experiment.Types.AuthorizationCode
instance Network.OAuth2.Experiment.Types.HasUserInfoRequest 'Network.OAuth2.Experiment.Types.ResourceOwnerPassword
instance Network.OAuth2.Experiment.Types.ToQueryParam a => Network.OAuth2.Experiment.Types.ToQueryParam (GHC.Maybe.Maybe a)
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.GrantTypeValue
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.ClientId
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.ClientSecret
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.Username
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.Password
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.AuthorizeState
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.RedirectUri
instance Network.OAuth2.Experiment.Types.ToQueryParam (Data.Set.Internal.Set Network.OAuth2.Experiment.Types.Scope)
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Pkce.CodeVerifier
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Pkce.CodeChallenge
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Pkce.CodeChallengeMethod
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth.OAuth2.Internal.ExchangeToken
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth.OAuth2.Internal.RefreshToken
instance Data.String.IsString Network.OAuth2.Experiment.Types.Password
instance Data.String.IsString Network.OAuth2.Experiment.Types.Username
instance Data.String.IsString Network.OAuth2.Experiment.Types.AuthorizeState
instance Data.String.IsString Network.OAuth2.Experiment.Types.Scope
instance Network.OAuth2.Experiment.Types.ToResponseTypeValue 'Network.OAuth2.Experiment.Types.AuthorizationCode


-- | This module contains a new way of doing OAuth2 authorization and
--   authentication in order to obtain Access Token and maybe Refresh Token
--   base on rfc6749.
--   
--   This module will become default in future release. (TBD but likely
--   3.0).
--   
--   The key concept/change is to introduce the <a>GrantTypeFlow</a>, which
--   determines the entire work flow per spec. Each work flow will have
--   slight different request parameters, which often time you'll see
--   different configuration when creating OAuth2 application in the IdP
--   developer application page.
--   
--   Here are supported flows
--   
--   <ol>
--   <li>Authorization Code. This flow requires authorize call to obtain an
--   authorize code, then exchange the code for tokens.</li>
--   <li>Resource Owner Password. This flow only requires to hit token
--   endpoint with, of course, username and password, to obtain
--   tokens.</li>
--   <li>Client Credentials. This flow also only requires to hit token
--   endpoint but with different parameters. Client credentials flow does
--   not involve an end user hence you won't be able to hit userinfo
--   endpoint with access token obtained.</li>
--   <li>PKCE (rfc7636). This is enhancement on top of authorization code
--   flow.</li>
--   </ol>
--   
--   Implicit flow is not supported because it is more for SPA (single page
--   app) and more or less obsolete by Authorization Code flow with PKCE.
--   
--   Here is quick sample for how to use vocabularies from this new module.
--   
--   Firstly, initialize your IdP (use google as example) and the
--   application.
--   
--   <pre>
--   data Google = Google deriving (Eq, Show)
--   googleIdp = Idp Google
--     Idp
--       { idpFetchUserInfo = authGetJSON @(IdpUserInfo Google),
--         idpAuthorizeEndpoint = [uri|https://accounts.google.com/o/oauth2/v2/auth|],
--         idpTokenEndpoint = [uri|https://oauth2.googleapis.com/token|],
--         idpUserInfoEndpoint = [uri|https://www.googleapis.com/oauth2/v2/userinfo|]
--       }
--   
--   fooApp :: IdpApplication 'AuthorizationCode Google
--   fooApp =
--     AuthorizationCodeIdpApplication
--       { idpAppClientId = "xxxxx",
--         idpAppClientSecret = "xxxxx",
--         idpAppScope =
--           Set.fromList
--             [ "https://www.googleapis.com/auth/userinfo.email",
--               "https://www.googleapis.com/auth/userinfo.profile"
--             ],
--         idpAppAuthorizeState = "CHANGE_ME",
--         idpAppAuthorizeExtraParams = Map.empty,
--         idpAppRedirectUri = [uri|http://localhost/oauth2/callback|],
--         idpAppName = "default-google-App",
--         idpAppTokenRequestAuthenticationMethod = ClientSecretBasic,
--         idp = googleIdp
--       }
--   </pre>
--   
--   Secondly, construct the authorize URL.
--   
--   <pre>
--   authorizeUrl = mkAuthorizeRequest fooApp
--   </pre>
--   
--   Thirdly, after a successful redirect with authorize code, you could
--   exchange for access token
--   
--   <pre>
--   mgr &lt;- liftIO $ newManager tlsManagerSettings
--   tokenResp &lt;- conduitTokenRequest fooApp mgr authorizeCode
--   </pre>
--   
--   Lastly, you probably like to fetch user info
--   
--   <pre>
--   conduitUserInfoRequest fooApp mgr (accessToken tokenResp)
--   </pre>
--   
--   Also you could find example from <tt>hoauth2-providers-tutorials</tt>
--   module.
module Network.OAuth2.Experiment
