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


-- | Haskell OAuth2 authentication client
--   
--   This is Haskell binding of OAuth2 Authorization framework and Bearer
--   Token Usage framework.
@package hoauth2
@version 2.14.3

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 in practice it is S256
--   <a>https://datatracker.ietf.org/doc/html/rfc7636#section-4.3</a>
[codeChallengeMethod] :: PkceRequestParam -> CodeChallengeMethod
instance GHC.Internal.Show.Show Network.OAuth2.Experiment.Pkce.CodeChallengeMethod


-- | 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
data TokenResponseError
TokenResponseError :: TokenResponseErrorCode -> Maybe Text -> Maybe (URIRef Absolute) -> TokenResponseError
[tokenResponseError] :: TokenResponseError -> TokenResponseErrorCode
[tokenResponseErrorDescription] :: TokenResponseError -> Maybe Text
[tokenResponseErrorUri] :: TokenResponseError -> Maybe (URIRef Absolute)

-- | Token Error Responses
--   <a>https://tools.ietf.org/html/rfc6749#section-5.2</a>
data TokenResponseErrorCode
InvalidRequest :: TokenResponseErrorCode
InvalidClient :: TokenResponseErrorCode
InvalidGrant :: TokenResponseErrorCode
UnauthorizedClient :: TokenResponseErrorCode
UnsupportedGrantType :: TokenResponseErrorCode
InvalidScope :: TokenResponseErrorCode
UnknownErrorCode :: Text -> TokenResponseErrorCode
parseTokeResponseError :: ByteString -> TokenResponseError

-- | 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 :: forall (m :: Type -> Type). MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenResponseError m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessToken2 :: forall (m :: Type -> Type). MonadIO m => Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenResponseError m OAuth2Token

-- | <i>Deprecated: use <a>fetchAccessTokenWithAuthMethod</a></i>
fetchAccessTokenInternal :: forall (m :: Type -> Type). MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenResponseError 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 :: forall (m :: Type -> Type). MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> ExchangeToken -> ExceptT TokenResponseError m OAuth2Token

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

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessToken2 :: forall (m :: Type -> Type). MonadIO m => Manager -> OAuth2 -> RefreshToken -> ExceptT TokenResponseError m OAuth2Token

-- | <i>Deprecated: use <a>refreshAccessTokenWithAuthMethod</a></i>
refreshAccessTokenInternal :: forall (m :: Type -> Type). MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT TokenResponseError m OAuth2Token

-- | Fetch a new AccessToken using the Refresh Token.
--   
--   OAuth2 spec allows credential ("client_id", "client_secret") 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 :: forall (m :: Type -> Type). MonadIO m => ClientAuthenticationMethod -> Manager -> OAuth2 -> RefreshToken -> ExceptT TokenResponseError m OAuth2Token

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

-- | Conduct post request.
doSimplePostRequest :: forall (m :: Type -> Type). MonadIO m => Manager -> OAuth2 -> URI -> PostBody -> ExceptT TokenResponseError m ByteString

-- | Gets response body from a <tt>Response</tt> if 200 otherwise assume
--   <a>TokenResponseError</a>
handleOAuth2TokenResponse :: Response ByteString -> Either TokenResponseError ByteString

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

-- | Parses the response that contains not JSON but a Query String
parseResponseString :: FromJSON a => ByteString -> Either TokenResponseError a

-- | Add Basic Authentication header using client_id and client_secret.
addBasicAuth :: OAuth2 -> Request -> Request

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

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


-- | 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 :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Conduct an authorized GET request. Inject Access Token to
--   Authorization Header.
authGetBS :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m a

-- | Deprecated. Use <a>authGetJSONWithAuthMethod</a> instead.

-- | <i>Deprecated: use authGetJSONWithAuthMethod</i>
authGetJSONInternal :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => 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 :: forall (m :: Type -> Type). MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> ExceptT ByteString m ByteString

-- | <i>Deprecated: use authGetBSWithAuthMethod</i>
authGetBSInternal :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | Conduct POST request. Inject Access Token to http header
--   (Authorization)
authPostBS :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type). 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 :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m a

-- | <i>Deprecated: use <a>authPostJSONWithAuthMethod</a></i>
authPostJSONInternal :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => 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 :: forall (m :: Type -> Type). MonadIO m => APIAuthenticationMethod -> Manager -> AccessToken -> URI -> PostBody -> ExceptT ByteString m ByteString

-- | <i>Deprecated: use <a>authPostBSWithAuthMethod</a></i>
authPostBSInternal :: forall (m :: Type -> Type). 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.Eq Network.OAuth.OAuth2.HttpClient.APIAuthenticationMethod
instance GHC.Classes.Ord 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, it will stuck 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 AuthorizationResponseError
AuthorizationResponseError :: AuthorizationResponseErrorCode -> Maybe Text -> Maybe (URIRef Absolute) -> AuthorizationResponseError
[authorizationResponseError] :: AuthorizationResponseError -> AuthorizationResponseErrorCode
[authorizationResponseErrorDescription] :: AuthorizationResponseError -> Maybe Text
[authorizationResponseErrorUri] :: AuthorizationResponseError -> Maybe (URIRef Absolute)
data AuthorizationResponseErrorCode
InvalidRequest :: AuthorizationResponseErrorCode
UnauthorizedClient :: AuthorizationResponseErrorCode
AccessDenied :: AuthorizationResponseErrorCode
UnsupportedResponseType :: AuthorizationResponseErrorCode
InvalidScope :: AuthorizationResponseErrorCode
ServerError :: AuthorizationResponseErrorCode
TemporarilyUnavailable :: AuthorizationResponseErrorCode
UnknownErrorCode :: Text -> AuthorizationResponseErrorCode

