Compare commits

..

No commits in common. "main" and "v0.7.1.2" have entirely different histories.

60 changed files with 417 additions and 330 deletions

1
.github/CODEOWNERS vendored
View File

@ -1 +0,0 @@
* @freckle/backenders

View File

@ -1,16 +0,0 @@
name: Asana
on:
pull_request:
types: [opened]
jobs:
link-asana-task:
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- uses: Asana/create-app-attachment-github-action@v1.3
id: postAttachment
with:
asana-secret: ${{ secrets.ASANA_API_ACCESS_KEY }}
- run: echo "Status is ${{ steps.postAttachment.outputs.status }}"

View File

@ -9,41 +9,38 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
permissions:
contents: read
jobs: jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- id: generate
uses: freckle/stack-action/generate-matrix@v5
outputs:
stack-yamls: ${{ steps.generate.outputs.stack-yamls }}
test: test:
needs: generate runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
stack-yaml: ${{ fromJSON(needs.generate.outputs.stack-yamls) }} stack-yaml:
- stack-nightly.yaml # ghc-9.6 + hoauth2-2.9.0
- stack.yaml # ghc-9.4
- stack-lts-20.26.yaml # ghc-9.2
- stack-lts-19.33.yaml # ghc-9.0
- stack-lts-18.28.yaml # ghc-8.10
- stack-lts-16.31.yaml # ghc-8.8
- stack-lts-14.27.yaml # ghc-8.6 + hoauth2-1.14.0
- stack-hoauth2-2.6.yaml # ghc-9.4 (nightly-2022-12-09)
- stack-hoauth2-2.3.yaml # ghc-9.0 (nightly-2022-02-25)
- stack-hoauth2-2.2.yaml # ghc-9.0 (nightly-2022-02-25)
- stack-hoauth2-2.0.yaml # ghc-8.10
fail-fast: false fail-fast: false
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v3
- uses: freckle/stack-action@v5 - uses: freckle/stack-action@v4
with: with:
stack-build-arguments: --flag yesod-auth-oauth2:example stack-yaml: ${{ matrix.stack-yaml }}
env: stack-arguments: --flag yesod-auth-oauth2:example
STACK_YAML: ${{ matrix.stack-yaml }}
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v3
- uses: haskell-actions/hlint-setup@v2 - uses: haskell/actions/hlint-setup@v2
- uses: haskell-actions/hlint-run@v2 - uses: haskell/actions/hlint-run@v2
with: with:
fail-on: warning fail-on: warning

View File

@ -8,15 +8,16 @@ jobs:
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v2
- id: tag - id: tag
uses: freckle/haskell-tag-action@v1 uses: freckle/haskell-tag-action@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- if: steps.tag.outputs.tag - if: steps.tag.outputs.tag
run: stack upload --pvp-bounds lower . uses: freckle/stack-upload-action@main
with:
pvp-bounds: lower
env: env:
HACKAGE_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }} HACKAGE_API_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }}
# Use minimum LTS to set lowest lower bounds
STACK_YAML: stack-lts21.yaml

View File

@ -1,2 +0,0 @@
[versions]
oldest = lts-21

View File

@ -1,37 +1,4 @@
## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.8.0.0...main) ## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.2...main)
## [v0.8.0.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.4.0...v0.8.0.0)
- Drop support for GHC < 9.4 and hoauth2 < 2.8
- Add support for GHC 9.12 and hoauth2-2.15
- To align our interfaces with hoauth2-2.15:
- Make `OAuth2 {clientSecret}` non-`Maybe`
- Replace `OAuthToken` with `TokenResponse`
- Replace `Errors` with `TokenResponseError`
- Replace `fetchAccessToken{,2}` with `fetchAccessToken{Basic,Post}`
While technically a major version bump, this change should only affect those
users that maintain their own plugins.
## [v0.7.4.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.3.0...v0.7.4.0)
- Add `oauth2AzureADv2Widget` and `oauth2AzureADv2ScopedWidget`
## [v0.7.3.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.2.0...v0.7.3.0)
- Add ORCID provider
- Drop support for LTS-12 / GHC-8.6
- Replace `cryptonite` with `crypton`
## [v0.7.2.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.3...v0.7.2.0)
- Add `oauth2GitHubWidget` and `oauth2GitHubScopedWidget`
[@jaanisfehling](https://github.com/freckle/yesod-auth-oauth2/pull/181)
## [v0.7.1.3](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.2...v0.7.1.3)
- Add support (with caveats) for relative approots
[@cptrodolfox](https://github.com/freckle/yesod-auth-oauth2/pull/178)
## [v0.7.1.2](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.1...v0.7.1.2) ## [v0.7.1.2](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.1...v0.7.1.2)

View File

@ -34,7 +34,6 @@ import Yesod.Auth.OAuth2.GitHub
import Yesod.Auth.OAuth2.GitLab import Yesod.Auth.OAuth2.GitLab
import Yesod.Auth.OAuth2.Google import Yesod.Auth.OAuth2.Google
import Yesod.Auth.OAuth2.Nylas import Yesod.Auth.OAuth2.Nylas
import Yesod.Auth.OAuth2.ORCID
import Yesod.Auth.OAuth2.Salesforce import Yesod.Auth.OAuth2.Salesforce
import Yesod.Auth.OAuth2.Slack import Yesod.Auth.OAuth2.Slack
import Yesod.Auth.OAuth2.Spotify import Yesod.Auth.OAuth2.Spotify
@ -150,7 +149,6 @@ mkFoundation = do
, loadPlugin (oauth2Spotify []) "SPOTIFY" , loadPlugin (oauth2Spotify []) "SPOTIFY"
, loadPlugin oauth2Twitch "TWITCH" , loadPlugin oauth2Twitch "TWITCH"
, loadPlugin oauth2WordPressDotCom "WORDPRESS_DOT_COM" , loadPlugin oauth2WordPressDotCom "WORDPRESS_DOT_COM"
, loadPlugin oauth2ORCID "ORCID"
, loadPlugin oauth2Upcase "UPCASE" , loadPlugin oauth2Upcase "UPCASE"
] ]

