hoauth2-2.15.1: src/Network/OAuth2/Experiment.hs
-- | This module contains a new way of doing OAuth2 authorization and authentication
-- in order to obtain an access token and maybe a refresh token based on RFC 6749.
--
-- This module will become the default in a future release.
--
-- The key concept is introducing grant flows, which determine the entire workflow per the spec.
-- Each workflow has slightly different request parameters, which is why you'll often see
-- different configuration options when creating an OAuth2 application in an IdP developer console.
--
-- Here are the supported flows:
--
-- 1. Authorization Code. This flow requires an authorize call to obtain an authorization code,
-- then exchange the code for tokens.
--
-- 2. Resource Owner Password. This flow only requires hitting the token endpoint with, of course,
-- username and password, to obtain tokens.
--
-- 3. Client Credentials. This flow also only requires hitting the token endpoint, but with different parameters.
-- The client credentials flow does not involve an end user, so you won't be able to hit the userinfo endpoint
-- with the access token you obtain.
--
-- 4. PKCE (RFC 7636). This is an enhancement on top of the authorization code flow.
--
-- The implicit flow is not supported because it is primarily for SPAs (single-page apps),
-- and it has been deprecated in favor of the authorization code flow with PKCE.
--
-- Here is a quick sample showing how to use the vocabulary from this module.
--
-- First, initialize your IdP (using Google as an example) and the application.
--
-- @
--
-- 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",
-- acClientAuthenticationMethod = ClientSecretBasic,
-- }
--
-- fooIdpApplication :: IdpApplication AuthorizationCodeApplication Google
-- fooIdpApplication = IdpApplication fooApp googleIdp
-- @
--
-- Second, construct the authorize URL.
--
-- @
-- authorizeUrl = mkAuthorizationRequest fooIdpApplication
-- @
--
-- Third, after a successful redirect with an authorization code,
-- you can exchange it for an access token.
--
-- @
-- mgr <- liftIO $ newManager tlsManagerSettings
-- tokenResp <- conduitTokenRequest fooIdpApplication mgr authorizeCode
-- @
--
-- If you'd like to fetch user info, use this method:
--
-- @
-- conduitUserInfoRequest fooIdpApplication mgr (accessToken tokenResp)
-- @
--
-- You can also find an example in the @hoauth2-providers-tutorial@ module.
module Network.OAuth2.Experiment (
-- * Application per Grant type
module Network.OAuth2.Experiment.Grants,
-- * Authorization Code
mkAuthorizationRequest,
mkPkceAuthorizeRequest,
-- * Device Authorization
module Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest,
conduitDeviceAuthorizationRequest,
pollDeviceTokenRequest,
-- * Token Request
module Network.OAuth2.Experiment.Flows.TokenRequest,
conduitPkceTokenRequest,
conduitTokenRequest,
-- * Refresh Token Request
module Network.OAuth2.Experiment.Flows.RefreshTokenRequest,
conduitRefreshTokenRequest,
-- * UserInfo Request
module Network.OAuth2.Experiment.Flows.UserInfoRequest,
conduitUserInfoRequest,
conduitUserInfoRequestWithCustomMethod,
-- * Types
module Network.OAuth2.Experiment.Types,
module Network.OAuth2.Experiment.Pkce,
module Network.OAuth2,
-- * Utils
module Network.OAuth2.Experiment.Utils,
) where
import Network.OAuth2 (ClientAuthenticationMethod (..))
import Network.OAuth2.Experiment.Flows
import Network.OAuth2.Experiment.Flows.DeviceAuthorizationRequest (
DeviceAuthorizationResponse (..),
)
import Network.OAuth2.Experiment.Flows.RefreshTokenRequest (
HasRefreshTokenRequest,
)
import Network.OAuth2.Experiment.Flows.TokenRequest (
ExchangeTokenInfo,
HasTokenRequest,
NoNeedExchangeToken (..),
TokenRequest,
)
import Network.OAuth2.Experiment.Flows.UserInfoRequest (
HasUserInfoRequest,
)
import Network.OAuth2.Experiment.Grants
import Network.OAuth2.Experiment.Pkce (
CodeVerifier (..),
)
import Network.OAuth2.Experiment.Types (
AuthorizeState (..),
ClientId (..),
ClientSecret (..),
Idp (..),
IdpApplication (..),
Password (..),
RedirectUri (..),
Scope (..),
Username (..),
)
import Network.OAuth2.Experiment.Utils (uriToText)