packages feed

yesod-auth-oauth2 0.2.2 → 0.2.4

raw patch · 5 files changed

+101/−31 lines, 5 filesdep ~aesondep ~http-clientPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: aeson, http-client

API changes (from Hackage documentation)

- Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketEmailSearchResults
- Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketLink
- Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUser
- Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUserEmail
- Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUserLinks
- Yesod.Auth.OAuth2.EveOnline: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.EveOnline.EveUser
- Yesod.Auth.OAuth2.Github: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Github.GithubUser
- Yesod.Auth.OAuth2.Github: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Github.GithubUserEmail
- Yesod.Auth.OAuth2.Google: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Google.GoogleUser
- Yesod.Auth.OAuth2.Nylas: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Nylas.NylasAccount
- Yesod.Auth.OAuth2.Salesforce: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Salesforce.User
- Yesod.Auth.OAuth2.Slack: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Slack.SlackTeam
- Yesod.Auth.OAuth2.Slack: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Slack.SlackUser
- Yesod.Auth.OAuth2.Spotify: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Spotify.SpotifyUser
- Yesod.Auth.OAuth2.Spotify: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Spotify.SpotifyUserImage
- Yesod.Auth.OAuth2.Upcase: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Upcase.UpcaseResponse
- Yesod.Auth.OAuth2.Upcase: instance Data.Aeson.Types.Class.FromJSON Yesod.Auth.OAuth2.Upcase.UpcaseUser
+ Yesod.Auth.OAuth2.BattleNet: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.BattleNet.BattleNetUser
+ Yesod.Auth.OAuth2.BattleNet: oAuth2BattleNet :: YesodAuth m => Text -> Text -> Text -> WidgetT m IO () -> AuthPlugin m
+ Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketEmailSearchResults
+ Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketLink
+ Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUser
+ Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUserEmail
+ Yesod.Auth.OAuth2.Bitbucket: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Bitbucket.BitbucketUserLinks
+ Yesod.Auth.OAuth2.EveOnline: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.EveOnline.EveUser
+ Yesod.Auth.OAuth2.Github: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Github.GithubUser
+ Yesod.Auth.OAuth2.Github: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Github.GithubUserEmail
+ Yesod.Auth.OAuth2.Google: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Google.GoogleUser
+ Yesod.Auth.OAuth2.Nylas: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Nylas.NylasAccount
+ Yesod.Auth.OAuth2.Salesforce: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Salesforce.User
+ Yesod.Auth.OAuth2.Slack: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Slack.SlackTeam
+ Yesod.Auth.OAuth2.Slack: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Slack.SlackUser
+ Yesod.Auth.OAuth2.Spotify: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Spotify.SpotifyUser
+ Yesod.Auth.OAuth2.Spotify: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Spotify.SpotifyUserImage
+ Yesod.Auth.OAuth2.Upcase: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Upcase.UpcaseResponse
+ Yesod.Auth.OAuth2.Upcase: instance Data.Aeson.Types.FromJSON.FromJSON Yesod.Auth.OAuth2.Upcase.UpcaseUser

Files