View File

@ -1,6 +1,6 @@
--- ---
name: yesod-auth-oauth2 name: yesod-auth-oauth2
version: 0.8.0.0 version: 0.7.1.2
synopsis: OAuth 2.0 authentication plugins synopsis: OAuth 2.0 authentication plugins
description: Library to authenticate with OAuth 2.0 for Yesod web applications. description: Library to authenticate with OAuth 2.0 for Yesod web applications.
category: Web category: Web
@ -27,9 +27,9 @@ library:
dependencies: dependencies:
- aeson >=0.6 - aeson >=0.6
- bytestring >=0.9.1.4 - bytestring >=0.9.1.4
- crypton - cryptonite >=0.25
- errors - errors
- hoauth2 >=2.8.0 # TokenRequestError - hoauth2 >=1.11.0
- http-client >=0.4.0 - http-client >=0.4.0
- http-conduit >=2.0 - http-conduit >=2.0
- http-types >=0.8 - http-types >=0.8

View File

@ -1,7 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>freckle/renovate-config"
],
"minimumReleaseAge": "0 days"
}

View File

@ -2,117 +2,170 @@
module Network.OAuth.OAuth2.Compat module Network.OAuth.OAuth2.Compat
( OAuth2 (..) ( OAuth2 (..)
, OAuth2Result
, Errors
, authorizationUrl , authorizationUrl
, fetchAccessTokenBasic , fetchAccessToken
, fetchAccessTokenPost , fetchAccessToken2
, authGetBS , authGetBS
-- * Re-exports -- * Re-exports
, AccessToken (..) , module Network.OAuth.OAuth2
, ExchangeToken (..)
, RefreshToken (..)
, TokenResponse
, accessToken
, refreshToken
, expiresIn
, tokenType
, idToken
, TokenResponseError
) where ) where
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Except (runExceptT)
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import Data.Text (Text) import Data.Text (Text)
import Network.HTTP.Conduit (Manager) import Network.HTTP.Conduit (Manager)
import Network.OAuth.OAuth2
( AccessToken (..)
, ExchangeToken (..)
, OAuth2Token (..)
, RefreshToken (..)
)
import qualified Network.OAuth.OAuth2 as OAuth2
import URI.ByteString import URI.ByteString
#if MIN_VERSION_hoauth2(2,15,0) #if MIN_VERSION_hoauth2(2,2,0)
import Network.OAuth2 import Control.Monad.Trans.Except (ExceptT, runExceptT)
( AccessToken (..) import Data.Maybe (fromMaybe)
, ExchangeToken (..)
, RefreshToken (..)
, TokenResponse (..)
, TokenResponseError
)
import qualified Network.OAuth2 as OAuth2
#elif MIN_VERSION_hoauth2(2,9,0)
import Network.OAuth.OAuth2
( AccessToken (..)
, ExchangeToken (..)
, RefreshToken (..)
, OAuth2Token (..)
, TokenResponseError
)
import qualified Network.OAuth.OAuth2 as OAuth2
type TokenResponse = OAuth2Token
#else
-- hoauth2-2.8
import Network.OAuth.OAuth2
( AccessToken (..)
, ExchangeToken (..)
, RefreshToken (..)
, OAuth2Token (..)
)
import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
import qualified Network.OAuth.OAuth2 as OAuth2
type TokenResponse = OAuth2Token
type TokenResponseError = TokenRequestError
#endif #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 data OAuth2 = OAuth2
{ oauth2ClientId :: Text { oauth2ClientId :: Text
, oauth2ClientSecret :: Text , oauth2ClientSecret :: Maybe Text
, oauth2AuthorizeEndpoint :: URIRef Absolute , oauth2AuthorizeEndpoint :: URIRef Absolute
, oauth2TokenEndpoint :: URIRef Absolute , oauth2TokenEndpoint :: URIRef Absolute
, oauth2RedirectUri :: Maybe (URIRef Absolute) , oauth2RedirectUri :: Maybe (URIRef Absolute)
} }
type OAuth2Result err a = Either err a
authorizationUrl :: OAuth2 -> URI authorizationUrl :: OAuth2 -> URI
authorizationUrl = OAuth2.authorizationUrl . getOAuth2 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 fetchAccessTokenBasic
:: Manager :: Manager
-> OAuth2 -> OAuth2
-> ExchangeToken -> ExchangeToken
-> IO (Either TokenResponseError TokenResponse) -> IO (OAuth2Result Errors OAuth2Token)
fetchAccessTokenBasic = fetchAccessTokenBasic m o e = runOAuth2 $ f m (getOAuth2 o) e
runFetchAccessToken OAuth2.ClientSecretBasic 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 fetchAccessTokenPost
:: Manager :: Manager
-> OAuth2 -> OAuth2
-> ExchangeToken -> ExchangeToken
-> IO (Either TokenResponseError TokenResponse) -> IO (OAuth2Result Errors OAuth2Token)
fetchAccessTokenPost = fetchAccessTokenPost m o e = runOAuth2 $ f m (getOAuth2 o) e
runFetchAccessToken OAuth2.ClientSecretPost where
#if MIN_VERSION_hoauth2(2, 6, 0)
authGetBS :: Manager -> AccessToken -> URI -> IO (Either ByteString ByteString) f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretPost
authGetBS m a u = runExceptT $ OAuth2.authGetBS m a u #elif MIN_VERSION_hoauth2(2,3,0)
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretPost
getOAuth2 :: OAuth2 -> OAuth2.OAuth2 #else
getOAuth2 o = f = OAuth2.fetchAccessToken2
OAuth2.OAuth2 #endif
{ OAuth2.oauth2ClientId = oauth2ClientId o
, OAuth2.oauth2ClientSecret = oauth2ClientSecret o
, OAuth2.oauth2AuthorizeEndpoint = oauth2AuthorizeEndpoint o
, OAuth2.oauth2TokenEndpoint = oauth2TokenEndpoint o
, OAuth2.oauth2RedirectUri = case oauth2RedirectUri o of
Nothing ->
error
"programmer error: yesod-auth-oauth2:OAuth2 must have a Just value set as oauth2RedirectUri before using as an hauth2:OAuth2 value"
Just uri -> uri
}
runFetchAccessToken
:: MonadIO m
=> OAuth2.ClientAuthenticationMethod
-> Manager
-> OAuth2
-> ExchangeToken
-> m (Either TokenResponseError TokenResponse)
runFetchAccessToken am m o e = runExceptT $ OAuth2.fetchAccessTokenWithAuthMethod am m (getOAuth2 o) e

