mirror of
https://github.com/freckle/yesod-auth-oauth2.git
synced 2026-01-28 11:50:24 +01:00
- It may not be JSON (thought it always is now) - The JSON suffix should be used only when it is (such as in getUserResponseJSON)
74 lines
2.2 KiB
Haskell
74 lines
2.2 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
-- |
|
|
-- OAuth2 plugin for https://slack.com/
|
|
--
|
|
-- * Authenticates against slack
|
|
-- * Uses slack user id as credentials identifier
|
|
--
|
|
module Yesod.Auth.OAuth2.Slack
|
|
( SlackScope(..)
|
|
, oauth2Slack
|
|
, oauth2SlackScoped
|
|
) where
|
|
|
|
import Yesod.Auth.OAuth2.Prelude
|
|
|
|
import Network.HTTP.Client
|
|
(httpLbs, parseUrlThrow, responseBody, setQueryString)
|
|
|
|
data SlackScope
|
|
= SlackBasicScope
|
|
| SlackEmailScope
|
|
| SlackTeamScope
|
|
| SlackAvatarScope
|
|
|
|
scopeText :: SlackScope -> Text
|
|
scopeText SlackBasicScope = "identity.basic"
|
|
scopeText SlackEmailScope = "identity.email"
|
|
scopeText SlackTeamScope = "identity.team"
|
|
scopeText SlackAvatarScope = "identity.avatar"
|
|
|
|
newtype User = User Text
|
|
|
|
instance FromJSON User where
|
|
parseJSON = withObject "User" $ \root -> do
|
|
o <- root .: "user"
|
|
User <$> o .: "id"
|
|
|
|
pluginName :: Text
|
|
pluginName = "slack"
|
|
|
|
defaultScopes :: [SlackScope]
|
|
defaultScopes = [SlackBasicScope]
|
|
|
|
oauth2Slack :: YesodAuth m => Text -> Text -> AuthPlugin m
|
|
oauth2Slack = oauth2SlackScoped defaultScopes
|
|
|
|
oauth2SlackScoped :: YesodAuth m => [SlackScope] -> Text -> Text -> AuthPlugin m
|
|
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"
|
|
userResponse <- responseBody <$> httpLbs req manager
|
|
|
|
either
|
|
(const $ throwIO $ InvalidProfileResponse pluginName userResponse)
|
|
(\(User userId) -> pure Creds
|
|
{ credsPlugin = pluginName
|
|
, credsIdent = userId
|
|
, credsExtra = setExtra token userResponse
|
|
}
|
|
)
|
|
$ eitherDecode userResponse
|
|
where
|
|
oauth2 = OAuth2
|
|
{ oauthClientId = clientId
|
|
, oauthClientSecret = clientSecret
|
|
, oauthOAuthorizeEndpoint = "https://slack.com/oauth/authorize" `withQuery`
|
|
[ scopeParam "," $ map scopeText scopes
|
|
]
|
|
, oauthAccessTokenEndpoint = "https://slack.com/api/oauth.access"
|
|
, oauthCallback = Nothing
|
|
}
|