diff --git a/.restyled.yaml b/.restyled.yaml index fa61b26..be7a0c0 100644 --- a/.restyled.yaml +++ b/.restyled.yaml @@ -1,10 +1,4 @@ restylers: - - brittany: - include: - - "**/*.hs" - - "!src/Network/OAuth/OAuth2/Compat.hs" # CPP - - stylish-haskell: - include: - - "**/*.hs" - - "!src/Network/OAuth/OAuth2/Compat.hs" # CPP + - fourmolu + - "!stylish-haskell" - "*" diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml deleted file mode 100644 index a25ae44..0000000 --- a/.stylish-haskell.yaml +++ /dev/null @@ -1,21 +0,0 @@ -steps: - - simple_align: - cases: false - top_level_patterns: false - records: false - - imports: - align: none - list_align: after_alias - pad_module_names: false - long_list_align: new_line_multiline - empty_list_align: right_after - list_padding: 4 - separate_lists: false - space_surround: false - - language_pragmas: - style: vertical - align: false - remove_redundant: true - - trailing_whitespace: {} -columns: 80 -newline: native diff --git a/brittany.yaml b/brittany.yaml deleted file mode 100644 index 15e0ab3..0000000 --- a/brittany.yaml +++ /dev/null @@ -1,44 +0,0 @@ ---- -conf_debug: - dconf_roundtrip_exactprint_only: false - dconf_dump_bridoc_simpl_par: false - dconf_dump_ast_unknown: false - dconf_dump_bridoc_simpl_floating: false - dconf_dump_config: false - dconf_dump_bridoc_raw: false - dconf_dump_bridoc_final: false - dconf_dump_bridoc_simpl_alt: false - dconf_dump_bridoc_simpl_indent: false - dconf_dump_annotations: false - dconf_dump_bridoc_simpl_columns: false - dconf_dump_ast_full: false -conf_errorHandling: - econf_ExactPrintFallback: ExactPrintFallbackModeInline - econf_Werror: false - econf_omit_output_valid_check: false - econf_produceOutputOnErrors: false -conf_preprocessor: - ppconf_CPPMode: CPPModeAbort - ppconf_hackAroundIncludes: false -conf_obfuscate: false -conf_roundtrip_exactprint_only: false -conf_version: 1 -conf_layout: - lconfig_reformatModulePreamble: true - lconfig_altChooser: - tag: AltChooserBoundedSearch - contents: 3 - lconfig_allowSingleLineExportList: false - lconfig_importColumn: 60 - lconfig_hangingTypeSignature: false - lconfig_importAsColumn: 50 - lconfig_alignmentLimit: 1 - lconfig_indentListSpecial: true - lconfig_indentAmount: 2 - lconfig_alignmentBreakOnMultiline: true - lconfig_cols: 80 - lconfig_indentPolicy: IndentPolicyLeft - lconfig_indentWhereSpecial: true - lconfig_columnAlignMode: - tag: ColumnAlignModeDisabled - contents: 0.7 diff --git a/example/Main.hs b/example/Main.hs index 715fa30..9c8d836 100644 --- a/example/Main.hs +++ b/example/Main.hs @@ -13,7 +13,7 @@ import Data.Aeson.Encode.Pretty import Data.ByteString.Lazy (fromStrict, toStrict) import qualified Data.Map as M import Data.Maybe (fromJust) -import Data.String (IsString(fromString)) +import Data.String (IsString (fromString)) import Data.Text (Text, pack) import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8) @@ -46,13 +46,15 @@ data App = App , appAuthPlugins :: [AuthPlugin App] } -mkYesod "App" [parseRoutes| +mkYesod + "App" + [parseRoutes| / RootR GET /auth AuthR Auth getAuth |] instance Yesod App where - -- see https://github.com/thoughtbot/yesod-auth-oauth2/issues/87 + -- see https://github.com/thoughtbot/yesod-auth-oauth2/issues/87 approot = ApprootStatic "http://localhost:3000" instance YesodAuth App where @@ -65,9 +67,9 @@ instance YesodAuth App where -- 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" @@ -80,23 +82,24 @@ instance RenderMessage App FormMessage where getRootR :: Handler Html getRootR = do - sess <- getSession + sess <- getSession - let - prettify - = decodeUtf8 - . toStrict - . encodePretty - . fromJust - . decode @Value - . fromStrict + let + prettify = + decodeUtf8 + . toStrict + . encodePretty + . fromJust + . decode @Value + . fromStrict - mCredsIdent = decodeUtf8 <$> M.lookup "credsIdent" sess - mCredsPlugin = decodeUtf8 <$> M.lookup "credsPlugin" sess - mAccessToken = decodeUtf8 <$> M.lookup "accessToken" sess - mUserResponse = prettify <$> M.lookup "userResponse" sess + mCredsIdent = decodeUtf8 <$> M.lookup "credsIdent" sess + mCredsPlugin = decodeUtf8 <$> M.lookup "credsPlugin" sess + mAccessToken = decodeUtf8 <$> M.lookup "accessToken" sess + mUserResponse = prettify <$> M.lookup "userResponse" sess - defaultLayout [whamlet| + defaultLayout + [whamlet|
|]
-asWidget BigBlack
- = [whamlet|
|]
-asWidget SmallWhite
- = [whamlet|
|]
-asWidget SmallBlack
- = [whamlet|
|]
+asWidget BigBlack =
+ [whamlet|
|]
+asWidget SmallWhite =
+ [whamlet|
|]
+asWidget SmallBlack =
+ [whamlet|
|]
asWidget (Custom a) = a
pluginName :: Text
@@ -57,25 +58,28 @@ oauth2EveScoped
oauth2EveScoped scopes widgetType clientId clientSecret =
authOAuth2Widget (asWidget widgetType) pluginName oauth2 $ \manager token ->
do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://login.eveonline.com/oauth/verify"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://login.eveonline.com/oauth/verify"
- pure Creds
- { credsPlugin = "eveonline"
- -- FIXME: Preserved bug. See similar comment in Bitbucket provider.
- , credsIdent = T.pack $ show userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = "eveonline"
+ , -- FIXME: Preserved bug. See similar comment in Bitbucket provider.
+ credsIdent = T.pack $ show userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://login.eveonline.com/oauth/authorize"
- `withQuery` [("response_type", "code"), scopeParam " " scopes]
- , oauth2TokenEndpoint = "https://login.eveonline.com/oauth/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://login.eveonline.com/oauth/authorize"
+ `withQuery` [("response_type", "code"), scopeParam " " scopes]
+ , oauth2TokenEndpoint = "https://login.eveonline.com/oauth/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Exception.hs b/src/Yesod/Auth/OAuth2/Exception.hs
index 22b169a..5b05512 100644
--- a/src/Yesod/Auth/OAuth2/Exception.hs
+++ b/src/Yesod/Auth/OAuth2/Exception.hs
@@ -1,7 +1,7 @@
{-# LANGUAGE DeriveDataTypeable #-}
module Yesod.Auth.OAuth2.Exception
- ( YesodOAuth2Exception(..)
+ ( YesodOAuth2Exception (..)
) where
import Control.Exception.Safe
@@ -9,21 +9,18 @@ import Data.ByteString.Lazy (ByteString)
import Data.Text (Text)
data YesodOAuth2Exception
- = OAuth2Error Text ByteString
- -- ^ HTTP error during OAuth2 handshake
+ = -- | HTTP error during OAuth2 handshake
--
-- Plugin name and JSON-encoded @OAuth2Error@ from @hoauth2@.
- --
- | JSONDecodingError Text String
- -- ^ User profile was not as expected
+ OAuth2Error Text ByteString
+ | -- | User profile was not as expected
--
-- Plugin name and Aeson parse error message.
- --
- | GenericError Text String
- -- ^ Other error conditions
+ JSONDecodingError Text String
+ | -- | Other error conditions
--
-- Plugin name and error message.
- --
- deriving (Show, Typeable)
+ GenericError Text String
+ deriving (Show, Typeable)
instance Exception YesodOAuth2Exception
diff --git a/src/Yesod/Auth/OAuth2/GitHub.hs b/src/Yesod/Auth/OAuth2/GitHub.hs
index 753ba82..9725703 100644
--- a/src/Yesod/Auth/OAuth2/GitHub.hs
+++ b/src/Yesod/Auth/OAuth2/GitHub.hs
@@ -1,11 +1,11 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
--
-- OAuth2 plugin for http://github.com
--
-- * Authenticates against github
-- * Uses github user id as credentials identifier
---
module Yesod.Auth.OAuth2.GitHub
( oauth2GitHub
, oauth2GitHubScoped
@@ -32,24 +32,27 @@ oauth2GitHub = oauth2GitHubScoped defaultScopes
oauth2GitHubScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
oauth2GitHubScoped scopes clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://api.github.com/user"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://api.github.com/user"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = T.pack $ show userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = T.pack $ show userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://github.com/login/oauth/authorize"
- `withQuery` [scopeParam "," scopes]
- , oauth2TokenEndpoint = "https://github.com/login/oauth/access_token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://github.com/login/oauth/authorize"
+ `withQuery` [scopeParam "," scopes]
+ , oauth2TokenEndpoint = "https://github.com/login/oauth/access_token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/GitLab.hs b/src/Yesod/Auth/OAuth2/GitLab.hs
index 72d0bbd..e5a05fc 100644
--- a/src/Yesod/Auth/OAuth2/GitLab.hs
+++ b/src/Yesod/Auth/OAuth2/GitLab.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE OverloadedStrings #-}
+
module Yesod.Auth.OAuth2.GitLab
( oauth2GitLab
, oauth2GitLabHostScopes
@@ -32,7 +33,6 @@ defaultScopes = ["read_user"]
--
-- > oauth2GitLabHostScopes defaultHost ["api", "read_user"]
-- > oauth2GitLabHostScopes "https://gitlab.example.com" defaultScopes
---
oauth2GitLab :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2GitLab = oauth2GitLabHostScopes defaultHost defaultScopes
@@ -43,17 +43,19 @@ oauth2GitLabHostScopes host scopes clientId clientSecret =
(User userId, userResponse) <-
authGetProfile pluginName manager token $ host `withPath` "/api/v4/user"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = T.pack $ show userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = T.pack $ show userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes]
- , oauth2TokenEndpoint = host `withPath` "/oauth/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ host `withPath` "/oauth/authorize" `withQuery` [scopeParam " " scopes]
+ , oauth2TokenEndpoint = host `withPath` "/oauth/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Google.hs b/src/Yesod/Auth/OAuth2/Google.hs
index 2e293ae..77e7726 100644
--- a/src/Yesod/Auth/OAuth2/Google.hs
+++ b/src/Yesod/Auth/OAuth2/Google.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
+
-- |
--
-- OAuth2 plugin for http://www.google.com
@@ -23,7 +24,6 @@
-- > updatedCreds = creds { credsIdent = email }
-- >
-- > -- continue normally with updatedCreds
---
module Yesod.Auth.OAuth2.Google
( oauth2Google
, oauth2GoogleWidget
@@ -38,9 +38,10 @@ newtype User = User Text
instance FromJSON User where
parseJSON =
- withObject "User" $ \o -> User
- -- Required for data backwards-compatibility
- <$> (("google-uid:" <>) <$> o .: "sub")
+ withObject "User" $ \o ->
+ User
+ -- Required for data backwards-compatibility
+ <$> (("google-uid:" <>) <$> o .: "sub")
pluginName :: Text
pluginName = "google"
@@ -63,24 +64,27 @@ oauth2GoogleScopedWidget
:: YesodAuth m => WidgetFor m () -> [Text] -> Text -> Text -> AuthPlugin m
oauth2GoogleScopedWidget widget scopes clientId clientSecret =
authOAuth2Widget widget pluginName oauth2 $ \manager token -> do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://www.googleapis.com/oauth2/v3/userinfo"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://www.googleapis.com/oauth2/v3/userinfo"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://accounts.google.com/o/oauth2/auth"
- `withQuery` [scopeParam " " scopes]
- , oauth2TokenEndpoint = "https://www.googleapis.com/oauth2/v3/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://accounts.google.com/o/oauth2/auth"
+ `withQuery` [scopeParam " " scopes]
+ , oauth2TokenEndpoint = "https://www.googleapis.com/oauth2/v3/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Nylas.hs b/src/Yesod/Auth/OAuth2/Nylas.hs
index 99b5dce..fa043d5 100644
--- a/src/Yesod/Auth/OAuth2/Nylas.hs
+++ b/src/Yesod/Auth/OAuth2/Nylas.hs
@@ -26,41 +26,45 @@ defaultScopes = ["email"]
oauth2Nylas :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2Nylas clientId clientSecret =
authOAuth2 pluginName oauth $ \manager token -> do
- req <- applyBasicAuth (encodeUtf8 $ atoken $ accessToken token) ""
- <$> parseRequest "https://api.nylas.com/account"
+ req <-
+ applyBasicAuth (encodeUtf8 $ atoken $ accessToken token) ""
+ <$> parseRequest "https://api.nylas.com/account"
resp <- httpLbs req manager
let userResponse = responseBody resp
-- FIXME: was this working? I'm 95% sure that the client will throw its
-- own exception on unsuccessful status codes.
- unless (HT.statusIsSuccessful $ responseStatus resp)
- $ throwIO
- $ YesodOAuth2Exception.GenericError pluginName
- $ "Unsuccessful HTTP response: "
- <> BL8.unpack userResponse
+ unless (HT.statusIsSuccessful $ responseStatus resp) $
+ throwIO $
+ YesodOAuth2Exception.GenericError pluginName $
+ "Unsuccessful HTTP response: "
+ <> BL8.unpack userResponse
either
- (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
- (\(User userId) -> pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
- )
+ (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
+ ( \(User userId) ->
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
+ )
$ eitherDecode userResponse
where
- oauth = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://api.nylas.com/oauth/authorize"
- `withQuery` [ ("response_type", "code")
- , ("client_id", encodeUtf8 clientId)
- -- N.B. The scopes delimeter is unknown/untested. Verify that before
- -- extracting this to an argument and offering a Scoped function. In
- -- its current state, it doesn't matter because it's only one scope.
- , scopeParam "," defaultScopes
- ]
- , oauth2TokenEndpoint = "https://api.nylas.com/oauth/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://api.nylas.com/oauth/authorize"
+ `withQuery` [ ("response_type", "code")
+ , ("client_id", encodeUtf8 clientId)
+ , -- N.B. The scopes delimeter is unknown/untested. Verify that before
+ -- extracting this to an argument and offering a Scoped function. In
+ -- its current state, it doesn't matter because it's only one scope.
+ scopeParam "," defaultScopes
+ ]
+ , oauth2TokenEndpoint = "https://api.nylas.com/oauth/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Prelude.hs b/src/Yesod/Auth/OAuth2/Prelude.hs
index 8eba4a0..cc4d8c4 100644
--- a/src/Yesod/Auth/OAuth2/Prelude.hs
+++ b/src/Yesod/Auth/OAuth2/Prelude.hs
@@ -1,10 +1,10 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
+
-- |
--
-- Modules and support functions required by most or all provider
-- implementations. May also be useful for writing local providers.
---
module Yesod.Auth.OAuth2.Prelude
( authGetProfile
, scopeParam
@@ -20,8 +20,8 @@ module Yesod.Auth.OAuth2.Prelude
, (.:?)
, (.=)
, (<>)
- , FromJSON(..)
- , ToJSON(..)
+ , FromJSON (..)
+ , ToJSON (..)
, eitherDecode
, withObject
@@ -29,22 +29,22 @@ module Yesod.Auth.OAuth2.Prelude
, throwIO
-- * OAuth2
- , OAuth2(..)
- , OAuth2Token(..)
- , AccessToken(..)
- , RefreshToken(..)
+ , OAuth2 (..)
+ , OAuth2Token (..)
+ , AccessToken (..)
+ , RefreshToken (..)
-- * HTTP
, Manager
-- * Yesod
- , YesodAuth(..)
- , AuthPlugin(..)
- , Creds(..)
+ , YesodAuth (..)
+ , AuthPlugin (..)
+ , Creds (..)
-- * Bytestring URI types
, URI
- , Host(..)
+ , Host (..)
-- * Bytestring URI extensions
, module URI.ByteString.Extension
@@ -74,7 +74,6 @@ import qualified Yesod.Auth.OAuth2.Exception as YesodOAuth2Exception
-- The response should be parsed only far enough to read the required
-- @'credsIdent'@. Additional information should either be re-parsed by or
-- fetched via additional requests by consumers.
---
authGetProfile
:: FromJSON a
=> Text
@@ -101,7 +100,7 @@ fromAuthJSON name =
-- | A tuple of @\"scope\"@ and the given scopes separated by a delimiter
scopeParam :: Text -> [Text] -> (ByteString, ByteString)
-scopeParam d = ("scope", ) . encodeUtf8 . T.intercalate d
+scopeParam d = ("scope",) . encodeUtf8 . T.intercalate d
-- brittany-disable-next-binding
@@ -115,10 +114,9 @@ scopeParam d = ("scope", ) . encodeUtf8 . T.intercalate d
-- May set the following keys:
--
-- - @refreshToken@: if the provider supports refreshing the @accessToken@
---
setExtra :: OAuth2Token -> BL.ByteString -> [(Text, Text)]
setExtra token userResponse =
- [ ("accessToken", atoken $ accessToken token)
- , ("userResponse", decodeUtf8 $ BL.toStrict userResponse)
- ]
- <> maybe [] (pure . ("refreshToken", ) . rtoken) (refreshToken token)
+ [ ("accessToken", atoken $ accessToken token)
+ , ("userResponse", decodeUtf8 $ BL.toStrict userResponse)
+ ]
+ <> maybe [] (pure . ("refreshToken",) . rtoken) (refreshToken token)
diff --git a/src/Yesod/Auth/OAuth2/Random.hs b/src/Yesod/Auth/OAuth2/Random.hs
index b69835b..8c63925 100644
--- a/src/Yesod/Auth/OAuth2/Random.hs
+++ b/src/Yesod/Auth/OAuth2/Random.hs
@@ -5,7 +5,7 @@ module Yesod.Auth.OAuth2.Random
) where
import Crypto.Random (MonadRandom, getRandomBytes)
-import Data.ByteArray.Encoding (Base(Base64), convertToBase)
+import Data.ByteArray.Encoding (Base (Base64), convertToBase)
import Data.ByteString (ByteString)
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8)
@@ -13,7 +13,7 @@ import Data.Text.Encoding (decodeUtf8)
randomText
:: MonadRandom m
=> Int
- -- ^ Size in Bytes (note necessarily characters)
+ -- ^ Size in Bytes (note necessarily characters)
-> m Text
randomText size =
decodeUtf8 . convertToBase @ByteString Base64 <$> getRandomBytes size
diff --git a/src/Yesod/Auth/OAuth2/Salesforce.hs b/src/Yesod/Auth/OAuth2/Salesforce.hs
index 0fbff78..c874d84 100644
--- a/src/Yesod/Auth/OAuth2/Salesforce.hs
+++ b/src/Yesod/Auth/OAuth2/Salesforce.hs
@@ -1,11 +1,11 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
--
-- OAuth2 plugin for http://login.salesforce.com
--
-- * Authenticates against Salesforce (or sandbox)
-- * Uses Salesforce user id as credentials identifier
---
module Yesod.Auth.OAuth2.Salesforce
( oauth2Salesforce
, oauth2SalesforceScoped
@@ -30,47 +30,54 @@ oauth2Salesforce :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2Salesforce = oauth2SalesforceScoped defaultScopes
oauth2SalesforceScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
-oauth2SalesforceScoped = salesforceHelper
- pluginName
- "https://login.salesforce.com/services/oauth2/userinfo"
- "https://login.salesforce.com/services/oauth2/authorize"
- "https://login.salesforce.com/services/oauth2/token"
+oauth2SalesforceScoped =
+ salesforceHelper
+ pluginName
+ "https://login.salesforce.com/services/oauth2/userinfo"
+ "https://login.salesforce.com/services/oauth2/authorize"
+ "https://login.salesforce.com/services/oauth2/token"
oauth2SalesforceSandbox :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2SalesforceSandbox = oauth2SalesforceSandboxScoped defaultScopes
oauth2SalesforceSandboxScoped
:: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
-oauth2SalesforceSandboxScoped = salesforceHelper
- (pluginName <> "-sandbox")
- "https://test.salesforce.com/services/oauth2/userinfo"
- "https://test.salesforce.com/services/oauth2/authorize"
- "https://test.salesforce.com/services/oauth2/token"
+oauth2SalesforceSandboxScoped =
+ salesforceHelper
+ (pluginName <> "-sandbox")
+ "https://test.salesforce.com/services/oauth2/userinfo"
+ "https://test.salesforce.com/services/oauth2/authorize"
+ "https://test.salesforce.com/services/oauth2/token"
salesforceHelper
:: YesodAuth m
=> Text
- -> URI -- ^ User profile
- -> URI -- ^ Authorize
- -> URI -- ^ Token
+ -> URI
+ -- ^ User profile
+ -> URI
+ -- ^ Authorize
+ -> URI
+ -- ^ Token
-> [Text]
-> Text
-> Text
-> AuthPlugin m
-salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSecret
- = authOAuth2 name oauth2 $ \manager token -> do
+salesforceHelper name profileUri authorizeUri tokenUri scopes clientId clientSecret =
+ authOAuth2 name oauth2 $ \manager token -> do
(User userId, userResponse) <- authGetProfile name manager token profileUri
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
- , oauth2TokenEndpoint = tokenUri
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint = authorizeUri `withQuery` [scopeParam " " scopes]
+ , oauth2TokenEndpoint = tokenUri
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Slack.hs b/src/Yesod/Auth/OAuth2/Slack.hs
index b909b5b..d416444 100644
--- a/src/Yesod/Auth/OAuth2/Slack.hs
+++ b/src/Yesod/Auth/OAuth2/Slack.hs
@@ -1,12 +1,12 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
-- OAuth2 plugin for https://slack.com/
--
-- * Authenticates against slack
-- * Uses slack user id as credentials identifier
---
module Yesod.Auth.OAuth2.Slack
- ( SlackScope(..)
+ ( SlackScope (..)
, oauth2Slack
, oauth2SlackScoped
) where
@@ -14,14 +14,18 @@ module Yesod.Auth.OAuth2.Slack
import Yesod.Auth.OAuth2.Prelude
import Network.HTTP.Client
- (httpLbs, parseUrlThrow, responseBody, setQueryString)
+ ( httpLbs
+ , parseUrlThrow
+ , responseBody
+ , setQueryString
+ )
import Yesod.Auth.OAuth2.Exception as YesodOAuth2Exception
data SlackScope
- = SlackBasicScope
- | SlackEmailScope
- | SlackTeamScope
- | SlackAvatarScope
+ = SlackBasicScope
+ | SlackEmailScope
+ | SlackTeamScope
+ | SlackAvatarScope
scopeText :: SlackScope -> Text
scopeText SlackBasicScope = "identity.basic"
@@ -50,26 +54,30 @@ oauth2SlackScoped
oauth2SlackScoped scopes clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
let param = encodeUtf8 $ atoken $ accessToken token
- req <- setQueryString [("token", Just param)]
- <$> parseUrlThrow "https://slack.com/api/users.identity"
+ req <-
+ setQueryString [("token", Just param)]
+ <$> parseUrlThrow "https://slack.com/api/users.identity"
userResponse <- responseBody <$> httpLbs req manager
either
- (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
- (\(User userId) -> pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
- )
+ (throwIO . YesodOAuth2Exception.JSONDecodingError pluginName)
+ ( \(User userId) ->
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
+ )
$ eitherDecode userResponse
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://slack.com/oauth/authorize"
- `withQuery` [scopeParam "," $ map scopeText scopes]
- , oauth2TokenEndpoint = "https://slack.com/api/oauth.access"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://slack.com/oauth/authorize"
+ `withQuery` [scopeParam "," $ map scopeText scopes]
+ , oauth2TokenEndpoint = "https://slack.com/api/oauth.access"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Spotify.hs b/src/Yesod/Auth/OAuth2/Spotify.hs
index 93bcc48..47c3e39 100644
--- a/src/Yesod/Auth/OAuth2/Spotify.hs
+++ b/src/Yesod/Auth/OAuth2/Spotify.hs
@@ -1,8 +1,8 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
--
-- OAuth2 plugin for http://spotify.com
---
module Yesod.Auth.OAuth2.Spotify
( oauth2Spotify
) where
@@ -20,24 +20,27 @@ pluginName = "spotify"
oauth2Spotify :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
oauth2Spotify scopes clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://api.spotify.com/v1/me"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://api.spotify.com/v1/me"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://accounts.spotify.com/authorize"
- `withQuery` [scopeParam " " scopes]
- , oauth2TokenEndpoint = "https://accounts.spotify.com/api/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://accounts.spotify.com/authorize"
+ `withQuery` [scopeParam " " scopes]
+ , oauth2TokenEndpoint = "https://accounts.spotify.com/api/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Twitch.hs b/src/Yesod/Auth/OAuth2/Twitch.hs
index cfa066f..8b6e46e 100644
--- a/src/Yesod/Auth/OAuth2/Twitch.hs
+++ b/src/Yesod/Auth/OAuth2/Twitch.hs
@@ -1,11 +1,11 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
--
-- OAuth2 plugin for http://twitch.tv
--
-- * Authenticates against twitch
-- * Uses twitch user id as credentials identifier
---
module Yesod.Auth.OAuth2.Twitch
( oauth2Twitch
, oauth2TwitchScoped
@@ -32,28 +32,31 @@ oauth2Twitch = oauth2TwitchScoped defaultScopes
oauth2TwitchScoped :: YesodAuth m => [Text] -> Text -> Text -> AuthPlugin m
oauth2TwitchScoped scopes clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://id.twitch.tv/oauth2/validate"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://id.twitch.tv/oauth2/validate"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://id.twitch.tv/oauth2/authorize"
- `withQuery` [scopeParam " " scopes]
- , oauth2TokenEndpoint =
- "https://id.twitch.tv/oauth2/token"
- `withQuery` [ ("client_id", T.encodeUtf8 clientId)
- , ("client_secret", T.encodeUtf8 clientSecret)
- ]
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://id.twitch.tv/oauth2/authorize"
+ `withQuery` [scopeParam " " scopes]
+ , oauth2TokenEndpoint =
+ "https://id.twitch.tv/oauth2/token"
+ `withQuery` [ ("client_id", T.encodeUtf8 clientId)
+ , ("client_secret", T.encodeUtf8 clientSecret)
+ ]
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/Upcase.hs b/src/Yesod/Auth/OAuth2/Upcase.hs
index 3d69474..ee903ed 100644
--- a/src/Yesod/Auth/OAuth2/Upcase.hs
+++ b/src/Yesod/Auth/OAuth2/Upcase.hs
@@ -1,11 +1,11 @@
{-# LANGUAGE OverloadedStrings #-}
+
-- |
--
-- OAuth2 plugin for http://upcase.com
--
-- * Authenticates against upcase
-- * Uses upcase user id as credentials identifier
---
module Yesod.Auth.OAuth2.Upcase
( oauth2Upcase
) where
@@ -27,22 +27,25 @@ pluginName = "upcase"
oauth2Upcase :: YesodAuth m => Text -> Text -> AuthPlugin m
oauth2Upcase clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
- (User userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "http://upcase.com/api/v1/me.json"
+ (User userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "http://upcase.com/api/v1/me.json"
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = T.pack $ show userId
- , credsExtra = setExtra token userResponse
- }
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = T.pack $ show userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize"
- , oauth2TokenEndpoint = "http://upcase.com/oauth/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint = "http://upcase.com/oauth/authorize"
+ , oauth2TokenEndpoint = "http://upcase.com/oauth/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/src/Yesod/Auth/OAuth2/WordPressDotCom.hs b/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
index 4c6b36d..5059413 100644
--- a/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
+++ b/src/Yesod/Auth/OAuth2/WordPressDotCom.hs
@@ -16,31 +16,35 @@ instance FromJSON WpUser where
parseJSON = withObject "WpUser" $ \o -> WpUser <$> o .: "ID"
oauth2WordPressDotCom
- :: (YesodAuth m)
- => Text -- ^ Client Id
- -> Text -- ^ Client Secret
+ :: YesodAuth m
+ => Text
+ -- ^ Client Id
+ -> Text
+ -- ^ Client Secret
-> AuthPlugin m
oauth2WordPressDotCom clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
- (WpUser userId, userResponse) <- authGetProfile
- pluginName
- manager
- token
- "https://public-api.wordpress.com/rest/v1/me/"
-
- pure Creds
- { credsPlugin = pluginName
- , credsIdent = T.pack $ show userId
- , credsExtra = setExtra token userResponse
- }
+ (WpUser userId, userResponse) <-
+ authGetProfile
+ pluginName
+ manager
+ token
+ "https://public-api.wordpress.com/rest/v1/me/"
+ pure
+ Creds
+ { credsPlugin = pluginName
+ , credsIdent = T.pack $ show userId
+ , credsExtra = setExtra token userResponse
+ }
where
- oauth2 = OAuth2
- { oauth2ClientId = clientId
- , oauth2ClientSecret = Just clientSecret
- , oauth2AuthorizeEndpoint =
- "https://public-api.wordpress.com/oauth2/authorize"
- `withQuery` [scopeParam "," ["auth"]]
- , oauth2TokenEndpoint = "https://public-api.wordpress.com/oauth2/token"
- , oauth2RedirectUri = Nothing
- }
+ oauth2 =
+ OAuth2
+ { oauth2ClientId = clientId
+ , oauth2ClientSecret = Just clientSecret
+ , oauth2AuthorizeEndpoint =
+ "https://public-api.wordpress.com/oauth2/authorize"
+ `withQuery` [scopeParam "," ["auth"]]
+ , oauth2TokenEndpoint = "https://public-api.wordpress.com/oauth2/token"
+ , oauth2RedirectUri = Nothing
+ }
diff --git a/test/URI/ByteString/ExtensionSpec.hs b/test/URI/ByteString/ExtensionSpec.hs
index a5ea600..3533a68 100644
--- a/test/URI/ByteString/ExtensionSpec.hs
+++ b/test/URI/ByteString/ExtensionSpec.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
+
module URI.ByteString.ExtensionSpec
( spec
) where
@@ -61,9 +62,8 @@ spec = do
uriWithQuery `shouldBe` [uri|http://example.com?foo=bar|]
it "handles a URI with an existing query" $ do
- let
- uriWithQuery =
- [uri|http://example.com?foo=bar|] `withQuery` [("baz", "bat")]
+ let uriWithQuery =
+ [uri|http://example.com?foo=bar|] `withQuery` [("baz", "bat")]
uriWithQuery `shouldBe` [uri|http://example.com?foo=bar&baz=bat|]
@@ -71,9 +71,8 @@ spec = do
-- it's worthwhile to show that you don't (and can't) pre-sanitize when
-- using this function.
it "handles santization of the query" $ do
- let
- uriWithQuery =
- [uri|http://example.com|] `withQuery` [("foo", "bar baz")]
+ let uriWithQuery =
+ [uri|http://example.com|] `withQuery` [("foo", "bar baz")]
toText uriWithQuery `shouldBe` "http://example.com?foo=bar%20baz"