Restyled by brittany

This commit is contained in:
Restyled.io 2023-06-30 19:53:18 +00:00 committed by William R. Arellano
parent c04092cfc5
commit a20f38ff18
4 changed files with 83 additions and 70 deletions

View File

@ -34,13 +34,13 @@ import Yesod.Auth.OAuth2.GitHub
import Yesod.Auth.OAuth2.GitLab
import Yesod.Auth.OAuth2.Google
import Yesod.Auth.OAuth2.Nylas
import Yesod.Auth.OAuth2.Okta
import Yesod.Auth.OAuth2.Salesforce
import Yesod.Auth.OAuth2.Slack
import Yesod.Auth.OAuth2.Spotify
import Yesod.Auth.OAuth2.Twitch
import Yesod.Auth.OAuth2.Upcase
import Yesod.Auth.OAuth2.WordPressDotCom
import Yesod.Auth.OAuth2.Okta
data App = App
{ appHttpManager :: Manager
@ -148,7 +148,9 @@ mkFoundation = do
, loadPlugin oauth2Twitch "TWITCH"
, loadPlugin oauth2WordPressDotCom "WORDPRESS_DOT_COM"
, loadPlugin oauth2Upcase "UPCASE"
, loadPlugin (oauth2Okta False (fromString oktaHost) "default" Nothing) "OKTA"
, loadPlugin
(oauth2Okta False (fromString oktaHost) "default" Nothing)
"OKTA"
]
return App { .. }

View File

@ -18,8 +18,8 @@ import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Network.HTTP.Conduit (Manager)
import Network.OAuth.OAuth2.Compat
import UnliftIO.Exception
import URI.ByteString.Extension
import UnliftIO.Exception
import Yesod.Auth hiding (ServerError)
import Yesod.Auth.OAuth2.DispatchError
import Yesod.Auth.OAuth2.ErrorResponse
@ -101,10 +101,10 @@ withCallbackAndState
-> m OAuth2
withCallbackAndState name oauth2 csrf = do
pluginURI <- ($ PluginR name ["callback"]) <$> getParentUrlRender
let uri =
case oauth2AppRoot oauth2 of
Just root -> root <> pluginURI
Nothing -> pluginURI
let
uri = case oauth2AppRoot oauth2 of
Just root -> root <> pluginURI
Nothing -> pluginURI
callback <- maybe (throwError $ InvalidCallbackUri uri) pure $ fromText uri
pure oauth2
{ oauth2RedirectUri = Just callback

View File

@ -8,18 +8,17 @@
-- -- * Authenticates against a specific Okta application
-- -- * Uses Okta sub as user id
module Yesod.Auth.OAuth2.Okta
( oauth2Okta,
oauth2OktaWithScopes,
defaultOktaScopes,
pluginName,
User (..),
)
where
( oauth2Okta
, oauth2OktaWithScopes
, defaultOktaScopes
, pluginName
, User(..)
) where
import Data.Aeson as Aeson
import Data.ByteString (ByteString)
import Yesod.Auth.OAuth2.Prelude
import Prelude
import Yesod.Auth.OAuth2.Prelude
-- | Okta User's info: https://developer.okta.com/docs/reference/api/oidc/#userinfo
newtype User = User Text
@ -36,80 +35,92 @@ pluginName :: Text
pluginName = "okta"
-- | Creates an Okta 'AuthPlugin' for application using the default scopes.
oauth2Okta ::
YesodAuth m =>
oauth2Okta
:: YesodAuth m
=>
-- | Prompt login on authorize redirect
Bool ->
Bool
->
-- | The host address of the Okta application (absolute)
URI ->
URI
->
-- | The authorization server
ByteString ->
ByteString
->
-- | Application Root for redirect links
Maybe Text ->
Maybe Text
->
-- | Client ID of the Okta application
Text ->
Text
->
-- | Client Secret of the Okta application
Text ->
AuthPlugin m
Text
-> AuthPlugin m
oauth2Okta = oauth2OktaWithScopes defaultOktaScopes
-- | Creates an Okta 'AuthPlugin' for application with access to the provided scopes.
oauth2OktaWithScopes ::
YesodAuth m =>
oauth2OktaWithScopes
:: YesodAuth m
=>
-- | The scopes accessible to the 'AuthPlugin'
[Text] ->
[Text]
->
-- | Prompt login on authorize redirect
Bool ->
Bool
->
-- | The host address of the Okta application (absolute)
URI ->
URI
->
-- | The authorization server
ByteString ->
ByteString
->
-- | Application Root for building callbacks
Maybe Text ->
Maybe Text
->
-- | Client ID of the Okta application
Text ->
Text
->
-- | Client Secret of the Okta application
Text ->
AuthPlugin m
oauth2OktaWithScopes scopes shouldPrompt host authorizationServer appRoot clientId clientSecret =
authOAuth2 pluginName oauth2 $ \manager token -> do
(User uid, userResponse) <-
authGetProfile
pluginName
manager
token
(host `withPath` (mkEndpointSegment authorizationServer "userinfo"))
pure
Creds
{ credsPlugin = pluginName,
credsIdent = uid,
credsExtra = setExtra token userResponse
}
where
queryParams =
if shouldPrompt
then [scopeParam " " scopes, ("prompt", "login")]
else [scopeParam " " scopes]
oauth2 =
OAuth2
{ oauth2ClientId = clientId,
oauth2ClientSecret = Just clientSecret,
oauth2AuthorizeEndpoint =
host
`withPath` (mkEndpointSegment authorizationServer "authorize")
`withQuery` queryParams,
oauth2TokenEndpoint = host `withPath` (mkEndpointSegment authorizationServer "token"),
oauth2RedirectUri = Nothing,
oauth2AppRoot = appRoot
}
Text
-> AuthPlugin m
oauth2OktaWithScopes scopes shouldPrompt host authorizationServer appRoot clientId clientSecret
= authOAuth2 pluginName oauth2 $ \manager token -> do
(User uid, userResponse) <- authGetProfile
pluginName
manager
token
(host `withPath` (mkEndpointSegment authorizationServer "userinfo"))
pure Creds
{ credsPlugin = pluginName
, credsIdent = uid
, credsExtra = setExtra token userResponse
}
where
queryParams = if shouldPrompt
then [scopeParam " " scopes, ("prompt", "login")]
else [scopeParam " " scopes]
oauth2 = OAuth2
{ oauth2ClientId = clientId
, oauth2ClientSecret = Just clientSecret
, oauth2AuthorizeEndpoint =
host
`withPath` (mkEndpointSegment authorizationServer "authorize")
`withQuery` queryParams
, oauth2TokenEndpoint =
host `withPath` (mkEndpointSegment authorizationServer "token")
, oauth2RedirectUri = Nothing
, oauth2AppRoot = appRoot
}
-- | Helper function for creating an endpoint path segment for the given authorization server
-- and endpoint.
mkEndpointSegment ::
mkEndpointSegment
::
-- | Authorization server ID
ByteString ->
ByteString
->
-- | Endpoint
ByteString ->
ByteString
ByteString
-> ByteString
mkEndpointSegment authorizationServer endpoint =
"/oauth2/" <> authorizationServer <> "/v1/" <> endpoint

View File

@ -14,7 +14,7 @@ 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