View File

@ -11,13 +11,13 @@ module Yesod.Auth.OAuth2
( OAuth2 (..) ( OAuth2 (..)
, FetchCreds , FetchCreds
, Manager , Manager
, TokenResponse , OAuth2Token (..)
, Creds (..) , Creds (..)
, oauth2Url , oauth2Url
, authOAuth2 , authOAuth2
, authOAuth2Widget , authOAuth2Widget
-- * Alternatives that use 'fetchAccessTokenPost' -- * Alternatives that use 'fetchAccessToken2'
, authOAuth2' , authOAuth2'
, authOAuth2Widget' , authOAuth2Widget'
@ -49,7 +49,7 @@ oauth2Url name = PluginR name ["forward"]
authOAuth2 :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m authOAuth2 :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m
authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name authOAuth2 name = authOAuth2Widget [whamlet|Login via #{name}|] name
-- | A version of 'authOAuth2' that uses 'fetchAccessTokenPost' -- | A version of 'authOAuth2' that uses 'fetchAccessToken2'
-- --
-- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129> -- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129>
authOAuth2' :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m authOAuth2' :: YesodAuth m => Text -> OAuth2 -> FetchCreds m -> AuthPlugin m
@ -66,9 +66,9 @@ authOAuth2Widget
-> OAuth2 -> OAuth2
-> FetchCreds m -> FetchCreds m
-> AuthPlugin m -> AuthPlugin m
authOAuth2Widget = buildPlugin fetchAccessTokenBasic authOAuth2Widget = buildPlugin fetchAccessToken
-- | A version of 'authOAuth2Widget' that uses 'fetchAccessTokenPost' -- | A version of 'authOAuth2Widget' that uses 'fetchAccessToken2'
-- --
-- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129> -- See <https://github.com/thoughtbot/yesod-auth-oauth2/pull/129>
authOAuth2Widget' authOAuth2Widget'
@ -78,7 +78,7 @@ authOAuth2Widget'
-> OAuth2 -> OAuth2
-> FetchCreds m -> FetchCreds m
-> AuthPlugin m -> AuthPlugin m
authOAuth2Widget' = buildPlugin fetchAccessTokenPost authOAuth2Widget' = buildPlugin fetchAccessToken2
buildPlugin buildPlugin
:: YesodAuth m :: YesodAuth m

View File

@ -52,7 +52,7 @@ oauth2Auth0HostScopes host scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
host `withPath` "/authorize" `withQuery` [scopeParam " " scopes] host `withPath` "/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = host `withPath` "/oauth/token" , oauth2TokenEndpoint = host `withPath` "/oauth/token"

View File

@ -48,7 +48,7 @@ oauth2AzureADScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://login.windows.net/common/oauth2/authorize" "https://login.windows.net/common/oauth2/authorize"
`withQuery` [ scopeParam "," scopes `withQuery` [ scopeParam "," scopes

View File

@ -1,5 +1,4 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
-- | -- |
-- --
@ -10,12 +9,9 @@
module Yesod.Auth.OAuth2.AzureADv2 module Yesod.Auth.OAuth2.AzureADv2
( oauth2AzureADv2 ( oauth2AzureADv2
, oauth2AzureADv2Scoped , oauth2AzureADv2Scoped
, oauth2AzureADv2Widget
, oauth2AzureADv2ScopedWidget
) where ) where
import Yesod.Auth.OAuth2.Prelude import Yesod.Auth.OAuth2.Prelude
import Yesod.Core (WidgetFor, whamlet)
import Prelude import Prelude
import Data.String import Data.String
@ -45,21 +41,9 @@ oauth2AzureADv2
-> AuthPlugin m -> AuthPlugin m
oauth2AzureADv2 = oauth2AzureADv2Scoped defaultScopes oauth2AzureADv2 = oauth2AzureADv2Scoped defaultScopes
oauth2AzureADv2Widget
:: YesodAuth m => WidgetFor m () -> Text -> Text -> Text -> AuthPlugin m
oauth2AzureADv2Widget widget =
oauth2AzureADv2ScopedWidget widget defaultScopes
oauth2AzureADv2Scoped oauth2AzureADv2Scoped
:: YesodAuth m => [Text] -> Text -> Text -> Text -> AuthPlugin m
oauth2AzureADv2Scoped =
oauth2AzureADv2ScopedWidget [whamlet|Login via #{pluginName}|]
oauth2AzureADv2ScopedWidget
:: YesodAuth m :: YesodAuth m
=> WidgetFor m () => [Text]
-- ^ Widget
-> [Text]
-- ^ Scopes -- ^ Scopes
-> Text -> Text
-- ^ Tenant Id -- ^ Tenant Id
@ -70,8 +54,8 @@ oauth2AzureADv2ScopedWidget
-> Text -> Text
-- ^ Client Secret -- ^ Client Secret
-> AuthPlugin m -> AuthPlugin m
oauth2AzureADv2ScopedWidget widget scopes tenantId clientId clientSecret = oauth2AzureADv2Scoped scopes tenantId clientId clientSecret =
authOAuth2Widget widget pluginName oauth2 $ \manager token -> do authOAuth2 pluginName oauth2 $ \manager token -> do
(User userId, userResponse) <- (User userId, userResponse) <-
authGetProfile authGetProfile
pluginName pluginName
@ -89,7 +73,7 @@ oauth2AzureADv2ScopedWidget widget scopes tenantId clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
tenantUrl "/authorize" `withQuery` [scopeParam " " scopes] tenantUrl "/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = tenantUrl "/token" , oauth2TokenEndpoint = tenantUrl "/token"

View File

@ -53,7 +53,7 @@ oauth2BattleNet widget region clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = fromRelative "https" host "/oauth/authorize" , oauth2AuthorizeEndpoint = fromRelative "https" host "/oauth/authorize"
, oauth2TokenEndpoint = fromRelative "https" host "/oauth/token" , oauth2TokenEndpoint = fromRelative "https" host "/oauth/token"
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -55,7 +55,7 @@ oauth2BitbucketScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://bitbucket.com/site/oauth2/authorize" "https://bitbucket.com/site/oauth2/authorize"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -43,7 +43,7 @@ oauth2ClassLinkScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://launchpad.classlink.com/oauth2/v2/auth" "https://launchpad.classlink.com/oauth2/v2/auth"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -6,8 +6,8 @@
module Yesod.Auth.OAuth2.Dispatch module Yesod.Auth.OAuth2.Dispatch
( FetchToken ( FetchToken
, fetchAccessTokenBasic , fetchAccessToken
, fetchAccessTokenPost , fetchAccessToken2
, FetchCreds , FetchCreds
, dispatchAuthRequest , dispatchAuthRequest
) where ) where
@ -31,13 +31,10 @@ import Yesod.Core hiding (ErrorResponse)
-- --
-- This will be 'fetchAccessToken' or 'fetchAccessToken2' -- This will be 'fetchAccessToken' or 'fetchAccessToken2'
type FetchToken = type FetchToken =
Manager Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token)
-> OAuth2
-> ExchangeToken
-> IO (Either TokenResponseError TokenResponse)
-- | How to take an @'OAuth2Token'@ and retrieve user credentials -- | How to take an @'OAuth2Token'@ and retrieve user credentials
type FetchCreds m = Manager -> TokenResponse -> IO (Creds m) type FetchCreds m = Manager -> OAuth2Token -> IO (Creds m)
-- | Dispatch the various OAuth2 handshake routes -- | Dispatch the various OAuth2 handshake routes
dispatchAuthRequest dispatchAuthRequest
@ -108,17 +105,14 @@ withCallbackAndState
-> Text -> Text
-> m OAuth2 -> m OAuth2
withCallbackAndState name oauth2 csrf = do withCallbackAndState name oauth2 csrf = do
callback <- maybe defaultCallback pure $ oauth2RedirectUri oauth2 uri <- ($ PluginR name ["callback"]) <$> getParentUrlRender
callback <- maybe (throwError $ InvalidCallbackUri uri) pure $ fromText uri
pure pure
oauth2 oauth2
{ oauth2RedirectUri = Just callback { oauth2RedirectUri = Just callback
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
oauth2AuthorizeEndpoint oauth2 `withQuery` [("state", encodeUtf8 csrf)] oauth2AuthorizeEndpoint oauth2 `withQuery` [("state", encodeUtf8 csrf)]
} }
where
defaultCallback = do
uri <- ($ PluginR name ["callback"]) <$> getParentUrlRender
maybe (throwError $ InvalidCallbackUri uri) pure $ fromText uri
getParentUrlRender :: MonadHandler m => m (Route (SubHandlerSite m) -> Text) getParentUrlRender :: MonadHandler m => m (Route (SubHandlerSite m) -> Text)
getParentUrlRender = (.) <$> getUrlRender <*> getRouteToParent getParentUrlRender = (.) <$> getUrlRender <*> getRouteToParent

View File

@ -16,7 +16,7 @@ module Yesod.Auth.OAuth2.DispatchError
import Control.Monad.Except import Control.Monad.Except
import Data.Text (Text, pack) import Data.Text (Text, pack)
import Network.OAuth.OAuth2.Compat (TokenResponseError) import Network.OAuth.OAuth2.Compat (Errors)
import UnliftIO.Except () import UnliftIO.Except ()
import UnliftIO.Exception import UnliftIO.Exception
import Yesod.Auth hiding (ServerError) import Yesod.Auth hiding (ServerError)
@ -30,7 +30,7 @@ data DispatchError
| InvalidStateToken (Maybe Text) Text | InvalidStateToken (Maybe Text) Text
| InvalidCallbackUri Text | InvalidCallbackUri Text
| OAuth2HandshakeError ErrorResponse | OAuth2HandshakeError ErrorResponse
| OAuth2ResultError TokenResponseError | OAuth2ResultError Errors
| FetchCredsIOException IOException | FetchCredsIOException IOException
| FetchCredsYesodOAuth2Exception YesodOAuth2Exception | FetchCredsYesodOAuth2Exception YesodOAuth2Exception
| OtherDispatchError Text | OtherDispatchError Text

View File

@ -76,7 +76,7 @@ oauth2EveScoped scopes widgetType clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://login.eveonline.com/oauth/authorize" "https://login.eveonline.com/oauth/authorize"
`withQuery` [("response_type", "code"), scopeParam " " scopes] `withQuery` [("response_type", "code"), scopeParam " " scopes]

View File

@ -1,3 +1,5 @@
{-# LANGUAGE DeriveDataTypeable #-}
module Yesod.Auth.OAuth2.Exception module Yesod.Auth.OAuth2.Exception
( YesodOAuth2Exception (..) ( YesodOAuth2Exception (..)
) where ) where
@ -19,6 +21,6 @@ data YesodOAuth2Exception
-- --
-- Plugin name and error message. -- Plugin name and error message.
GenericError Text String GenericError Text String
deriving (Show) deriving (Show, Typeable)
instance Exception YesodOAuth2Exception instance Exception YesodOAuth2Exception

View File

@ -1,5 +1,4 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
-- | -- |
-- --
@ -9,14 +8,12 @@
-- * Uses github user id as credentials identifier -- * Uses github user id as credentials identifier
module Yesod.Auth.OAuth2.GitHub module Yesod.Auth.OAuth2.GitHub
( oauth2GitHub ( oauth2GitHub
, oauth2GitHubWidget
, oauth2GitHubScoped , oauth2GitHubScoped
, oauth2GitHubScopedWidget
) where ) where
import qualified Data.Text as T
import Yesod.Auth.OAuth2.Prelude import Yesod.Auth.OAuth2.Prelude
import Yesod.Core (WidgetFor, whamlet)
import qualified Data.Text as T
newtype User = User Int newtype User = User Int
@ -32,18 +29,9 @@ defaultScopes = ["user:email"]
oauth2GitHub :: YesodAuth m => Text -> Text -> AuthPlugin m oauth2GitHub :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2GitHub = oauth2GitHubScoped defaultScopes oauth2GitHub = oauth2GitHubScoped defaultScopes
oauth2GitHubWidget
:: YesodAuth m => WidgetFor m () -> Text -> Text -> AuthPlugin m
oauth2GitHubWidget widget = oauth2GitHubScopedWidget widget defaultScopes
oauth2GitHubScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m oauth2GitHubScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
oauth2GitHubScoped = oauth2GitHubScoped scopes clientId clientSecret =
oauth2GitHubScopedWidget [whamlet|Login via #{pluginName}|] authOAuth2 pluginName oauth2 $ \manager token -> do
oauth2GitHubScopedWidget
:: YesodAuth m => WidgetFor m () -> [Text] -> Text -> Text -> AuthPlugin m
oauth2GitHubScopedWidget widget scopes clientId clientSecret =
authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
(User userId, userResponse) <- (User userId, userResponse) <-
authGetProfile authGetProfile
pluginName pluginName
@ -61,7 +49,7 @@ oauth2GitHubScopedWidget widget scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://github.com/login/oauth/authorize" "https://github.com/login/oauth/authorize"
`withQuery` [scopeParam "," scopes] `withQuery` [scopeParam "," scopes]

View File

@ -53,7 +53,7 @@ oauth2GitLabHostScopes host scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes] host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = host `withPath` "/oauth/token" , oauth2TokenEndpoint = host `withPath` "/oauth/token"

View File

@ -39,8 +39,9 @@ newtype User = User Text
instance FromJSON User where instance FromJSON User where
parseJSON = parseJSON =
withObject "User" $ \o -> withObject "User" $ \o ->
-- Required for data backwards-compatibility User
User . ("google-uid:" <>) <$> o .: "sub" -- Required for data backwards-compatibility
<$> (("google-uid:" <>) <$> o .: "sub")
pluginName :: Text pluginName :: Text
pluginName = "google" pluginName = "google"
@ -80,7 +81,7 @@ oauth2GoogleScopedWidget widget scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://accounts.google.com/o/oauth2/auth" "https://accounts.google.com/o/oauth2/auth"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -55,7 +55,7 @@ oauth2Nylas clientId clientSecret =
oauth = oauth =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://api.nylas.com/oauth/authorize" "https://api.nylas.com/oauth/authorize"
`withQuery` [ ("response_type", "code") `withQuery` [ ("response_type", "code")

View File

@ -1,50 +0,0 @@
{-# LANGUAGE OverloadedStrings #-}
module Yesod.Auth.OAuth2.ORCID
( oauth2ORCID
) where
import qualified Data.Text as T
import Yesod.Auth.OAuth2.Prelude
pluginName :: Text
pluginName = "orcid"
newtype User = User Text
instance FromJSON User where
parseJSON = withObject "User" $ \o -> User <$> o .: "sub"
oauth2ORCID
:: YesodAuth m
=> Text
-- ^ Client Id
-> Text
-- ^ Client Secret
-> AuthPlugin m
oauth2ORCID clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
(User userId, userResponse) <-
authGetProfile
pluginName
manager
token
"https://orcid.org/oauth/userinfo"
pure
Creds
{ credsPlugin = pluginName
, credsIdent = T.pack $ show userId
, credsExtra = setExtra token userResponse
}
where
oauth2 =
OAuth2
{ oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret
, oauth2AuthorizeEndpoint =
"https://orcid.org/oauth/authorize"
`withQuery` [scopeParam " " ["openid"]]
, oauth2TokenEndpoint = "https://orcid.org/oauth/token"
, oauth2RedirectUri = Nothing
}

View File

@ -30,12 +30,7 @@ module Yesod.Auth.OAuth2.Prelude
-- * OAuth2 -- * OAuth2
, OAuth2 (..) , OAuth2 (..)
, TokenResponse , OAuth2Token (..)
, accessToken
, refreshToken
, expiresIn
, tokenType
, idToken
, AccessToken (..) , AccessToken (..)
, RefreshToken (..) , RefreshToken (..)
@ -83,7 +78,7 @@ authGetProfile
:: FromJSON a :: FromJSON a
=> Text => Text
-> Manager -> Manager
-> TokenResponse -> OAuth2Token
-> URI -> URI
-> IO (a, BL.ByteString) -> IO (a, BL.ByteString)
authGetProfile name manager token url = do authGetProfile name manager token url = do
@ -119,7 +114,7 @@ scopeParam d = ("scope",) . encodeUtf8 . T.intercalate d
-- May set the following keys: -- May set the following keys:
-- --
-- - @refreshToken@: if the provider supports refreshing the @accessToken@ -- - @refreshToken@: if the provider supports refreshing the @accessToken@
setExtra :: TokenResponse -> BL.ByteString -> [(Text, Text)] setExtra :: OAuth2Token -> BL.ByteString -> [(Text, Text)]
setExtra token userResponse = setExtra token userResponse =
[ ("accessToken", atoken $ accessToken token) [ ("accessToken", atoken $ accessToken token)
, ("userResponse", decodeUtf8 $ BL.toStrict userResponse) , ("userResponse", decodeUtf8 $ BL.toStrict userResponse)

View File

@ -76,7 +76,7 @@ salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSec
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes] , oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
, oauth2TokenEndpoint = tokenUri , oauth2TokenEndpoint = tokenUri
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -74,7 +74,7 @@ oauth2SlackScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://slack.com/oauth/authorize" "https://slack.com/oauth/authorize"
`withQuery` [scopeParam "," $ map scopeText scopes] `withQuery` [scopeParam "," $ map scopeText scopes]

View File

@ -37,7 +37,7 @@ oauth2Spotify scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://accounts.spotify.com/authorize" "https://accounts.spotify.com/authorize"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -49,7 +49,7 @@ oauth2TwitchScoped scopes clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://id.twitch.tv/oauth2/authorize" "https://id.twitch.tv/oauth2/authorize"
`withQuery` [scopeParam " " scopes] `withQuery` [scopeParam " " scopes]

View File

@ -44,7 +44,7 @@ oauth2Upcase clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize" , oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize"
, oauth2TokenEndpoint = "http://upcase.com/oauth/token" , oauth2TokenEndpoint = "http://upcase.com/oauth/token"
, oauth2RedirectUri = Nothing , oauth2RedirectUri = Nothing

View File

@ -41,7 +41,7 @@ oauth2WordPressDotCom clientId clientSecret =
oauth2 = oauth2 =
OAuth2 OAuth2
{ oauth2ClientId = clientId { oauth2ClientId = clientId
, oauth2ClientSecret = clientSecret , oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint = , oauth2AuthorizeEndpoint =
"https://public-api.wordpress.com/oauth2/authorize" "https://public-api.wordpress.com/oauth2/authorize"
`withQuery` [scopeParam "," ["auth"]] `withQuery` [scopeParam "," ["auth"]]

3
stack-hoauth2-2.0.yaml Normal file
View File

@ -0,0 +1,3 @@
resolver: lts-18.28
extra-deps:
- hoauth2-2.0.0

View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.0.0@sha256:4686d776272d4c57d3c8dbeb9e58b04afe4d2b410382011bd78a3d2bfb08a3fe,5662
pantry-tree:
sha256: 291b3dd90854ef44f270519ec17e34b6778f8430f6d6517bd67b0128bd549553
size: 2171
original:
hackage: hoauth2-2.0.0
snapshots:
- completed:
sha256: 428ec8d5ce932190d3cbe266b9eb3c175cd81e984babf876b64019e2cbe4ea68
size: 590100
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
original: lts-18.28

3
stack-hoauth2-2.2.yaml Normal file
View File

@ -0,0 +1,3 @@
resolver: nightly-2022-02-25
extra-deps:
- hoauth2-2.2.0

View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.2.0@sha256:83a96156717d9e2c93394b35bef4151f82b90dc88b83d0e35c0bf1158bd41c6c,2801
pantry-tree:
sha256: d6e2d12e0e66eb9392301ec97d50677afb71608568f3664eb466a4451c66ba59
size: 593
original:
hackage: hoauth2-2.2.0
snapshots:
- completed:
sha256: b18614ab8986a4ba6d469921a2c18decab244af78309effa3d2dab85dbdfef80
size: 611886
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/2/25.yaml
original: nightly-2022-02-25

3
stack-hoauth2-2.3.yaml Normal file
View File

@ -0,0 +1,3 @@
resolver: nightly-2022-02-25
extra-deps:
- hoauth2-2.3.0

View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.3.0@sha256:213744356007a4686ff3bb72105843d478bc0ba6229659429cbe241a99f55095,2816
pantry-tree:
sha256: e559c811165a2e75cfe649b68396466b3bd0b6a5353a9d6476605e6a40e0eb37
size: 594
original:
hackage: hoauth2-2.3.0
snapshots:
- completed:
sha256: b18614ab8986a4ba6d469921a2c18decab244af78309effa3d2dab85dbdfef80
size: 611886
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/2/25.yaml
original: nightly-2022-02-25

11
stack-hoauth2-2.6.yaml Normal file
View File

@ -0,0 +1,11 @@
resolver: nightly-2022-12-09
extra-deps:
- hoauth2-2.6.0
allow-newer: true
allow-newer-deps:
- hoauth2 # specifying the package itself is not necessary in the newest
# stack, and in fact doens't make conceptual sense. But it is
# required on the version of stack on GHA or you get a warning about
# ignoreing the bounds (as desired) but it still fails on them...
- memory
- text

View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.6.0@sha256:168321df73bf75dc7cdda8e72725e9f3f624a9776b1fe59ae46c29c45029dc5d,2262
pantry-tree:
sha256: 5d39759b171cfaaf5842069a5548c2c1a41c0978645d018da7df713a186192b5
size: 859
original:
hackage: hoauth2-2.6.0
snapshots:
- completed:
sha256: b77e2c2b7988ed34cd317c01eb1958a8b8c234c3cc17e44077616c212959bed0
size: 558756
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/12/9.yaml
original: nightly-2022-12-09

3
stack-lts-14.27.yaml Normal file
View File

@ -0,0 +1,3 @@
resolver: lts-14.27
extra-deps:
- hoauth2-1.14.0

19
stack-lts-14.27.yaml.lock Normal file
View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-1.14.0@sha256:fcb4284fc78950c91d5b548317c51bd99a5ced84f4bb9e6153624b5783e4215f,5628
pantry-tree:
sha256: f25e2c2c101312196159dad5a3e2a4c8f549ed2d036d9566b66786d758db7dba
size: 2046
original:
hackage: hoauth2-1.14.0
snapshots:
- completed:
sha256: 7ea31a280c56bf36ff591a7397cc384d0dff622e7f9e4225b47d8980f019a0f0
size: 524996
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/27.yaml
original: lts-14.27

1
stack-lts-16.31.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-16.31

12
stack-lts-16.31.yaml.lock Normal file
View File

@ -0,0 +1,12 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 637fb77049b25560622a224845b7acfe81a09fdb6a96a3c75997a10b651667f6
size: 534126
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/31.yaml
original: lts-16.31

1
stack-lts-18.28.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-18.28

12
stack-lts-18.28.yaml.lock Normal file
View File

@ -0,0 +1,12 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 428ec8d5ce932190d3cbe266b9eb3c175cd81e984babf876b64019e2cbe4ea68
size: 590100
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
original: lts-18.28

1
stack-lts-19.33.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-19.33

12
stack-lts-19.33.yaml.lock Normal file
View File

@ -0,0 +1,12 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4
size: 619204
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml
original: lts-19.33

1
stack-lts-20.26.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-20.26

12
stack-lts-20.26.yaml.lock Normal file
View File

@ -0,0 +1,12 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages: []
snapshots:
- completed:
sha256: 5a59b2a405b3aba3c00188453be172b85893cab8ebc352b1ef58b0eae5d248a2
size: 650475
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/26.yaml
original: lts-20.26

View File

@ -1 +0,0 @@
resolver: lts-21.25

View File

@ -1 +0,0 @@
resolver: lts-22.44

View File

@ -1 +0,0 @@
resolver: lts-23.28

View File

@ -1 +0,0 @@
resolver: lts-24.26

View File

@ -1,4 +1,3 @@
resolver: nightly-2026-01-05 resolver: nightly-2023-10-30
extra-deps: extra-deps:
- cryptonite-0.30 - hoauth2-2.9.0
- yesod-auth-1.6.11.3

19
stack-nightly.yaml.lock Normal file
View File

@ -0,0 +1,19 @@
# This file was autogenerated by Stack.
# You should not edit this file by hand.
# For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files
packages:
- completed:
hackage: hoauth2-2.9.0@sha256:b12385374771dd2d134cb88234aa80c4ab381ff0c491870a3be5f2676c3fade6,3529
pantry-tree:
sha256: 33a8b924018c8c2d7b08dfbd16ec00e6f645ab9d5c653a0e335132936641bc82
size: 2129
original:
hackage: hoauth2-2.9.0
snapshots:
- completed:
sha256: e1e4b585723b266822e37cf602d87b57c7c8774b7e5f6b84fdcc580ea5eb2bf1
size: 697668
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2023/10/30.yaml
original: nightly-2023-10-30

View File

@ -1 +0,0 @@
stack-lts24.yaml

1
stack.yaml Normal file
View File

@ -0,0 +1 @@
resolver: lts-21.5

View File

@ -1,12 +1,12 @@
# This file was autogenerated by Stack. # This file was autogenerated by Stack.
# You should not edit this file by hand. # You should not edit this file by hand.
# For more information, please see the documentation at: # For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/topics/lock_files # https://docs.haskellstack.org/en/stable/lock_files
packages: [] packages: []
snapshots: snapshots:
- completed: - completed:
sha256: d90eb1418667a225998b173817300e5ae2e1500ed03c0a9457cc2a0e78a0122a sha256: 1d5fb7e344e76dd2c8958e3061d4e4dabb50a1355e6ff02e7d0e4f754c0adf47
size: 726337 size: 640015
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/24/26.yaml url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/5.yaml
original: lts-24.26 original: lts-21.5

View File

@ -1,13 +1,13 @@
cabal-version: 1.18 cabal-version: 1.18
-- This file has been generated from package.yaml by hpack version 0.38.1. -- This file has been generated from package.yaml by hpack version 0.36.0.
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: d595b9569ed34feddc8c41cf6f1f8cabbd8a37fa14b6afeeb24ad651ca689011 -- hash: d17748cda71a5090b2883f761cea3167a59252819da563075e3983a1a248d667
name: yesod-auth-oauth2 name: yesod-auth-oauth2
version: 0.8.0.0 version: 0.7.1.2
synopsis: OAuth 2.0 authentication plugins synopsis: OAuth 2.0 authentication plugins
description: Library to authenticate with OAuth 2.0 for Yesod web applications. description: Library to authenticate with OAuth 2.0 for Yesod web applications.
category: Web category: Web
@ -54,7 +54,6 @@ library
Yesod.Auth.OAuth2.GitLab Yesod.Auth.OAuth2.GitLab
Yesod.Auth.OAuth2.Google Yesod.Auth.OAuth2.Google
Yesod.Auth.OAuth2.Nylas Yesod.Auth.OAuth2.Nylas
Yesod.Auth.OAuth2.ORCID
Yesod.Auth.OAuth2.Prelude Yesod.Auth.OAuth2.Prelude
Yesod.Auth.OAuth2.Random Yesod.Auth.OAuth2.Random
Yesod.Auth.OAuth2.Salesforce Yesod.Auth.OAuth2.Salesforce
@ -72,9 +71,9 @@ library
aeson >=0.6 aeson >=0.6
, base >=4.9.0.0 && <5 , base >=4.9.0.0 && <5
, bytestring >=0.9.1.4 , bytestring >=0.9.1.4
, crypton , cryptonite >=0.25
, errors , errors
, hoauth2 >=2.8.0 , hoauth2 >=1.11.0
, http-client >=0.4.0 , http-client >=0.4.0
, http-conduit >=2.0 , http-conduit >=2.0
, http-types >=0.8 , http-types >=0.8