-- | 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.Classes.Eq Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseError
instance GHC.Classes.Eq Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseErrorCode
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseError
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseErrorCode
instance GHC.Internal.Show.Show Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseError
instance GHC.Internal.Show.Show Network.OAuth.OAuth2.AuthorizationRequest.AuthorizationResponseErrorCode


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

-- | 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

-- | How would the Client (RP) authenticate itself?
--   
--   The client MUST NOT use more than one authentication method in each
--   request. Means use Authorization header or Post body.
--   
--   See more details
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-2.3</a>
--   <a>https://oauth.net/private-key-jwt/</a>
--   <a>https://www.rfc-editor.org/rfc/rfc7523.html</a>
data ClientAuthenticationMethod
ClientSecretBasic :: ClientAuthenticationMethod
ClientSecretPost :: ClientAuthenticationMethod
ClientAssertionJwt :: ClientAuthenticationMethod
newtype RefreshToken
RefreshToken :: Text -> RefreshToken
[rtoken] :: RefreshToken -> 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 -> Maybe Text -> Object -> OAuth2Token
[accessToken] :: OAuth2Token -> AccessToken

-- | Exists when <tt>offline_access</tt> scope is in the Authorization
--   Request 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 Authorization Request and
--   the provider supports OpenID protocol.
[idToken] :: OAuth2Token -> Maybe IdToken
[scope] :: OAuth2Token -> Maybe Text
[rawResponse] :: OAuth2Token -> Object

-- | Type synonym of post body content
type PostBody = [(ByteString, ByteString)]
uriToRequest :: MonadThrow m => URI -> m Request

-- | Authorization Code
newtype ExchangeToken
ExchangeToken :: Text -> ExchangeToken
[extoken] :: ExchangeToken -> Text
newtype AccessToken
AccessToken :: Text -> AccessToken
[atoken] :: AccessToken -> Text
newtype IdToken
IdToken :: Text -> IdToken
[idtoken] :: IdToken -> Text

-- | Type sysnonym of request query params
type QueryParams = [(ByteString, ByteString)]
defaultRequestHeaders :: [(HeaderName, ByteString)]
appendQueryParams :: [(ByteString, ByteString)] -> URIRef a -> URIRef a
hostLens :: Lens' Request ByteString
portLens :: Lens' Request Int
requestToUri :: Request -> URI

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

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

module Network.OAuth2.Experiment.Types

-- | <tt>Idp i</tt> consists various endpoints endpoints.
--   
--   The <tt>i</tt> is actually phantom type for information only (Idp
--   name) at this moment. And it is PolyKinds.
--   
--   Hence whenever <tt>Idp i</tt> or <tt>IdpApplication i a</tt> is used
--   as function parameter, PolyKinds need to be enabled.
data Idp (i :: k)
Idp :: URI -> URI -> URI -> Maybe URI -> Idp (i :: k)

-- | Userinfo Endpoint
[idpUserInfoEndpoint] :: Idp (i :: k) -> URI

-- | Authorization Endpoint
[idpAuthorizeEndpoint] :: Idp (i :: k) -> URI

-- | Token Endpoint
[idpTokenEndpoint] :: Idp (i :: k) -> URI

-- | Apparently not all IdP support device code flow
[idpDeviceAuthorizationEndpoint] :: Idp (i :: k) -> Maybe URI

-- | An OAuth2 Application "a" of IdP "i". "a" can be one of following
--   type:
--   
--   <ul>
--   <li><a>AuthorizationCodeApplication</a></li>
--   <li><a>DeviceAuthorizationApplication</a></li>
--   <li><a>ClientCredentialsApplication</a></li>
--   <li><a>ResourceOwnerPasswordApplication</a></li>
--   <li><a>JwtBearerApplication</a></li>
--   </ul>
data IdpApplication (i :: k) a
IdpApplication :: Idp i -> a -> IdpApplication (i :: k) a
[idp] :: IdpApplication (i :: k) a -> Idp i
[application] :: IdpApplication (i :: k) a -> a
newtype Scope
Scope :: Text -> Scope
[unScope] :: Scope -> Text

-- | Grant type query parameter has association with different GrantType
--   flows but not completely strict.
--   
--   e.g. Both AuthorizationCode and ResourceOwnerPassword flow could
--   support refresh token flow.
data GrantTypeValue
GTAuthorizationCode :: GrantTypeValue
GTPassword :: GrantTypeValue
GTClientCredentials :: GrantTypeValue
GTRefreshToken :: GrantTypeValue
GTJwtBearer :: GrantTypeValue
GTDeviceCode :: GrantTypeValue
data ResponseType
Code :: ResponseType
newtype ClientId
ClientId :: Text -> ClientId
[unClientId] :: ClientId -> Text

