mirror of
https://github.com/freckle/yesod-auth-oauth2.git
synced 2026-02-03 23:00:25 +01:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4c3d9f049 | ||
|
|
3dd2318067 | ||
|
|
3e5dbdec77 | ||
|
|
a8de561848 | ||
|
|
a179049522 | ||
|
|
36bc61fa27 | ||
|
|
09cda079d4 | ||
|
|
560647fb01 | ||
|
|
7f6096079f | ||
|
|
4e123a9482 | ||
|
|
a916af9688 | ||
|
|
3b55cee63b | ||
|
|
fa54bc36aa | ||
|
|
e79d174821 | ||
|
|
51c6574183 | ||
|
|
50cc0ea49b | ||
|
|
56c2d0a30d | ||
|
|
624b2be5aa | ||
|
|
87a0231a6d | ||
|
|
7b0d4f6243 | ||
|
|
07c6ea6875 | ||
|
|
433e8b324b |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @freckle/backenders
|
||||||
16
.github/workflows/add-asana-comment.yml.bak
vendored
Normal file
16
.github/workflows/add-asana-comment.yml.bak
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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 }}"
|
||||||
40
.github/workflows/ci.yml
vendored
40
.github/workflows/ci.yml
vendored
@ -9,38 +9,40 @@ concurrency:
|
|||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
permissions:
|
||||||
test:
|
contents: read
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
needs: generate
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
stack-yaml:
|
stack-yaml: ${{ fromJSON(needs.generate.outputs.stack-yamls) }}
|
||||||
- stack-nightly.yaml # ghc-9.8
|
|
||||||
- stack.yaml # ghc-9.6
|
|
||||||
- stack-lts-21.25.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@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: freckle/stack-action@v5
|
- uses: freckle/stack-action@v5
|
||||||
with:
|
with:
|
||||||
stack-yaml: ${{ matrix.stack-yaml }}
|
|
||||||
stack-build-arguments: --flag yesod-auth-oauth2:example
|
stack-build-arguments: --flag yesod-auth-oauth2:example
|
||||||
|
env:
|
||||||
|
STACK_YAML: ${{ matrix.stack-yaml }}
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- 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:
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
|||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
|
|
||||||
- id: tag
|
- id: tag
|
||||||
uses: freckle/haskell-tag-action@v1
|
uses: freckle/haskell-tag-action@v1
|
||||||
@ -19,4 +19,4 @@ jobs:
|
|||||||
HACKAGE_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }}
|
HACKAGE_KEY: ${{ secrets.HACKAGE_UPLOAD_API_KEY }}
|
||||||
|
|
||||||
# Use minimum LTS to set lowest lower bounds
|
# Use minimum LTS to set lowest lower bounds
|
||||||
STACK_YAML: stack-lts-14.27.yaml
|
STACK_YAML: stack-lts21.yaml
|
||||||
|
|||||||
2
.stack-all
Normal file
2
.stack-all
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[versions]
|
||||||
|
oldest = lts-21
|
||||||
25
CHANGELOG.md
25
CHANGELOG.md
@ -1,4 +1,27 @@
|
|||||||
## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.2.0...main)
|
## [_Unreleased_](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.8.0.0...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)
|
## [v0.7.2.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.7.1.3...v0.7.2.0)
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@ 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
|
||||||
@ -149,6 +150,7 @@ 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"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: yesod-auth-oauth2
|
name: yesod-auth-oauth2
|
||||||
version: 0.7.2.0
|
version: 0.8.0.0
|
||||||
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
|
||||||
- cryptonite >=0.25
|
- crypton
|
||||||
- errors
|
- errors
|
||||||
- hoauth2 >=1.11.0
|
- hoauth2 >=2.8.0 # TokenRequestError
|
||||||
- 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
|
||||||
|
|||||||
7
renovate.json
Normal file
7
renovate.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"local>freckle/renovate-config"
|
||||||
|
],
|
||||||
|
"minimumReleaseAge": "0 days"
|
||||||
|
}
|
||||||
@ -2,170 +2,117 @@
|
|||||||
|
|
||||||
module Network.OAuth.OAuth2.Compat
|
module Network.OAuth.OAuth2.Compat
|
||||||
( OAuth2 (..)
|
( OAuth2 (..)
|
||||||
, OAuth2Result
|
|
||||||
, Errors
|
|
||||||
, authorizationUrl
|
, authorizationUrl
|
||||||
, fetchAccessToken
|
, fetchAccessTokenBasic
|
||||||
, fetchAccessToken2
|
, fetchAccessTokenPost
|
||||||
, authGetBS
|
, authGetBS
|
||||||
|
|
||||||
-- * Re-exports
|
-- * Re-exports
|
||||||
, module Network.OAuth.OAuth2
|
, AccessToken (..)
|
||||||
|
, 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 URI.ByteString
|
||||||
|
|
||||||
|
#if MIN_VERSION_hoauth2(2,15,0)
|
||||||
|
import Network.OAuth2
|
||||||
|
( AccessToken (..)
|
||||||
|
, ExchangeToken (..)
|
||||||
|
, RefreshToken (..)
|
||||||
|
, TokenResponse (..)
|
||||||
|
, TokenResponseError
|
||||||
|
)
|
||||||
|
import qualified Network.OAuth2 as OAuth2
|
||||||
|
|
||||||
|
#elif MIN_VERSION_hoauth2(2,9,0)
|
||||||
import Network.OAuth.OAuth2
|
import Network.OAuth.OAuth2
|
||||||
( AccessToken (..)
|
( AccessToken (..)
|
||||||
, ExchangeToken (..)
|
, ExchangeToken (..)
|
||||||
, OAuth2Token (..)
|
|
||||||
, RefreshToken (..)
|
, RefreshToken (..)
|
||||||
|
, OAuth2Token (..)
|
||||||
|
, TokenResponseError
|
||||||
)
|
)
|
||||||
import qualified Network.OAuth.OAuth2 as OAuth2
|
import qualified Network.OAuth.OAuth2 as OAuth2
|
||||||
import URI.ByteString
|
|
||||||
|
|
||||||
#if MIN_VERSION_hoauth2(2,2,0)
|
type TokenResponse = OAuth2Token
|
||||||
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
|
#else
|
||||||
import qualified Network.OAuth.OAuth2.TokenRequest as LegacyTokenRequest
|
-- hoauth2-2.8
|
||||||
import Network.OAuth.OAuth2 (OAuth2Error)
|
import Network.OAuth.OAuth2
|
||||||
type Errors = OAuth2Error LegacyTokenRequest.Errors
|
( AccessToken (..)
|
||||||
#endif
|
, ExchangeToken (..)
|
||||||
|
, RefreshToken (..)
|
||||||
|
, OAuth2Token (..)
|
||||||
|
)
|
||||||
|
import Network.OAuth.OAuth2.TokenRequest (TokenRequestError)
|
||||||
|
import qualified Network.OAuth.OAuth2 as OAuth2
|
||||||
|
|
||||||
{-# ANN module ("HLint: ignore Use fewer imports" :: String) #-}
|
type TokenResponse = OAuth2Token
|
||||||
|
type TokenResponseError = TokenRequestError
|
||||||
|
#endif
|
||||||
|
|
||||||
data OAuth2 = OAuth2
|
data OAuth2 = OAuth2
|
||||||
{ oauth2ClientId :: Text
|
{ oauth2ClientId :: Text
|
||||||
, oauth2ClientSecret :: Maybe Text
|
, oauth2ClientSecret :: 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 (OAuth2Result Errors OAuth2Token)
|
-> IO (Either TokenResponseError TokenResponse)
|
||||||
fetchAccessTokenBasic m o e = runOAuth2 $ f m (getOAuth2 o) e
|
fetchAccessTokenBasic =
|
||||||
where
|
runFetchAccessToken OAuth2.ClientSecretBasic
|
||||||
#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 (OAuth2Result Errors OAuth2Token)
|
-> IO (Either TokenResponseError TokenResponse)
|
||||||
fetchAccessTokenPost m o e = runOAuth2 $ f m (getOAuth2 o) e
|
fetchAccessTokenPost =
|
||||||
where
|
runFetchAccessToken OAuth2.ClientSecretPost
|
||||||
#if MIN_VERSION_hoauth2(2, 6, 0)
|
|
||||||
f = OAuth2.fetchAccessTokenWithAuthMethod OAuth2.ClientSecretPost
|
authGetBS :: Manager -> AccessToken -> URI -> IO (Either ByteString ByteString)
|
||||||
#elif MIN_VERSION_hoauth2(2,3,0)
|
authGetBS m a u = runExceptT $ OAuth2.authGetBS m a u
|
||||||
f = OAuth2.fetchAccessTokenInternal OAuth2.ClientSecretPost
|
|
||||||
#else
|
getOAuth2 :: OAuth2 -> OAuth2.OAuth2
|
||||||
f = OAuth2.fetchAccessToken2
|
getOAuth2 o =
|
||||||
#endif
|
OAuth2.OAuth2
|
||||||
|
{ 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
|
||||||
|
|||||||
@ -11,13 +11,13 @@ module Yesod.Auth.OAuth2
|
|||||||
( OAuth2 (..)
|
( OAuth2 (..)
|
||||||
, FetchCreds
|
, FetchCreds
|
||||||
, Manager
|
, Manager
|
||||||
, OAuth2Token (..)
|
, TokenResponse
|
||||||
, Creds (..)
|
, Creds (..)
|
||||||
, oauth2Url
|
, oauth2Url
|
||||||
, authOAuth2
|
, authOAuth2
|
||||||
, authOAuth2Widget
|
, authOAuth2Widget
|
||||||
|
|
||||||
-- * Alternatives that use 'fetchAccessToken2'
|
-- * Alternatives that use 'fetchAccessTokenPost'
|
||||||
, 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 'fetchAccessToken2'
|
-- | A version of 'authOAuth2' that uses 'fetchAccessTokenPost'
|
||||||
--
|
--
|
||||||
-- 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 fetchAccessToken
|
authOAuth2Widget = buildPlugin fetchAccessTokenBasic
|
||||||
|
|
||||||
-- | A version of 'authOAuth2Widget' that uses 'fetchAccessToken2'
|
-- | A version of 'authOAuth2Widget' that uses 'fetchAccessTokenPost'
|
||||||
--
|
--
|
||||||
-- 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 fetchAccessToken2
|
authOAuth2Widget' = buildPlugin fetchAccessTokenPost
|
||||||
|
|
||||||
buildPlugin
|
buildPlugin
|
||||||
:: YesodAuth m
|
:: YesodAuth m
|
||||||
|
|||||||
@ -52,7 +52,7 @@ oauth2Auth0HostScopes host scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = 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"
|
||||||
|
|||||||
@ -48,7 +48,7 @@ oauth2AzureADScoped scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://login.windows.net/common/oauth2/authorize"
|
"https://login.windows.net/common/oauth2/authorize"
|
||||||
`withQuery` [ scopeParam "," scopes
|
`withQuery` [ scopeParam "," scopes
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
--
|
--
|
||||||
@ -9,9 +10,12 @@
|
|||||||
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
|
||||||
@ -41,9 +45,21 @@ 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
|
||||||
=> [Text]
|
=> WidgetFor m ()
|
||||||
|
-- ^ Widget
|
||||||
|
-> [Text]
|
||||||
-- ^ Scopes
|
-- ^ Scopes
|
||||||
-> Text
|
-> Text
|
||||||
-- ^ Tenant Id
|
-- ^ Tenant Id
|
||||||
@ -54,8 +70,8 @@ oauth2AzureADv2Scoped
|
|||||||
-> Text
|
-> Text
|
||||||
-- ^ Client Secret
|
-- ^ Client Secret
|
||||||
-> AuthPlugin m
|
-> AuthPlugin m
|
||||||
oauth2AzureADv2Scoped scopes tenantId clientId clientSecret =
|
oauth2AzureADv2ScopedWidget widget scopes tenantId clientId clientSecret =
|
||||||
authOAuth2 pluginName oauth2 $ \manager token -> do
|
authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
|
||||||
(User userId, userResponse) <-
|
(User userId, userResponse) <-
|
||||||
authGetProfile
|
authGetProfile
|
||||||
pluginName
|
pluginName
|
||||||
@ -73,7 +89,7 @@ oauth2AzureADv2Scoped scopes tenantId clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
tenantUrl "/authorize" `withQuery` [scopeParam " " scopes]
|
tenantUrl "/authorize" `withQuery` [scopeParam " " scopes]
|
||||||
, oauth2TokenEndpoint = tenantUrl "/token"
|
, oauth2TokenEndpoint = tenantUrl "/token"
|
||||||
|
|||||||
@ -53,7 +53,7 @@ oauth2BattleNet widget region clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = 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
|
||||||
|
|||||||
@ -55,7 +55,7 @@ oauth2BitbucketScoped scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://bitbucket.com/site/oauth2/authorize"
|
"https://bitbucket.com/site/oauth2/authorize"
|
||||||
`withQuery` [scopeParam "," scopes]
|
`withQuery` [scopeParam "," scopes]
|
||||||
|
|||||||
@ -43,7 +43,7 @@ oauth2ClassLinkScoped scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://launchpad.classlink.com/oauth2/v2/auth"
|
"https://launchpad.classlink.com/oauth2/v2/auth"
|
||||||
`withQuery` [scopeParam "," scopes]
|
`withQuery` [scopeParam "," scopes]
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
module Yesod.Auth.OAuth2.Dispatch
|
module Yesod.Auth.OAuth2.Dispatch
|
||||||
( FetchToken
|
( FetchToken
|
||||||
, fetchAccessToken
|
, fetchAccessTokenBasic
|
||||||
, fetchAccessToken2
|
, fetchAccessTokenPost
|
||||||
, FetchCreds
|
, FetchCreds
|
||||||
, dispatchAuthRequest
|
, dispatchAuthRequest
|
||||||
) where
|
) where
|
||||||
@ -31,10 +31,13 @@ import Yesod.Core hiding (ErrorResponse)
|
|||||||
--
|
--
|
||||||
-- This will be 'fetchAccessToken' or 'fetchAccessToken2'
|
-- This will be 'fetchAccessToken' or 'fetchAccessToken2'
|
||||||
type FetchToken =
|
type FetchToken =
|
||||||
Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token)
|
Manager
|
||||||
|
-> 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 -> OAuth2Token -> IO (Creds m)
|
type FetchCreds m = Manager -> TokenResponse -> IO (Creds m)
|
||||||
|
|
||||||
-- | Dispatch the various OAuth2 handshake routes
|
-- | Dispatch the various OAuth2 handshake routes
|
||||||
dispatchAuthRequest
|
dispatchAuthRequest
|
||||||
|
|||||||
@ -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 (Errors)
|
import Network.OAuth.OAuth2.Compat (TokenResponseError)
|
||||||
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 Errors
|
| OAuth2ResultError TokenResponseError
|
||||||
| FetchCredsIOException IOException
|
| FetchCredsIOException IOException
|
||||||
| FetchCredsYesodOAuth2Exception YesodOAuth2Exception
|
| FetchCredsYesodOAuth2Exception YesodOAuth2Exception
|
||||||
| OtherDispatchError Text
|
| OtherDispatchError Text
|
||||||
|
|||||||
@ -76,7 +76,7 @@ oauth2EveScoped scopes widgetType clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = 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]
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
|
||||||
|
|
||||||
module Yesod.Auth.OAuth2.Exception
|
module Yesod.Auth.OAuth2.Exception
|
||||||
( YesodOAuth2Exception (..)
|
( YesodOAuth2Exception (..)
|
||||||
) where
|
) where
|
||||||
@ -21,6 +19,6 @@ data YesodOAuth2Exception
|
|||||||
--
|
--
|
||||||
-- Plugin name and error message.
|
-- Plugin name and error message.
|
||||||
GenericError Text String
|
GenericError Text String
|
||||||
deriving (Show, Typeable)
|
deriving (Show)
|
||||||
|
|
||||||
instance Exception YesodOAuth2Exception
|
instance Exception YesodOAuth2Exception
|
||||||
|
|||||||
@ -61,7 +61,7 @@ oauth2GitHubScopedWidget widget scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://github.com/login/oauth/authorize"
|
"https://github.com/login/oauth/authorize"
|
||||||
`withQuery` [scopeParam "," scopes]
|
`withQuery` [scopeParam "," scopes]
|
||||||
|
|||||||
@ -53,7 +53,7 @@ oauth2GitLabHostScopes host scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = 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"
|
||||||
|
|||||||
@ -39,9 +39,8 @@ newtype User = User Text
|
|||||||
instance FromJSON User where
|
instance FromJSON User where
|
||||||
parseJSON =
|
parseJSON =
|
||||||
withObject "User" $ \o ->
|
withObject "User" $ \o ->
|
||||||
User
|
-- Required for data backwards-compatibility
|
||||||
-- Required for data backwards-compatibility
|
User . ("google-uid:" <>) <$> o .: "sub"
|
||||||
<$> (("google-uid:" <>) <$> o .: "sub")
|
|
||||||
|
|
||||||
pluginName :: Text
|
pluginName :: Text
|
||||||
pluginName = "google"
|
pluginName = "google"
|
||||||
@ -81,7 +80,7 @@ oauth2GoogleScopedWidget widget scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://accounts.google.com/o/oauth2/auth"
|
"https://accounts.google.com/o/oauth2/auth"
|
||||||
`withQuery` [scopeParam " " scopes]
|
`withQuery` [scopeParam " " scopes]
|
||||||
|
|||||||
@ -55,7 +55,7 @@ oauth2Nylas clientId clientSecret =
|
|||||||
oauth =
|
oauth =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://api.nylas.com/oauth/authorize"
|
"https://api.nylas.com/oauth/authorize"
|
||||||
`withQuery` [ ("response_type", "code")
|
`withQuery` [ ("response_type", "code")
|
||||||
|
|||||||
50
src/Yesod/Auth/OAuth2/ORCID.hs
Normal file
50
src/Yesod/Auth/OAuth2/ORCID.hs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{-# 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
|
||||||
|
}
|
||||||
@ -30,7 +30,12 @@ module Yesod.Auth.OAuth2.Prelude
|
|||||||
|
|
||||||
-- * OAuth2
|
-- * OAuth2
|
||||||
, OAuth2 (..)
|
, OAuth2 (..)
|
||||||
, OAuth2Token (..)
|
, TokenResponse
|
||||||
|
, accessToken
|
||||||
|
, refreshToken
|
||||||
|
, expiresIn
|
||||||
|
, tokenType
|
||||||
|
, idToken
|
||||||
, AccessToken (..)
|
, AccessToken (..)
|
||||||
, RefreshToken (..)
|
, RefreshToken (..)
|
||||||
|
|
||||||
@ -78,7 +83,7 @@ authGetProfile
|
|||||||
:: FromJSON a
|
:: FromJSON a
|
||||||
=> Text
|
=> Text
|
||||||
-> Manager
|
-> Manager
|
||||||
-> OAuth2Token
|
-> TokenResponse
|
||||||
-> URI
|
-> URI
|
||||||
-> IO (a, BL.ByteString)
|
-> IO (a, BL.ByteString)
|
||||||
authGetProfile name manager token url = do
|
authGetProfile name manager token url = do
|
||||||
@ -114,7 +119,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 :: OAuth2Token -> BL.ByteString -> [(Text, Text)]
|
setExtra :: TokenResponse -> 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)
|
||||||
|
|||||||
@ -76,7 +76,7 @@ salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSec
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
|
, oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
|
||||||
, oauth2TokenEndpoint = tokenUri
|
, oauth2TokenEndpoint = tokenUri
|
||||||
, oauth2RedirectUri = Nothing
|
, oauth2RedirectUri = Nothing
|
||||||
|
|||||||
@ -74,7 +74,7 @@ oauth2SlackScoped scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://slack.com/oauth/authorize"
|
"https://slack.com/oauth/authorize"
|
||||||
`withQuery` [scopeParam "," $ map scopeText scopes]
|
`withQuery` [scopeParam "," $ map scopeText scopes]
|
||||||
|
|||||||
@ -37,7 +37,7 @@ oauth2Spotify scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://accounts.spotify.com/authorize"
|
"https://accounts.spotify.com/authorize"
|
||||||
`withQuery` [scopeParam " " scopes]
|
`withQuery` [scopeParam " " scopes]
|
||||||
|
|||||||
@ -49,7 +49,7 @@ oauth2TwitchScoped scopes clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://id.twitch.tv/oauth2/authorize"
|
"https://id.twitch.tv/oauth2/authorize"
|
||||||
`withQuery` [scopeParam " " scopes]
|
`withQuery` [scopeParam " " scopes]
|
||||||
|
|||||||
@ -44,7 +44,7 @@ oauth2Upcase clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = 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
|
||||||
|
|||||||
@ -41,7 +41,7 @@ oauth2WordPressDotCom clientId clientSecret =
|
|||||||
oauth2 =
|
oauth2 =
|
||||||
OAuth2
|
OAuth2
|
||||||
{ oauth2ClientId = clientId
|
{ oauth2ClientId = clientId
|
||||||
, oauth2ClientSecret = Just clientSecret
|
, oauth2ClientSecret = clientSecret
|
||||||
, oauth2AuthorizeEndpoint =
|
, oauth2AuthorizeEndpoint =
|
||||||
"https://public-api.wordpress.com/oauth2/authorize"
|
"https://public-api.wordpress.com/oauth2/authorize"
|
||||||
`withQuery` [scopeParam "," ["auth"]]
|
`withQuery` [scopeParam "," ["auth"]]
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
resolver: lts-18.28
|
|
||||||
extra-deps:
|
|
||||||
- hoauth2-2.0.0
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
resolver: nightly-2022-02-25
|
|
||||||
extra-deps:
|
|
||||||
- hoauth2-2.2.0
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
resolver: nightly-2022-02-25
|
|
||||||
extra-deps:
|
|
||||||
- hoauth2-2.3.0
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
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
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
resolver: lts-14.27
|
|
||||||
extra-deps:
|
|
||||||
- hoauth2-1.14.0
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
# 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 +0,0 @@
|
|||||||
resolver: lts-16.31
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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 +0,0 @@
|
|||||||
resolver: lts-18.28
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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 +0,0 @@
|
|||||||
resolver: lts-19.33
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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 +0,0 @@
|
|||||||
resolver: lts-20.26
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
# 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: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd
|
|
||||||
size: 640086
|
|
||||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml
|
|
||||||
original: lts-21.25
|
|
||||||
1
stack-lts22.yaml
Normal file
1
stack-lts22.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
resolver: lts-22.44
|
||||||
1
stack-lts23.yaml
Normal file
1
stack-lts23.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
resolver: lts-23.28
|
||||||
1
stack-lts24.yaml
Normal file
1
stack-lts24.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
resolver: lts-24.26
|
||||||
@ -1,12 +1,4 @@
|
|||||||
resolver: nightly-2024-02-27
|
resolver: nightly-2026-01-05
|
||||||
extra-deps:
|
extra-deps:
|
||||||
- yesod-auth-1.6.11.2
|
- cryptonite-0.30
|
||||||
|
- yesod-auth-1.6.11.3
|
||||||
# For yesod-auth
|
|
||||||
- email-validate-2.3.2.19
|
|
||||||
- yesod-form-1.7.6
|
|
||||||
- yesod-1.6.2.1
|
|
||||||
|
|
||||||
allow-newer: true
|
|
||||||
allow-newer-deps:
|
|
||||||
- email-validate
|
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
# 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: yesod-auth-1.6.11.2@sha256:c580afaccc311ad90fc8a90210b5cf998d95350ddffb622e45282d9b640cf519,3108
|
|
||||||
pantry-tree:
|
|
||||||
sha256: 58e36ca675fc01109915342d4df9cb2680fd37ff20919d84694cdd1d52eb7dc3
|
|
||||||
size: 1013
|
|
||||||
original:
|
|
||||||
hackage: yesod-auth-1.6.11.2
|
|
||||||
- completed:
|
|
||||||
hackage: email-validate-2.3.2.19@sha256:206a835fe99a79f2360c576e3594d8add82d2f1e001d58b49a60f60233da2bf5,1380
|
|
||||||
pantry-tree:
|
|
||||||
sha256: 391475ca7c84d59b1d8de362856acd2f56321d29d54ffcd05ed2a170d4e62692
|
|
||||||
size: 419
|
|
||||||
original:
|
|
||||||
hackage: email-validate-2.3.2.19
|
|
||||||
- completed:
|
|
||||||
hackage: yesod-form-1.7.6@sha256:42219f2c4feaa2de32280c0b8f98db818f993152693a79960808fd3001a4c0e2,3434
|
|
||||||
pantry-tree:
|
|
||||||
sha256: 8a48fc861796a61cf6abd2087fedd86844ba5c3e11c89c74d2d04c4656d69997
|
|
||||||
size: 1797
|
|
||||||
original:
|
|
||||||
hackage: yesod-form-1.7.6
|
|
||||||
- completed:
|
|
||||||
hackage: yesod-1.6.2.1@sha256:504bc888257dae9bb40f4cd1e1110c4e80dfe7b867e8e207b22c4ca4dbd87f9a,2030
|
|
||||||
pantry-tree:
|
|
||||||
sha256: 5a78fa0c6e7dcb46c9acd687ab9409c8fcda0d59b930e2a93e5dc44128c740ec
|
|
||||||
size: 618
|
|
||||||
original:
|
|
||||||
hackage: yesod-1.6.2.1
|
|
||||||
snapshots:
|
|
||||||
- completed:
|
|
||||||
sha256: e596f5467d31095fd7b9f750e82aeffe012e38e795c13e1cdc945c9cab928085
|
|
||||||
size: 604415
|
|
||||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/2/27.yaml
|
|
||||||
original: nightly-2024-02-27
|
|
||||||
@ -1 +0,0 @@
|
|||||||
resolver: lts-22.12
|
|
||||||
1
stack.yaml
Symbolic link
1
stack.yaml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
stack-lts24.yaml
|
||||||
@ -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/lock_files
|
# https://docs.haskellstack.org/en/stable/topics/lock_files
|
||||||
|
|
||||||
packages: []
|
packages: []
|
||||||
snapshots:
|
snapshots:
|
||||||
- completed:
|
- completed:
|
||||||
sha256: e2c529ccfb21501f98f639e056cbde50470b86256d9849d7a82d414ca23e4276
|
sha256: d90eb1418667a225998b173817300e5ae2e1500ed03c0a9457cc2a0e78a0122a
|
||||||
size: 712898
|
size: 726337
|
||||||
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/12.yaml
|
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/24/26.yaml
|
||||||
original: lts-22.12
|
original: lts-24.26
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
cabal-version: 1.18
|
cabal-version: 1.18
|
||||||
|
|
||||||
-- This file has been generated from package.yaml by hpack version 0.36.0.
|
-- This file has been generated from package.yaml by hpack version 0.38.1.
|
||||||
--
|
--
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
--
|
--
|
||||||
-- hash: 0bef4a9a180a48d0f0187fb359f4a27027166f3a0dd3827b76a6accb71753a27
|
-- hash: d595b9569ed34feddc8c41cf6f1f8cabbd8a37fa14b6afeeb24ad651ca689011
|
||||||
|
|
||||||
name: yesod-auth-oauth2
|
name: yesod-auth-oauth2
|
||||||
version: 0.7.2.0
|
version: 0.8.0.0
|
||||||
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,6 +54,7 @@ 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
|
||||||
@ -71,9 +72,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
|
||||||
, cryptonite >=0.25
|
, crypton
|
||||||
, errors
|
, errors
|
||||||
, hoauth2 >=1.11.0
|
, hoauth2 >=2.8.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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user