yesod-auth-oauth2/src/Network/OAuth/OAuth2/Compat.hs
patrick brisbin 3700a89ada Update .Compat for hoauth2-2.9.0
The only breaking change seems to be the error type, which we were
already wrapping in `CPP` and our own `Errors` synonym for 2.7. All this
change does is add a 2.9 case and move some thing around so it's
syntactically nicer.
2023-10-30 16:38:12 -04:00

172 lines
5.2 KiB
Haskell

{-# LANGUAGE CPP #-}
module Network.OAuth.OAuth2.Compat
( OAuth2 (..)
, OAuth2Result
, Errors
, authorizationUrl
, fetchAccessToken
, fetchAccessToken2
, authGetBS
-- * Re-exports
, module Network.OAuth.OAuth2
) where
import Data.ByteString.Lazy (ByteString)
import Data.Text (Text)
import Network.HTTP.Conduit (Manager)
import Network.OAuth.OAuth2
( AccessToken (..)
, ExchangeToken (..)
, OAuth2Token (..)
, RefreshToken (..)
)
import qualified Network.OAuth.OAuth2 as OAuth2
import URI.ByteString
#if MIN_VERSION_hoauth2(2,2,0)
import Control.Monad.Trans.Except (ExceptT, runExceptT)
import Data.Maybe (fromMaybe)
#endif
#if MIN_VERSION_hoauth2(2,9,0)
import Network.OAuth.OAuth2.TokenRequest (TokenResponseError)
type Errors = TokenResponseError
#elif MIN_VERSION_hoauth2(2,7,0)
import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
type Errors = TokenRequestError
#else
import qualified Network.OAuth.OAuth2.TokenRequest as LegacyTokenRequest
import Network.OAuth.OAuth2 (OAuth2Error)
type Errors = OAuth2Error LegacyTokenRequest.Errors
#endif
{-# ANN module ("HLint: ignore Use fewer imports" :: String) #-}
data OAuth2 = OAuth2
{ oauth2ClientId :: Text
, oauth2ClientSecret :: Maybe Text
, oauth2AuthorizeEndpoint :: URIRef Absolute
, oauth2TokenEndpoint :: URIRef Absolute
, oauth2RedirectUri :: Maybe (URIRef Absolute)
}
type OAuth2Result err a = Either err a
authorizationUrl :: OAuth2 -> URI
authorizationUrl = OAuth2.authorizationUrl . getOAuth2
fetchAccessToken
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessToken = fetchAccessTokenBasic
fetchAccessToken2
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessToken2 = fetchAccessTokenPost
authGetBS :: Manager -> AccessToken -> URI -> IO (Either ByteString ByteString)
authGetBS m a u = runOAuth2 $ OAuth2.authGetBS m a u
-- Normalize the rename of record fields at hoauth2-2.0. Our type is the newer
-- names and we up-convert if hoauth2-1.x is in use. getClientSecret and
-- getRedirectUri handle the differences in hoauth2-2.2 and 2.3.
#if MIN_VERSION_hoauth2(2,0,0)
getOAuth2 :: OAuth2 -> OAuth2.OAuth2
getOAuth2 o = OAuth2.OAuth2
{ OAuth2.oauth2ClientId = oauth2ClientId o
, OAuth2.oauth2ClientSecret = getClientSecret $ oauth2ClientSecret o
, OAuth2.oauth2AuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauth2TokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauth2RedirectUri = getRedirectUri $ oauth2RedirectUri o
}
#else
getOAuth2 :: OAuth2 -> OAuth2.OAuth2
getOAuth2 o = OAuth2.OAuth2
{ OAuth2.oauthClientId = oauth2ClientId o
, OAuth2.oauthClientSecret = getClientSecret $ oauth2ClientSecret o
, OAuth2.oauthOAuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauthAccessTokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauthCallback = getRedirectUri $ oauth2RedirectUri o
}
#endif
-- hoauth2-2.2 made oauth2ClientSecret non-Maybe, after 2.0 had just made it
-- Maybe so we have to adjust, twice. TODO: change ours type to non-Maybe (major
-- bump) and reverse this to up-convert with Just in pre-2.2.
#if MIN_VERSION_hoauth2(2,2,0)
getClientSecret :: Maybe Text -> Text
getClientSecret =
fromMaybe $ error "Cannot use OAuth2.oauth2ClientSecret with Nothing"
#else
getClientSecret :: Maybe Text -> Maybe Text
getClientSecret = id
#endif
-- hoauth2-2.3 then made oauth2RedirectUri non-Maybe too. We logically rely on
-- instantiating with Nothing at definition-time, then setting it to the
-- callback at use-time, which means we can't just change our type and invert
-- this shim; we'll have to do something much more pervasive to avoid this
-- fromMaybe.
#if MIN_VERSION_hoauth2(2,3,0)
getRedirectUri :: Maybe (URIRef Absolute) -> (URIRef Absolute)
getRedirectUri =
fromMaybe $ error "Cannot use OAuth2.oauth2RedirectUri with Nothing"
#else
getRedirectUri :: Maybe (URIRef Absolute) -> Maybe (URIRef Absolute)
getRedirectUri = id
#endif
-- hoauth-2.2 moved most IO-Either functions to ExceptT. This reverses that.
#if MIN_VERSION_hoauth2(2,2,0)
runOAuth2 :: ExceptT e m a -> m (Either e a)
runOAuth2 = runExceptT
#else
runOAuth2 :: IO (Either e a) -> IO (Either e a)
runOAuth2 = id
#endif
-- The fetchAccessToken functions grew a nicer interface in hoauth2-2.3. This
-- up-converts the older ones. We should update our code to use these functions
-- directly.
fetchAccessTokenBasic
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessTokenBasic m o e = runOAuth2 $ f m (getOAuth2 o) e
where
#if MIN_VERSION_hoauth2(2,6,0)
f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretBasic
#elif MIN_VERSION_hoauth2(2,3,0)
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretBasic
#else
f = OAuth2.fetchAccessToken
#endif
fetchAccessTokenPost
:: Manager
-> OAuth2
-> ExchangeToken
-> IO (OAuth2Result Errors OAuth2Token)
fetchAccessTokenPost m o e = runOAuth2 $ f m (getOAuth2 o) e
where
#if MIN_VERSION_hoauth2(2, 6, 0)
f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretPost
#elif MIN_VERSION_hoauth2(2,3,0)
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretPost
#else
f = OAuth2.fetchAccessToken2
#endif