-- | Can be either "Client Secret" or JWT base on client authentication
--   method
newtype ClientSecret
ClientSecret :: Text -> ClientSecret
[unClientSecret] :: 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
[unRedirectUri] :: RedirectUri -> URI
newtype AuthorizeState
AuthorizeState :: Text -> AuthorizeState
[unAuthorizeState] :: AuthorizeState -> Text
newtype Username
Username :: Text -> Username
[unUsername] :: Username -> Text
newtype Password
Password :: Text -> Password
[unPassword] :: Password -> Text
class ToQueryParam a
toQueryParam :: ToQueryParam a => a -> Map Text Text
class HasOAuth2Key a
mkOAuth2Key :: HasOAuth2Key a => a -> OAuth2
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.AuthorizeState
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.ClientId
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.ClientSecret
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.GrantTypeValue
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Password
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.RedirectUri
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Scope
instance GHC.Classes.Eq Network.OAuth2.Experiment.Types.Username
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.AuthorizeState
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.ClientId
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.ClientSecret
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.Password
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.Scope
instance GHC.Internal.Data.String.IsString Network.OAuth2.Experiment.Types.Username
instance GHC.Classes.Ord Network.OAuth2.Experiment.Types.Scope
instance GHC.Internal.Show.Show Network.OAuth2.Experiment.Types.ClientId
instance GHC.Internal.Show.Show Network.OAuth2.Experiment.Types.GrantTypeValue
instance GHC.Internal.Show.Show Network.OAuth2.Experiment.Types.Scope
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.AuthorizeState
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.Pkce.CodeChallenge
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Pkce.CodeChallengeMethod
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Pkce.CodeVerifier
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth.OAuth2.Internal.ExchangeToken
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.GrantTypeValue
instance Network.OAuth2.Experiment.Types.ToQueryParam a => Network.OAuth2.Experiment.Types.ToQueryParam (GHC.Internal.Maybe.Maybe a)
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.Password
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.RedirectUri
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth.OAuth2.Internal.RefreshToken
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.ResponseType
instance Network.OAuth2.Experiment.Types.ToQueryParam (Data.Set.Internal.Set Network.OAuth2.Experiment.Types.Scope)
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Types.Username

module Network.OAuth2.Experiment.Flows.UserInfoRequest
class HasUserInfoRequest (a :: k)

-- | Standard approach of fetching /userinfo
conduitUserInfoRequest :: forall {k} (m :: Type -> Type) a b (i :: k). (MonadIO m, HasUserInfoRequest a, FromJSON b) => IdpApplication i a -> Manager -> AccessToken -> ExceptT ByteString m b

-- | Usually <a>conduitUserInfoRequest</a> is good enough. But some IdP has
--   different approach to fetch user information rather than GET. This
--   method gives the flexiblity.
conduitUserInfoRequestWithCustomMethod :: forall {k} (m :: Type -> Type) a b (i :: k). (MonadIO m, HasUserInfoRequest a, FromJSON b) => (Manager -> AccessToken -> URI -> ExceptT ByteString m b) -> IdpApplication i a -> Manager -> AccessToken -> ExceptT ByteString m b

module Network.OAuth2.Experiment.Flows.TokenRequest
class HasTokenRequestClientAuthenticationMethod a
getClientAuthenticationMethod :: HasTokenRequestClientAuthenticationMethod a => a -> ClientAuthenticationMethod

-- | Only Authorization Code Grant involves a Exchange Token (Authorization
--   Code). ResourceOwnerPassword and Client Credentials make token request
--   directly.
data NoNeedExchangeToken
NoNeedExchangeToken :: NoNeedExchangeToken
class (HasOAuth2Key a, HasTokenRequestClientAuthenticationMethod a) => HasTokenRequest a where {
    data TokenRequest a;
    type ExchangeTokenInfo a;
}

-- | Only 'AuthorizationCode flow (but not resource owner password nor
--   client credentials) will use <tt>ExchangeToken</tt> 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
mkTokenRequestParam :: HasTokenRequest a => a -> ExchangeTokenInfo a -> TokenRequest a

-- | <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3</a>
conduitTokenRequest :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> ExchangeTokenInfo a -> ExceptT TokenResponseError m OAuth2Token

-- | <a>https://datatracker.ietf.org/doc/html/rfc7636#section-4.5</a>
conduitPkceTokenRequest :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> (ExchangeTokenInfo a, CodeVerifier) -> ExceptT TokenResponseError m OAuth2Token
conduitTokenRequestInternal :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> (ExchangeTokenInfo a, Maybe CodeVerifier) -> ExceptT TokenResponseError m OAuth2Token
doTokenRequestInternal :: forall (m :: Type -> Type) a. (MonadIO m, FromJSON a) => ClientAuthenticationMethod -> Manager -> OAuth2 -> URI -> PostBody -> ExceptT TokenResponseError m a

module Network.OAuth2.Experiment.Grants.JwtBearer

