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 +80/−0
- Yesod/Auth/OAuth2/Bitbucket.hs +5/−5
- Yesod/Auth/OAuth2/Nylas.hs +11/−22
- Yesod/Auth/OAuth2/Upcase.hs +1/−1
- yesod-auth-oauth2.cabal +4/−3
+ 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