packages feed

yesod-auth-oauth2 0.6.1.7 → 0.6.2.0

raw patch · 5 files changed

+187/−114 lines, 5 filesdep ~aesondep ~aeson-prettydep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, aeson-pretty, bytestring, containers, cryptonite, errors, hspec, http-conduit, load-env, memory, microlens, safe-exceptions, text, uri-bytestring, warp, yesod, yesod-auth

API changes (from Hackage documentation)

+ Yesod.Auth.OAuth2.ClassLink: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.ClassLink.User
+ Yesod.Auth.OAuth2.ClassLink: oauth2ClassLink :: YesodAuth m => Text -> Text -> AuthPlugin m
+ Yesod.Auth.OAuth2.ClassLink: oauth2ClassLinkScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m

Files

CHANGELOG.md view
@@ -1,6 +1,17 @@-## [*Unreleased*](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.1.7...master)+## [*Unreleased*](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.2.0...master)  None++## [v0.6.2.0](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.1.7...v0.6.2.0)++- Filter `+` from `state` tokens++  This decreases entropy in the token slightly, but ensures that providers+  performing unexpected +/space/%20 encoding (e.g. ClassLink) still function.++  See [#140](https://github.com/thoughtbot/yesod-auth-oauth2/pull/140).++- Add ClassLink provider  ## [v0.6.1.7](https://github.com/thoughtbot/yesod-auth-oauth2/compare/v0.6.1.6...v0.6.1.7) 
example/Main.hs view
@@ -38,6 +38,7 @@ import Yesod.Auth.OAuth2.AzureAD import Yesod.Auth.OAuth2.BattleNet import Yesod.Auth.OAuth2.Bitbucket+import Yesod.Auth.OAuth2.ClassLink import Yesod.Auth.OAuth2.EveOnline import Yesod.Auth.OAuth2.GitHub import Yesod.Auth.OAuth2.GitLab@@ -46,8 +47,8 @@ import Yesod.Auth.OAuth2.Salesforce import Yesod.Auth.OAuth2.Slack import Yesod.Auth.OAuth2.Spotify-import Yesod.Auth.OAuth2.WordPressDotCom import Yesod.Auth.OAuth2.Upcase+import Yesod.Auth.OAuth2.WordPressDotCom  data App = App     { appHttpManager :: Manager@@ -73,10 +74,9 @@      -- Copy the Creds response into the session for viewing after     authenticate c = do-        mapM_ (uncurry setSession) $-            [ ("credsIdent", credsIdent c)-            , ("credsPlugin", credsPlugin c)-            ] ++ credsExtra c+        mapM_ (uncurry setSession)+            $ [("credsIdent", credsIdent c), ("credsPlugin", credsPlugin c)]+            ++ credsExtra c          return $ Authenticated "1" @@ -138,6 +138,7 @@         [ loadPlugin oauth2AzureAD "AZURE_AD"         , loadPlugin (oauth2BattleNet [whamlet|TODO|] "en") "BATTLE_NET"         , loadPlugin oauth2Bitbucket "BITBUCKET"+        , loadPlugin oauth2ClassLink "CLASSLINK"         , loadPlugin (oauth2Eve Plain) "EVE_ONLINE"         , loadPlugin oauth2GitHub "GITHUB"         , loadPlugin oauth2GitLab "GITLAB"@@ -150,7 +151,7 @@         , loadPlugin oauth2Upcase "UPCASE"         ] -    return App {..}+    return App { .. }   where     loadPlugin f prefix = do         clientId <- getEnv $ prefix <> "_CLIENT_ID"
+ src/Yesod/Auth/OAuth2/ClassLink.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE OverloadedStrings #-}++module Yesod.Auth.OAuth2.ClassLink+    ( oauth2ClassLink+    , oauth2ClassLinkScoped+    )+where++import Yesod.Auth.OAuth2.Prelude++import qualified Data.Text as T++newtype User = User Int++instance FromJSON User where+    parseJSON = withObject "User" $ \o -> User <$> o .: "UserId"++pluginName :: Text+pluginName = "classlink"++defaultScopes :: [Text]+defaultScopes = ["profile", "oneroster"]++oauth2ClassLink :: YesodAuth m => Text -> Text -> AuthPlugin m+oauth2ClassLink = oauth2ClassLinkScoped defaultScopes++oauth2ClassLinkScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m+oauth2ClassLinkScoped scopes clientId clientSecret =+    authOAuth2 pluginName oauth2 $ \manager token -> do+        (User userId, userResponse) <- authGetProfile+            pluginName+            manager+            token+            "https://nodeapi.classlink.com/v2/my/info"++        pure Creds+            { credsPlugin = pluginName+            , credsIdent = T.pack $ show userId+            , credsExtra = setExtra token userResponse+            }+  where+    oauth2 = OAuth2+        { oauthClientId = clientId+        , oauthClientSecret = Just clientSecret+        , oauthOAuthorizeEndpoint =+            "https://launchpad.classlink.com/oauth2/v2/auth"+                `withQuery` [scopeParam "," scopes]+        , oauthAccessTokenEndpoint =+            "https://launchpad.classlink.com/oauth2/v2/token"+        , oauthCallback = Nothing+        }
src/Yesod/Auth/OAuth2/Dispatch.hs view
@@ -156,14 +156,25 @@ getParentUrlRender :: MonadHandler m => m (Route (SubHandlerSite m) -> Text) getParentUrlRender = (.) <$> getUrlRender <*> getRouteToParent --- | Set a random, 30-character value in the session+-- | Set a random, ~30-character value in the session+--+-- Some (but not all) providers decode a @+@ in the state token as a space when+-- sending it back to us. We don't expect this and fail. And if we did code for+-- it, we'd then fail on the providers that /don't/ do that.+--+-- Therefore, we just exclude @+@ in our tokens, which means this function may+-- return slightly less than 30 characters.+-- setSessionCSRF :: MonadHandler m => Text -> m Text setSessionCSRF sessionKey = do     csrfToken <- liftIO randomToken     csrfToken <$ setSession sessionKey csrfToken   where     randomToken =-        decodeUtf8 . convertToBase @ByteString Base64 <$> getRandomBytes 64+        T.filter (/= '+')+            . decodeUtf8+            . convertToBase @ByteString Base64+            <$> getRandomBytes 64  -- | Verify the callback provided the same CSRF token as in our session verifySessionCSRF :: MonadHandler m => Text -> m Text@@ -172,8 +183,14 @@     sessionToken <- lookupSession sessionKey     deleteSession sessionKey -    unless (sessionToken == Just token)-        $ permissionDenied "Invalid OAuth2 state token"+    unless (sessionToken == Just token) $ do+        $(logError)+            $ "state token does not match. "+            <> "Param: "+            <> tshow token+            <> "State: "+            <> tshow sessionToken+        permissionDenied "Invalid OAuth2 state token"      return token 
yesod-auth-oauth2.cabal view
@@ -1,117 +1,110 @@-cabal-version: 1.12---- This file has been generated from package.yaml by hpack version 0.33.0.------ see: https://github.com/sol/hpack------ hash: 426ae261ba0f32722928565c45da419547ef444e7635ac5e9da56872729a0df9+cabal-version:      1.12+name:               yesod-auth-oauth2+version:            0.6.2.0+license:            MIT+license-file:       LICENSE+maintainer:         Pat Brisbin <pbrisbin@gmail.com>+author:             Tom Streller+homepage:           http://github.com/thoughtbot/yesod-auth-oauth2+bug-reports:        https://github.com/thoughtbot/yesod-auth-oauth2/issues+synopsis:           OAuth 2.0 authentication plugins+description:+    Library to authenticate with OAuth 2.0 for Yesod web applications. -name:           yesod-auth-oauth2-version:        0.6.1.7-synopsis:       OAuth 2.0 authentication plugins-description:    Library to authenticate with OAuth 2.0 for Yesod web applications.-category:       Web-homepage:       http://github.com/thoughtbot/yesod-auth-oauth2-bug-reports:    https://github.com/thoughtbot/yesod-auth-oauth2/issues-author:         Tom Streller-maintainer:     Pat Brisbin <pbrisbin@gmail.com>-license:        MIT-license-file:   LICENSE-build-type:     Simple+category:           Web+build-type:         Simple extra-source-files:     README.md     CHANGELOG.md  source-repository head-  type: git-  location: https://github.com/thoughtbot/yesod-auth-oauth2+    type:     git+    location: https://github.com/thoughtbot/yesod-auth-oauth2  flag example-  description: Build the example application-  manual: False-  default: False+    description: Build the example application+    default:     False  library-  exposed-modules:-      URI.ByteString.Extension-      Yesod.Auth.OAuth2-      Yesod.Auth.OAuth2.AzureAD-      Yesod.Auth.OAuth2.BattleNet-      Yesod.Auth.OAuth2.Bitbucket-      Yesod.Auth.OAuth2.Dispatch-      Yesod.Auth.OAuth2.ErrorResponse-      Yesod.Auth.OAuth2.EveOnline-      Yesod.Auth.OAuth2.Exception-      Yesod.Auth.OAuth2.GitHub-      Yesod.Auth.OAuth2.GitLab-      Yesod.Auth.OAuth2.Google-      Yesod.Auth.OAuth2.Nylas-      Yesod.Auth.OAuth2.Prelude-      Yesod.Auth.OAuth2.Salesforce-      Yesod.Auth.OAuth2.Slack-      Yesod.Auth.OAuth2.Spotify-      Yesod.Auth.OAuth2.Upcase-      Yesod.Auth.OAuth2.WordPressDotCom-  other-modules:-      Paths_yesod_auth_oauth2-  hs-source-dirs:-      src-  ghc-options: -Wall-  build-depends:-      aeson >=0.6 && <1.6-    , base >=4.9.0.0 && <5-    , bytestring >=0.9.1.4-    , cryptonite-    , errors-    , hoauth2 >=1.11.0 && <1.17-    , http-client >=0.4.0 && <0.8-    , http-conduit >=2.0 && <3.0-    , http-types >=0.8 && <0.13-    , memory-    , microlens-    , safe-exceptions-    , text >=0.7 && <2.0-    , uri-bytestring-    , yesod-auth >=1.6.0 && <1.7-    , yesod-core >=1.6.0 && <1.7-  default-language: Haskell2010+    exposed-modules:+        URI.ByteString.Extension+        Yesod.Auth.OAuth2+        Yesod.Auth.OAuth2.AzureAD+        Yesod.Auth.OAuth2.BattleNet+        Yesod.Auth.OAuth2.Bitbucket+        Yesod.Auth.OAuth2.ClassLink+        Yesod.Auth.OAuth2.Dispatch+        Yesod.Auth.OAuth2.ErrorResponse+        Yesod.Auth.OAuth2.EveOnline+        Yesod.Auth.OAuth2.Exception+        Yesod.Auth.OAuth2.GitHub+        Yesod.Auth.OAuth2.GitLab+        Yesod.Auth.OAuth2.Google+        Yesod.Auth.OAuth2.Nylas+        Yesod.Auth.OAuth2.Prelude+        Yesod.Auth.OAuth2.Salesforce+        Yesod.Auth.OAuth2.Slack+        Yesod.Auth.OAuth2.Spotify+        Yesod.Auth.OAuth2.Upcase+        Yesod.Auth.OAuth2.WordPressDotCom +    hs-source-dirs:   src+    other-modules:    Paths_yesod_auth_oauth2+    default-language: Haskell2010+    ghc-options:      -Wall+    build-depends:+        aeson >=0.6 && <1.6,+        base >=4.9.0.0 && <5,+        bytestring >=0.9.1.4 && <0.11,+        cryptonite >=0.26 && <0.28,+        errors >=2.3.0 && <2.4,+        hoauth2 >=1.11.0 && <1.17,+        http-client >=0.4.0 && <0.8,+        http-conduit >=2.0 && <3.0,+        http-types >=0.8 && <0.13,+        memory >=0.15.0 && <0.16,+        microlens >=0.4.11.2 && <0.5,+        safe-exceptions >=0.1.7.1 && <0.2,+        text >=0.7 && <2.0,+        uri-bytestring >=0.3.3.0 && <0.4,+        yesod-auth >=1.6.0 && <1.7,+        yesod-core >=1.6.0 && <1.7+ executable yesod-auth-oauth2-example-  main-is: Main.hs-  other-modules:-      Paths_yesod_auth_oauth2-  hs-source-dirs:-      example-  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N-  build-depends:-      aeson-    , aeson-pretty-    , base >=4.9.0.0 && <5-    , bytestring-    , containers-    , http-conduit-    , load-env-    , text-    , warp-    , yesod-    , yesod-auth-    , yesod-auth-oauth2-  if !(flag(example))-    buildable: False-  default-language: Haskell2010+    main-is:          Main.hs+    hs-source-dirs:   example+    other-modules:    Paths_yesod_auth_oauth2+    default-language: Haskell2010+    ghc-options:      -Wall -threaded -rtsopts -with-rtsopts=-N+    build-depends:+        aeson >=1.4.7.1 && <1.5,+        aeson-pretty >=0.8.8 && <0.9,+        base >=4.9.0.0 && <5,+        bytestring >=0.10.10.1 && <0.11,+        containers >=0.6.2.1 && <0.7,+        http-conduit >=2.3.7.4 && <2.4,+        load-env >=0.2.1.0 && <0.3,+        text >=1.2.4.0 && <1.3,+        warp >=3.3.13 && <3.4,+        yesod >=1.6.1.0 && <1.7,+        yesod-auth >=1.6.10.1 && <1.7,+        yesod-auth-oauth2 -any +    if !flag(example)+        buildable: False+ test-suite test-  type: exitcode-stdio-1.0-  main-is: Spec.hs-  other-modules:-      URI.ByteString.ExtensionSpec-      Paths_yesod_auth_oauth2-  hs-source-dirs:-      test-  ghc-options: -Wall-  build-depends:-      base >=4.9.0.0 && <5-    , hspec-    , uri-bytestring-    , yesod-auth-oauth2-  default-language: Haskell2010+    type:             exitcode-stdio-1.0+    main-is:          Spec.hs+    hs-source-dirs:   test+    other-modules:+        URI.ByteString.ExtensionSpec+        Paths_yesod_auth_oauth2++    default-language: Haskell2010+    ghc-options:      -Wall+    build-depends:+        base >=4.9.0.0 && <5,+        hspec >=2.7.4 && <2.8,+        uri-bytestring >=0.3.3.0 && <0.4,+        yesod-auth-oauth2 -any