-- | An Application that supports "JWT Bearer" flow
--   
--   <a>https://datatracker.ietf.org/doc/html/rfc7523</a>
data JwtBearerApplication
JwtBearerApplication :: Text -> ByteString -> JwtBearerApplication
[jbName] :: JwtBearerApplication -> Text
[jbJwtAssertion] :: JwtBearerApplication -> ByteString
instance Network.OAuth2.Experiment.Types.HasOAuth2Key Network.OAuth2.Experiment.Grants.JwtBearer.JwtBearerApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequestClientAuthenticationMethod Network.OAuth2.Experiment.Grants.JwtBearer.JwtBearerApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequest Network.OAuth2.Experiment.Grants.JwtBearer.JwtBearerApplication
instance Network.OAuth2.Experiment.Flows.UserInfoRequest.HasUserInfoRequest Network.OAuth2.Experiment.Grants.JwtBearer.JwtBearerApplication
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Flows.TokenRequest.TokenRequest Network.OAuth2.Experiment.Grants.JwtBearer.JwtBearerApplication)

module Network.OAuth2.Experiment.Grants.ClientCredentials

-- | An Application that supports "Client Credentials" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.4</a>
data ClientCredentialsApplication
ClientCredentialsApplication :: ClientId -> ClientSecret -> Text -> Set Scope -> Map Text Text -> ClientAuthenticationMethod -> ClientCredentialsApplication
[ccClientId] :: ClientCredentialsApplication -> ClientId
[ccClientSecret] :: ClientCredentialsApplication -> ClientSecret
[ccName] :: ClientCredentialsApplication -> Text
[ccScope] :: ClientCredentialsApplication -> Set Scope
[ccTokenRequestExtraParams] :: ClientCredentialsApplication -> Map Text Text
[ccTokenRequestAuthenticationMethod] :: ClientCredentialsApplication -> ClientAuthenticationMethod
instance Network.OAuth2.Experiment.Types.HasOAuth2Key Network.OAuth2.Experiment.Grants.ClientCredentials.ClientCredentialsApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequestClientAuthenticationMethod Network.OAuth2.Experiment.Grants.ClientCredentials.ClientCredentialsApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequest Network.OAuth2.Experiment.Grants.ClientCredentials.ClientCredentialsApplication
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Flows.TokenRequest.TokenRequest Network.OAuth2.Experiment.Grants.ClientCredentials.ClientCredentialsApplication)

module Network.OAuth2.Experiment.Flows.RefreshTokenRequest
data RefreshTokenRequest
RefreshTokenRequest :: RefreshToken -> GrantTypeValue -> Set Scope -> Maybe ClientId -> Maybe ClientSecret -> RefreshTokenRequest
[rrRefreshToken] :: RefreshTokenRequest -> RefreshToken
[rrGrantType] :: RefreshTokenRequest -> GrantTypeValue
[rrScope] :: RefreshTokenRequest -> Set Scope
[rrClientId] :: RefreshTokenRequest -> Maybe ClientId
[rrClientSecret] :: RefreshTokenRequest -> Maybe ClientSecret
class (HasOAuth2Key a, HasTokenRequestClientAuthenticationMethod a) => HasRefreshTokenRequest a

-- | Make Refresh Token Request parameters |
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-6</a>
mkRefreshTokenRequestParam :: HasRefreshTokenRequest a => a -> RefreshToken -> RefreshTokenRequest

-- | Make Refresh Token Request
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-6</a>
conduitRefreshTokenRequest :: forall {k} (m :: Type -> Type) a (i :: k). (MonadIO m, HasRefreshTokenRequest a) => IdpApplication i a -> Manager -> RefreshToken -> ExceptT TokenResponseError m OAuth2Token
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Flows.RefreshTokenRequest.RefreshTokenRequest

module Network.OAuth2.Experiment.Grants.ResourceOwnerPassword

-- | An Application that supports "Resource Owner Password" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.3</a>
data ResourceOwnerPasswordApplication
ResourceOwnerPasswordApplication :: ClientId -> ClientSecret -> Text -> Set Scope -> Username -> Password -> Map Text Text -> ClientAuthenticationMethod -> ResourceOwnerPasswordApplication
[ropClientId] :: ResourceOwnerPasswordApplication -> ClientId
[ropClientSecret] :: ResourceOwnerPasswordApplication -> ClientSecret
[ropName] :: ResourceOwnerPasswordApplication -> Text
[ropScope] :: ResourceOwnerPasswordApplication -> Set Scope
[ropUserName] :: ResourceOwnerPasswordApplication -> Username
[ropPassword] :: ResourceOwnerPasswordApplication -> Password
[ropTokenRequestExtraParams] :: ResourceOwnerPasswordApplication -> Map Text Text
[ropTokenRequestAuthenticationMethod] :: ResourceOwnerPasswordApplication -> ClientAuthenticationMethod
instance Network.OAuth2.Experiment.Types.HasOAuth2Key Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication
instance Network.OAuth2.Experiment.Flows.RefreshTokenRequest.HasRefreshTokenRequest Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequestClientAuthenticationMethod Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequest Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication
instance Network.OAuth2.Experiment.Flows.UserInfoRequest.HasUserInfoRequest Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Flows.TokenRequest.TokenRequest Network.OAuth2.Experiment.Grants.ResourceOwnerPassword.ResourceOwnerPasswordApplication)

module Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest
newtype DeviceCode
DeviceCode :: Text -> DeviceCode

-- | <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.2</a>
data DeviceAuthorizationResponse
DeviceAuthorizationResponse :: DeviceCode -> Text -> URI -> Maybe URI -> Integer -> Maybe Int -> DeviceAuthorizationResponse
[deviceCode] :: DeviceAuthorizationResponse -> DeviceCode
[userCode] :: DeviceAuthorizationResponse -> Text
[verificationUri] :: DeviceAuthorizationResponse -> URI
[verificationUriComplete] :: DeviceAuthorizationResponse -> Maybe URI
[expiresIn] :: DeviceAuthorizationResponse -> Integer
[interval] :: DeviceAuthorizationResponse -> Maybe Int
data DeviceAuthorizationRequestParam
DeviceAuthorizationRequestParam :: Set Scope -> Maybe ClientId -> Map Text Text -> DeviceAuthorizationRequestParam
[arScope] :: DeviceAuthorizationRequestParam -> Set Scope
[arClientId] :: DeviceAuthorizationRequestParam -> Maybe ClientId
[arExtraParams] :: DeviceAuthorizationRequestParam -> Map Text Text
class HasOAuth2Key a => HasDeviceAuthorizationRequest a

-- | Create Device Authorization Request parameters
--   <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.1</a>
mkDeviceAuthorizationRequestParam :: HasDeviceAuthorizationRequest a => a -> DeviceAuthorizationRequestParam

-- | Makes Device Authorization Request
--   <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.1</a>
conduitDeviceAuthorizationRequest :: forall {k} (m :: Type -> Type) a (i :: k). (MonadIO m, HasDeviceAuthorizationRequest a) => IdpApplication i a -> Manager -> ExceptT ByteString m DeviceAuthorizationResponse
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest.DeviceAuthorizationResponse
instance Data.Aeson.Types.FromJSON.FromJSON Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest.DeviceCode
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest.DeviceAuthorizationRequestParam
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest.DeviceCode

module Network.OAuth2.Experiment.Grants.DeviceAuthorization

-- | An Application that supports "Device Authorization Grant"
--   
--   <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.1</a>
data DeviceAuthorizationApplication
DeviceAuthorizationApplication :: Text -> ClientId -> ClientSecret -> Set Scope -> Map Text Text -> Maybe ClientAuthenticationMethod -> DeviceAuthorizationApplication
[daName] :: DeviceAuthorizationApplication -> Text
[daClientId] :: DeviceAuthorizationApplication -> ClientId
[daClientSecret] :: DeviceAuthorizationApplication -> ClientSecret
[daScope] :: DeviceAuthorizationApplication -> Set Scope

-- | Additional parameters to the device authorization request. Most of
--   identity providers follow the spec strictly but AzureAD requires
--   "tenant" parameter.
[daAuthorizationRequestExtraParam] :: DeviceAuthorizationApplication -> Map Text Text

-- | The spec requires similar authentication method as /token request.
--   Most of identity providers doesn't required it but some does like
--   Okta.
[daAuthorizationRequestAuthenticationMethod] :: DeviceAuthorizationApplication -> Maybe ClientAuthenticationMethod
pollDeviceTokenRequest :: forall {k} (m :: Type -> Type) (i :: k). MonadIO m => IdpApplication i DeviceAuthorizationApplication -> Manager -> DeviceAuthorizationResponse -> ExceptT TokenResponseError m OAuth2Token
instance Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest.HasDeviceAuthorizationRequest Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication
instance Network.OAuth2.Experiment.Types.HasOAuth2Key Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequestClientAuthenticationMethod Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequest Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication
instance Network.OAuth2.Experiment.Flows.UserInfoRequest.HasUserInfoRequest Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Flows.TokenRequest.TokenRequest Network.OAuth2.Experiment.Grants.DeviceAuthorization.DeviceAuthorizationApplication)

module Network.OAuth2.Experiment.Flows.AuthorizationRequest
data AuthorizationRequestParam
AuthorizationRequestParam :: Set Scope -> AuthorizeState -> ClientId -> Maybe RedirectUri -> ResponseType -> Map Text Text -> AuthorizationRequestParam
[arScope] :: AuthorizationRequestParam -> Set Scope
[arState] :: AuthorizationRequestParam -> AuthorizeState
[arClientId] :: AuthorizationRequestParam -> ClientId
[arRedirectUri] :: AuthorizationRequestParam -> Maybe RedirectUri

-- | It could be optional there is only one redirect_uri registered. See:
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-3.1.2.3</a>
[arResponseType] :: AuthorizationRequestParam -> ResponseType
[arExtraParams] :: AuthorizationRequestParam -> Map Text Text
class HasAuthorizeRequest a

-- | Constructs Authorization Code request parameters |
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1</a>
mkAuthorizationRequestParam :: HasAuthorizeRequest a => a -> AuthorizationRequestParam

-- | Constructs Authorization Code request URI
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1</a>
mkAuthorizationRequest :: forall {k} a (i :: k). HasAuthorizeRequest a => IdpApplication i a -> URI