+ Yesod/Auth/OAuth2/BattleNet.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE CPP               #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+-- |
+--
+-- OAuth2 plugin for Battle.Net
+--
+-- * Authenticates against battle.net.
+-- * Uses user's id as credentials identifier.
+-- * Returns user's battletag in extras.
+--
+
+module Yesod.Auth.OAuth2.BattleNet
+  ( oAuth2BattleNet )
+  where
+
+#if __GLASGOW_HASKELL__ < 710
+import           Control.Applicative  ((<$>), (<*>))
+#endif
+
+import           Control.Exception    (throwIO)
+import           Control.Monad        (mzero)
+
+import           Yesod.Auth
+import           Yesod.Auth.OAuth2
+
+import           Data.Monoid          ((<>))
+import           Network.HTTP.Conduit (Manager)
+
+import           Data.Aeson
+import           Data.Text            (Text)
+import qualified Data.Text            as T (pack, toLower)
+import qualified Data.Text.Encoding   as E (encodeUtf8)
+import           Prelude
+import           Yesod.Core.Widget
+
+data BattleNetUser = BattleNetUser
+              { userId    :: Int
+              , battleTag :: Text
+              }
+
+instance FromJSON BattleNetUser where
+  parseJSON (Object o) = BattleNetUser
+                           <$> o .: "id"
+                           <*> o .: "battletag"
+  parseJSON _ = mzero
+
+oAuth2BattleNet :: YesodAuth m
+                => Text -- ^ Client ID
+                -> Text -- ^ Client Secret
+                -> Text -- ^ User region (e.g. "eu", "cn", "us")
+                -> WidgetT m IO () -- ^ Login widget
+                -> AuthPlugin m
+oAuth2BattleNet clientId clientSecret region widget = authOAuth2Widget widget "battle.net" oAuthData (makeCredentials region)
+  where oAuthData = OAuth2 { oauthClientId            = E.encodeUtf8 clientId
+                           , oauthClientSecret        = E.encodeUtf8 clientSecret
+                           , oauthOAuthorizeEndpoint  = E.encodeUtf8 ("https://" <> host <> "/oauth/authorize")
+                           , oauthAccessTokenEndpoint = E.encodeUtf8 ("https://" <> host <> "/oauth/token")
+                           , oauthCallback            = Nothing
+                           }
+        host = let r = T.toLower region in
+                 case r of
+                   "cn" -> "www.battlenet.com.cn"
+                   _    -> r <> ".battle.net"
+
+makeCredentials :: Text -> Manager -> AccessToken -> IO (Creds m)
+makeCredentials region manager token = do
+    userResult <- authGetJSON manager token ("https://" <> host <> "/account/user") :: IO (OAuth2Result BattleNetUser)
+    case userResult of
+         Left err -> throwIO $ InvalidProfileResponse "battle.net" err
+         Right user -> return Creds
+           { credsPlugin = "battle.net"
+           , credsIdent  = T.pack $ show $ userId user
+           , credsExtra  = [("battletag", battleTag user)]
+           }
+  where host :: URI
+        host = let r = T.toLower region in
+                 case r of
+                   "cn" -> "api.battlenet.com.cn"
+                   _    -> E.encodeUtf8 r <> ".api.battle.net"
Yesod/Auth/OAuth2/Bitbucket.hs view
@@ -50,7 +50,7 @@      parseJSON _ = mzero -data BitbucketUserLinks = BitbucketUserLinks+newtype BitbucketUserLinks = BitbucketUserLinks     { bitbucketAvatarLink :: BitbucketLink     } @@ -60,24 +60,24 @@      parseJSON _ = mzero -data BitbucketLink = BitbucketLink+newtype BitbucketLink = BitbucketLink     { bitbucketLinkHref :: Text     }  instance FromJSON BitbucketLink where     parseJSON (Object o) = BitbucketLink         <$> o .: "href"-  +     parseJSON _ = mzero -data BitbucketEmailSearchResults = BitbucketEmailSearchResults+newtype BitbucketEmailSearchResults = BitbucketEmailSearchResults     { bitbucketEmails :: [BitbucketUserEmail]     }  instance FromJSON BitbucketEmailSearchResults where     parseJSON (Object o) = BitbucketEmailSearchResults         <$> o .: "values"-  +     parseJSON _ = mzero  data BitbucketUserEmail = BitbucketUserEmail
Yesod/Auth/OAuth2/Nylas.hs view
@@ -16,15 +16,13 @@ import Data.Monoid ((<>)) import Data.Text (Text) import Data.Text.Encoding (encodeUtf8, decodeUtf8)-import Network.HTTP.Client (applyBasicAuth, parseUrl, httpLbs, responseStatus-                           , responseBody)+import Network.HTTP.Client (applyBasicAuth, httpLbs, parseRequest, responseBody,+                            responseStatus) import Network.HTTP.Conduit (Manager) import Yesod.Auth (Creds(..), YesodAuth, AuthPlugin)-import Yesod.Auth.OAuth2 (OAuth2(..), AccessToken(..)-                         , YesodOAuth2Exception(InvalidProfileResponse)-                         , authOAuth2)--import qualified Data.Text as T+import Yesod.Auth.OAuth2 (OAuth2(..), AccessToken(..),+                          YesodOAuth2Exception(InvalidProfileResponse),+                          authOAuth2) import qualified Network.HTTP.Types as HT  data NylasAccount = NylasAccount@@ -48,31 +46,22 @@             => Text -- ^ Client ID             -> Text -- ^ Client Secret             -> AuthPlugin m-oauth2Nylas = oauth2NylasScoped ["email"]--oauth2NylasScoped :: YesodAuth m-                  => [Text] -- ^ Scopes-                  -> Text   -- ^ Client ID-                  -> Text   -- ^ Client Secret-                  -> AuthPlugin m-oauth2NylasScoped scopes clientId clientSecret =-    authOAuth2 "nylas" oauth fetchCreds+oauth2Nylas clientId clientSecret = authOAuth2 "nylas" oauth fetchCreds   where-    authorizeUrl = encodeUtf8-                 $ "https://api.nylas.com/oauth/authorize?scope="-                 <> T.intercalate "," scopes-    tokenUrl = "https://api.nylas.com/oauth/token"+    authorizeUrl = encodeUtf8 $ "https://api.nylas.com/oauth/authorize" <>+        "?response_type=code&scope=email&client_id=" <> clientId+     oauth = OAuth2         { oauthClientId = encodeUtf8 clientId         , oauthClientSecret = encodeUtf8 clientSecret         , oauthOAuthorizeEndpoint = authorizeUrl-        , oauthAccessTokenEndpoint = tokenUrl+        , oauthAccessTokenEndpoint = "https://api.nylas.com/oauth/token"         , oauthCallback = Nothing         }  fetchCreds :: Manager -> AccessToken -> IO (Creds a) fetchCreds manager token = do-    req <- authorize <$> parseUrl "https://api.nylas.com/account"+    req <- authorize <$> parseRequest "https://api.nylas.com/account"     resp <- httpLbs req manager     if HT.statusIsSuccessful (responseStatus resp)         then case decode (responseBody resp) of
Yesod/Auth/OAuth2/Upcase.hs view
@@ -41,7 +41,7 @@      parseJSON _ = mzero -data UpcaseResponse = UpcaseResponse UpcaseUser+newtype UpcaseResponse = UpcaseResponse UpcaseUser  instance FromJSON UpcaseResponse where     parseJSON (Object o) = UpcaseResponse
yesod-auth-oauth2.cabal view
@@ -1,5 +1,5 @@ name:            yesod-auth-oauth2-version:         0.2.2+version:         0.2.4 license:         BSD3 license-file:    LICENSE author:          Tom Streller@@ -28,10 +28,10 @@      build-depends:   base                    >= 4.5       && < 5                    , bytestring              >= 0.9.1.4-                   , http-client             >= 0.4.0     && < 0.5+                   , http-client             >= 0.4.0     && < 0.6                    , http-conduit            >= 2.0       && < 3.0                    , http-types              >= 0.8       && < 0.10-                   , aeson                   >= 0.6       && < 0.12+                   , aeson                   >= 0.6       && < 1.1                    , yesod-core              >= 1.2       && < 1.5                    , authenticate            >= 1.3.2.7   && < 1.4                    , random@@ -53,6 +53,7 @@                      Yesod.Auth.OAuth2.Slack                      Yesod.Auth.OAuth2.Salesforce                      Yesod.Auth.OAuth2.Bitbucket+                     Yesod.Auth.OAuth2.BattleNet      ghc-options:     -Wall