-- | <a>https://datatracker.ietf.org/doc/html/rfc7636</a>
class HasAuthorizeRequest a => HasPkceAuthorizeRequest a
mkPkceAuthorizeRequestParam :: (HasPkceAuthorizeRequest a, MonadIO m) => a -> m (AuthorizationRequestParam, CodeVerifier)

-- | Constructs Authorization Code (PKCE) request URI and the Code
--   Verifier. <a>https://datatracker.ietf.org/doc/html/rfc7636</a>
mkPkceAuthorizeRequest :: forall {k} m a (i :: k). (MonadIO m, HasPkceAuthorizeRequest a) => IdpApplication i a -> m (URI, CodeVerifier)
instance Network.OAuth2.Experiment.Types.ToQueryParam Network.OAuth2.Experiment.Flows.AuthorizationRequest.AuthorizationRequestParam

module Network.OAuth2.Experiment.Grants.AuthorizationCode

-- | An Application that supports "Authorization code" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1</a>
data AuthorizationCodeApplication
AuthorizationCodeApplication :: Text -> ClientId -> ClientSecret -> Set Scope -> URI -> AuthorizeState -> Map Text Text -> ClientAuthenticationMethod -> AuthorizationCodeApplication
[acName] :: AuthorizationCodeApplication -> Text
[acClientId] :: AuthorizationCodeApplication -> ClientId
[acClientSecret] :: AuthorizationCodeApplication -> ClientSecret
[acScope] :: AuthorizationCodeApplication -> Set Scope
[acRedirectUri] :: AuthorizationCodeApplication -> URI
[acAuthorizeState] :: AuthorizationCodeApplication -> AuthorizeState
[acAuthorizeRequestExtraParams] :: AuthorizationCodeApplication -> Map Text Text
[acTokenRequestAuthenticationMethod] :: AuthorizationCodeApplication -> ClientAuthenticationMethod
instance Network.OAuth2.Experiment.Flows.AuthorizationRequest.HasAuthorizeRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Types.HasOAuth2Key Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Flows.AuthorizationRequest.HasPkceAuthorizeRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Flows.RefreshTokenRequest.HasRefreshTokenRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Flows.TokenRequest.HasTokenRequestClientAuthenticationMethod Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Flows.UserInfoRequest.HasUserInfoRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication
instance Network.OAuth2.Experiment.Types.ToQueryParam (Network.OAuth2.Experiment.Flows.TokenRequest.TokenRequest Network.OAuth2.Experiment.Grants.AuthorizationCode.AuthorizationCodeApplication)


-- | 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.
--   
--   The key concept/change is to introduce the Grant flow, 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) given it is deprecated 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>
--   import Network.OAuth2.Experiment
--   import URI.ByteString.QQ
--   
--   data Google = Google deriving (Eq, Show)
--   
--   googleIdp :: Idp Google
--   googleIdp =
--     Idp
--       { 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|]
--       , idpDeviceAuthorizationEndpoint = Just [uri|https://oauth2.googleapis.com/device/code|]
--       }
--   
--   fooApp :: AuthorizationCodeApplication
--   fooApp =
--     AuthorizationCodeApplication
--       { acClientId = "xxxxx",
--         acClientSecret = "xxxxx",
--         acScope =
--           Set.fromList
--             [ "https://www.googleapis.com/auth/userinfo.email",
--               "https://www.googleapis.com/auth/userinfo.profile"
--             ],
--         acAuthorizeState = "CHANGE_ME",
--         acAuthorizeRequestExtraParams = Map.empty,
--         acRedirectUri = [uri|http://localhost/oauth2/callback|],
--         acName = "sample-google-authorization-code-app",
--         acTokenRequestAuthenticationMethod = ClientSecretBasic,
--       }
--   
--   fooIdpApplication :: IdpApplication AuthorizationCodeApplication Google
--   fooIdpApplication = IdpApplication fooApp googleIdp
--   </pre>
--   
--   Secondly, construct the authorize URL.
--   
--   <pre>
--   authorizeUrl = mkAuthorizationRequest fooIdpApplication
--   </pre>
--   
--   Thirdly, after a successful redirect with authorize code, you could
--   exchange for access token
--   
--   <pre>
--   mgr &lt;- liftIO $ newManager tlsManagerSettings
--   tokenResp &lt;- conduitTokenRequest fooIdpApplication mgr authorizeCode
--   </pre>
--   
--   If you'd like to fetch user info, uses this method
--   
--   <pre>
--   conduitUserInfoRequest fooIdpApplication mgr (accessToken tokenResp)
--   </pre>
--   
--   You could also find example from <tt>hoauth2-providers-tutorials</tt>
--   module.
module Network.OAuth2.Experiment

-- | An Application that supports "Device Authorization Grant"
--   
--   <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.1</a>
data DeviceAuthorizationApplication
DeviceAuthorizationApplication :: Text -> ClientId -> ClientSecret -> Set Scope -> Map Text Text -> Maybe ClientAuthenticationMethod -> DeviceAuthorizationApplication
[daName] :: DeviceAuthorizationApplication -> Text
[daClientId] :: DeviceAuthorizationApplication -> ClientId
[daClientSecret] :: DeviceAuthorizationApplication -> ClientSecret
[daScope] :: DeviceAuthorizationApplication -> Set Scope

-- | Additional parameters to the device authorization request. Most of
--   identity providers follow the spec strictly but AzureAD requires
--   "tenant" parameter.
[daAuthorizationRequestExtraParam] :: DeviceAuthorizationApplication -> Map Text Text

-- | The spec requires similar authentication method as /token request.
--   Most of identity providers doesn't required it but some does like
--   Okta.
[daAuthorizationRequestAuthenticationMethod] :: DeviceAuthorizationApplication -> Maybe ClientAuthenticationMethod
pollDeviceTokenRequest :: forall {k} (m :: Type -> Type) (i :: k). MonadIO m => IdpApplication i DeviceAuthorizationApplication -> Manager -> DeviceAuthorizationResponse -> ExceptT TokenResponseError m OAuth2Token

-- | An Application that supports "Authorization code" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1</a>
data AuthorizationCodeApplication
AuthorizationCodeApplication :: Text -> ClientId -> ClientSecret -> Set Scope -> URI -> AuthorizeState -> Map Text Text -> ClientAuthenticationMethod -> AuthorizationCodeApplication
[acName] :: AuthorizationCodeApplication -> Text
[acClientId] :: AuthorizationCodeApplication -> ClientId
[acClientSecret] :: AuthorizationCodeApplication -> ClientSecret
[acScope] :: AuthorizationCodeApplication -> Set Scope
[acRedirectUri] :: AuthorizationCodeApplication -> URI
[acAuthorizeState] :: AuthorizationCodeApplication -> AuthorizeState
[acAuthorizeRequestExtraParams] :: AuthorizationCodeApplication -> Map Text Text
[acTokenRequestAuthenticationMethod] :: AuthorizationCodeApplication -> ClientAuthenticationMethod

-- | An Application that supports "Client Credentials" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.4</a>
data ClientCredentialsApplication
ClientCredentialsApplication :: ClientId -> ClientSecret -> Text -> Set Scope -> Map Text Text -> ClientAuthenticationMethod -> ClientCredentialsApplication
[ccClientId] :: ClientCredentialsApplication -> ClientId
[ccClientSecret] :: ClientCredentialsApplication -> ClientSecret
[ccName] :: ClientCredentialsApplication -> Text
[ccScope] :: ClientCredentialsApplication -> Set Scope
[ccTokenRequestExtraParams] :: ClientCredentialsApplication -> Map Text Text
[ccTokenRequestAuthenticationMethod] :: ClientCredentialsApplication -> ClientAuthenticationMethod

-- | An Application that supports "JWT Bearer" flow
--   
--   <a>https://datatracker.ietf.org/doc/html/rfc7523</a>
data JwtBearerApplication
JwtBearerApplication :: Text -> ByteString -> JwtBearerApplication
[jbName] :: JwtBearerApplication -> Text
[jbJwtAssertion] :: JwtBearerApplication -> ByteString

-- | An Application that supports "Resource Owner Password" flow
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.3</a>
data ResourceOwnerPasswordApplication
ResourceOwnerPasswordApplication :: ClientId -> ClientSecret -> Text -> Set Scope -> Username -> Password -> Map Text Text -> ClientAuthenticationMethod -> ResourceOwnerPasswordApplication
[ropClientId] :: ResourceOwnerPasswordApplication -> ClientId
[ropClientSecret] :: ResourceOwnerPasswordApplication -> ClientSecret
[ropName] :: ResourceOwnerPasswordApplication -> Text
[ropScope] :: ResourceOwnerPasswordApplication -> Set Scope
[ropUserName] :: ResourceOwnerPasswordApplication -> Username
[ropPassword] :: ResourceOwnerPasswordApplication -> Password
[ropTokenRequestExtraParams] :: ResourceOwnerPasswordApplication -> Map Text Text
[ropTokenRequestAuthenticationMethod] :: ResourceOwnerPasswordApplication -> ClientAuthenticationMethod
class HasAuthorizeRequest a

-- | Constructs Authorization Code request URI
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1</a>
mkAuthorizationRequest :: forall {k} a (i :: k). HasAuthorizeRequest a => IdpApplication i a -> URI

-- | Constructs Authorization Code (PKCE) request URI and the Code
--   Verifier. <a>https://datatracker.ietf.org/doc/html/rfc7636</a>
mkPkceAuthorizeRequest :: forall {k} m a (i :: k). (MonadIO m, HasPkceAuthorizeRequest a) => IdpApplication i a -> m (URI, CodeVerifier)

-- | <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.2</a>
data DeviceAuthorizationResponse
DeviceAuthorizationResponse :: DeviceCode -> Text -> URI -> Maybe URI -> Integer -> Maybe Int -> DeviceAuthorizationResponse
[deviceCode] :: DeviceAuthorizationResponse -> DeviceCode
[userCode] :: DeviceAuthorizationResponse -> Text
[verificationUri] :: DeviceAuthorizationResponse -> URI
[verificationUriComplete] :: DeviceAuthorizationResponse -> Maybe URI
[expiresIn] :: DeviceAuthorizationResponse -> Integer
[interval] :: DeviceAuthorizationResponse -> Maybe Int
class HasOAuth2Key a => HasDeviceAuthorizationRequest a

-- | Makes Device Authorization Request
--   <a>https://www.rfc-editor.org/rfc/rfc8628#section-3.1</a>
conduitDeviceAuthorizationRequest :: forall {k} (m :: Type -> Type) a (i :: k). (MonadIO m, HasDeviceAuthorizationRequest a) => IdpApplication i a -> Manager -> ExceptT ByteString m DeviceAuthorizationResponse
class (HasOAuth2Key a, HasTokenRequestClientAuthenticationMethod a) => HasTokenRequest a where {
    data TokenRequest a;
    type ExchangeTokenInfo a;
}
data family TokenRequest a
type family ExchangeTokenInfo a

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

-- | <a>https://datatracker.ietf.org/doc/html/rfc7636#section-4.5</a>
conduitPkceTokenRequest :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> (ExchangeTokenInfo a, CodeVerifier) -> ExceptT TokenResponseError m OAuth2Token

-- | <a>https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3</a>
conduitTokenRequest :: forall {k} a (m :: Type -> Type) (i :: k). (HasTokenRequest a, ToQueryParam (TokenRequest a), MonadIO m) => IdpApplication i a -> Manager -> ExchangeTokenInfo a -> ExceptT TokenResponseError m OAuth2Token
class (HasOAuth2Key a, HasTokenRequestClientAuthenticationMethod a) => HasRefreshTokenRequest a

-- | Make Refresh Token Request
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-6</a>
conduitRefreshTokenRequest :: forall {k} (m :: Type -> Type) a (i :: k). (MonadIO m, HasRefreshTokenRequest a) => IdpApplication i a -> Manager -> RefreshToken -> ExceptT TokenResponseError m OAuth2Token
newtype AuthorizeState
AuthorizeState :: Text -> AuthorizeState
[unAuthorizeState] :: AuthorizeState -> Text
newtype ClientId
ClientId :: Text -> ClientId
[unClientId] :: ClientId -> Text

-- | Can be either "Client Secret" or JWT base on client authentication
--   method
newtype ClientSecret
ClientSecret :: Text -> ClientSecret
[unClientSecret] :: ClientSecret -> Text
class HasOAuth2Key a

-- | <tt>Idp i</tt> consists various endpoints endpoints.
--   
--   The <tt>i</tt> is actually phantom type for information only (Idp
--   name) at this moment. And it is PolyKinds.
--   
--   Hence whenever <tt>Idp i</tt> or <tt>IdpApplication i a</tt> is used
--   as function parameter, PolyKinds need to be enabled.
data Idp (i :: k)
Idp :: URI -> URI -> URI -> Maybe URI -> Idp (i :: k)

-- | Userinfo Endpoint
[idpUserInfoEndpoint] :: Idp (i :: k) -> URI

-- | Authorization Endpoint
[idpAuthorizeEndpoint] :: Idp (i :: k) -> URI

-- | Token Endpoint
[idpTokenEndpoint] :: Idp (i :: k) -> URI

-- | Apparently not all IdP support device code flow
[idpDeviceAuthorizationEndpoint] :: Idp (i :: k) -> Maybe URI

-- | An OAuth2 Application "a" of IdP "i". "a" can be one of following
--   type:
--   
--   <ul>
--   <li><a>AuthorizationCodeApplication</a></li>
--   <li><a>DeviceAuthorizationApplication</a></li>
--   <li><a>ClientCredentialsApplication</a></li>
--   <li><a>ResourceOwnerPasswordApplication</a></li>
--   <li><a>JwtBearerApplication</a></li>
--   </ul>
data IdpApplication (i :: k) a
IdpApplication :: Idp i -> a -> IdpApplication (i :: k) a
[idp] :: IdpApplication (i :: k) a -> Idp i
[application] :: IdpApplication (i :: k) a -> a
newtype Password
Password :: Text -> Password
[unPassword] :: Password -> Text
newtype RedirectUri
RedirectUri :: URI -> RedirectUri
[unRedirectUri] :: RedirectUri -> URI
newtype Scope
Scope :: Text -> Scope
[unScope] :: Scope -> Text
newtype Username
Username :: Text -> Username
[unUsername] :: Username -> Text
newtype CodeVerifier
CodeVerifier :: Text -> CodeVerifier
[unCodeVerifier] :: CodeVerifier -> Text

-- | How would the Client (RP) authenticate itself?
--   
--   The client MUST NOT use more than one authentication method in each
--   request. Means use Authorization header or Post body.
--   
--   See more details
--   
--   <a>https://www.rfc-editor.org/rfc/rfc6749#section-2.3</a>
--   <a>https://oauth.net/private-key-jwt/</a>
--   <a>https://www.rfc-editor.org/rfc/rfc7523.html</a>
data ClientAuthenticationMethod
ClientSecretBasic :: ClientAuthenticationMethod
ClientSecretPost :: ClientAuthenticationMethod
ClientAssertionJwt :: ClientAuthenticationMethod
uriToText :: URI -> Text
