From 956464659eccdb519ad9a18ca05b908486904b27 Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Mon, 19 Feb 2024 00:52:15 +0000 Subject: [PATCH 1/8] feat(auth): link to sso test from dev login widget --- shell.nix | 3 ++- src/Foundation/Instances.hs | 8 ++++++++ templates/login.hamlet | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/shell.nix b/shell.nix index 8c3f8b97e..7b3fd32e9 100644 --- a/shell.nix +++ b/shell.nix @@ -9,7 +9,8 @@ let haskellPackages = pkgs.haskellPackages; - oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=d47908b4f7883b4b485abf1ee06645495ccdc7b3&ref=user-queries").packages.x86_64-linux; + oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=45debf40cd171f78a4de38f608a6cfd3be73b91a&ref=oidc").packages.x86_64-linux; + oauth2MockServer = oauth2Flake.default; mkOauth2DB = oauth2Flake.mkOauth2DB; diff --git a/src/Foundation/Instances.hs b/src/Foundation/Instances.hs index 20d10b2de..49b6b5de9 100644 --- a/src/Foundation/Instances.hs +++ b/src/Foundation/Instances.hs @@ -42,6 +42,8 @@ import Foundation.DB import Network.Wai.Parse (lbsBackEnd) +import System.Environment (lookupEnv) + import UnliftIO.Pool (withResource) import qualified Control.Monad.State.Class as State @@ -136,6 +138,12 @@ instance YesodAuth UniWorX where plugins <- getsYesod authPlugins $logDebugS "Auth" $ "Enabled plugins: " <> Text.intercalate ", " (map apName plugins) +#ifdef DEVELOPMENT + mPort <- liftIO $ lookupEnv "OAUTH2_SERVER_PORT" +#else + let mPort = Nothing +#endif + setTitleI MsgLoginTitle $(widgetFile "login") diff --git a/templates/login.hamlet b/templates/login.hamlet index bb3ee704e..e5dc2706f 100644 --- a/templates/login.hamlet +++ b/templates/login.hamlet @@ -1,6 +1,6 @@ $newline never -$# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,David Mosbach +$# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen , David Mosbach $# $# SPDX-License-Identifier: AGPL-3.0-or-later @@ -26,3 +26,8 @@ $forall AuthPlugin{apName, apLogin} <- plugins

_{MsgDummyLoginTitle} ^{apLogin toParent} +$maybe port <- mPort +
+

SSO Dev Test + Test login via single sign-on + From fbe0e37d281e19bcdbb926eb9a128c69186dd596 Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Tue, 5 Mar 2024 23:57:10 +0000 Subject: [PATCH 2/8] feat(auth): oidc based sso for auth protected routes --- config/settings.yml | 4 +++- src/Auth/OAuth2.hs | 22 ++++++++++++++-------- src/Foundation/Instances.hs | 21 ++++++++++++++------- src/Settings.hs | 5 ++++- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/config/settings.yml b/config/settings.yml index 602c9c0e2..28858440b 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -131,6 +131,8 @@ database: auto-db-migrate: '_env:AUTO_DB_MIGRATE:true' +single-sign-on: "_env:OIDC_SSO:true" + ldap: - host: "_env:LDAPHOST:" tls: "_env:LDAPTLS:" diff --git a/src/Auth/OAuth2.hs b/src/Auth/OAuth2.hs index fab04ca16..613a1ddd5 100644 --- a/src/Auth/OAuth2.hs +++ b/src/Auth/OAuth2.hs @@ -8,7 +8,7 @@ module Auth.OAuth2 ( AzureUserException(..) , azurePluginName , oauth2MockServer -, mockPluginName +, mockPluginName , queryOAuth2User , UserDataException ) where @@ -36,9 +36,9 @@ instance Exception AzureUserException azurePluginName :: Text azurePluginName = "azureadv2" ----------------------------------------- ----- OAuth2 development auth plugin ---- ----------------------------------------- +----------------------------------------------- +---- OAuth2 + OIDC development auth plugin ---- +----------------------------------------------- mockPluginName :: Text mockPluginName = "dev-oauth2-mock" @@ -53,7 +53,11 @@ oauth2MockServer port = let oa = OAuth2 { oauth2ClientId = "42" , oauth2ClientSecret = Just "shhh" - , oauth2AuthorizeEndpoint = (fromString $ mockServerURL <> "/auth") `withQuery` [scopeParam " " ["ID", "Profile"]] + , oauth2AuthorizeEndpoint = (fromString $ mockServerURL <> "/auth") + `withQuery` [ scopeParam " " ["openid", "profile", "email", "offline_access"] -- TODO read scopes from config + , ("response_type", "code id_token") + , ("nonce", "Foo") -- TODO generate meaningful value + ] , oauth2TokenEndpoint = fromString $ mockServerURL <> "/token" , oauth2RedirectUri = Nothing } @@ -94,7 +98,8 @@ queryOAuth2User userID = runExceptT $ do setSessionJson SessionOAuth2Token (Just $ accessToken newTokens, refreshToken newTokens) eResult <- lift $ getResponseBody <$> httpJSONEither @m @j (req { secure = secure - , requestHeaders = [("Authorization", encodeUtf8 . ("Bearer " <>) . atoken $ accessToken newTokens)] }) + , requestHeaders = [("Authorization", encodeUtf8 . ("Bearer " <>) . atoken $ accessToken newTokens)] + }) case eResult of Left x -> throwE $ UserDataJSONException x Right x -> return x @@ -130,8 +135,8 @@ refreshOAuth2Token (_, rToken) url secure body' <- if secure then do clientID <- liftIO $ fromJust <$> lookupEnv "CLIENT_ID" clientSecret <- liftIO $ fromJust <$> lookupEnv "CLIENT_SECRET" - return $ body ++ [("client_id", fromString clientID), ("client_secret", fromString clientSecret), ("scope", "openid profile")] - else return $ ("scope", "ID Profile") : body + return $ body ++ [("client_id", fromString clientID), ("client_secret", fromString clientSecret), ("scope", "openid profile offline_access")] -- TODO read from config + else return $ ("scope", "openid profile offline_access") : body -- TODO read from config $logErrorS "\27[31mAdmin Handler\27[0m" $ tshow (requestBody $ urlEncodedBody body' req{ secure = secure }) eResult <- lift $ getResponseBody <$> httpJSONEither @m @OAuth2Token (urlEncodedBody body' req{ secure = secure }) case eResult of @@ -142,3 +147,4 @@ refreshOAuth2Token (_, rToken) url secure instance Show RequestBody where show (RequestBodyLBS x) = show x show _ = error ":(" + diff --git a/src/Foundation/Instances.hs b/src/Foundation/Instances.hs index 49b6b5de9..ca9dc9ad3 100644 --- a/src/Foundation/Instances.hs +++ b/src/Foundation/Instances.hs @@ -11,11 +11,14 @@ module Foundation.Instances , unsafeHandler ) where +import qualified Prelude as P + import Import.NoFoundation import qualified Data.Text as Text import Data.List (inits) +import Yesod.Auth.OAuth2 import qualified Yesod.Core.Unsafe as Unsafe import qualified Yesod.Auth.Message as Auth @@ -23,6 +26,7 @@ import Utils.Form import Auth.LDAP import Auth.PWHash import Auth.Dummy +import Auth.OAuth2 import qualified Foundation.Yesod.Session as UniWorX import qualified Foundation.Yesod.Middleware as UniWorX @@ -133,17 +137,20 @@ instance YesodAuth UniWorX where redirectToReferer _ = True loginHandler = do + plugins <- getsYesod authPlugins + AppSettings{..} <- getsYesod appSettings' + + when appSingleSignOn $ do + let plugin = P.head $ P.filter ((`elem` [mockPluginName, azurePluginName]) . apName) plugins + pieces = case oauth2Url (apName plugin) of + PluginR _ p -> p + _ -> error "Unexpected OAuth2 AuthRoute" + void $ apDispatch plugin "GET" pieces + toParent <- getRouteToParent liftHandler . defaultLayout $ do - plugins <- getsYesod authPlugins $logDebugS "Auth" $ "Enabled plugins: " <> Text.intercalate ", " (map apName plugins) - -#ifdef DEVELOPMENT mPort <- liftIO $ lookupEnv "OAUTH2_SERVER_PORT" -#else - let mPort = Nothing -#endif - setTitleI MsgLoginTitle $(widgetFile "login") diff --git a/src/Settings.hs b/src/Settings.hs index e3fcc6105..5dadb7646 100644 --- a/src/Settings.hs +++ b/src/Settings.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost +-- SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -96,6 +96,8 @@ data AppSettings = AppSettings , appDatabaseConf :: PostgresConf -- ^ Configuration settings for accessing the database. , appAutoDbMigrate :: Bool + , appSingleSignOn :: Bool + -- ^ Enable OIDC single sign-on , appLdapConf :: Maybe (PointedList LdapConf) -- ^ Configuration settings for CSV export/import to LMS (= Learn Management System) , appLmsConf :: LmsConf @@ -627,6 +629,7 @@ instance FromJSON AppSettings where appWebpackEntrypoints <- o .: "webpack-manifest" appDatabaseConf <- o .: "database" appAutoDbMigrate <- o .: "auto-db-migrate" + appSingleSignOn <- o .: "single-sign-on" let nonEmptyHost LdapConf{..} = case ldapHost of Ldap.Tls host _ -> not $ null host Ldap.Plain host -> not $ null host From d88acf46345657da6d5b01aa76d9fa8106294ee0 Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Wed, 6 Mar 2024 04:26:47 +0000 Subject: [PATCH 3/8] chore(auth): updated mock server --- shell.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell.nix b/shell.nix index 7b3fd32e9..48d9cc57e 100644 --- a/shell.nix +++ b/shell.nix @@ -9,7 +9,7 @@ let haskellPackages = pkgs.haskellPackages; - oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=45debf40cd171f78a4de38f608a6cfd3be73b91a&ref=oidc").packages.x86_64-linux; + oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=83d99e55303f5b1cd6cde30b2936d61419268f8c&ref=oidc").packages.x86_64-linux; oauth2MockServer = oauth2Flake.default; From b947037ea29bb721f3c5cade28ba606ad3e9e26f Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Thu, 7 Mar 2024 03:31:17 +0000 Subject: [PATCH 4/8] feat(auth): implemented single sign out --- .../categories/authorization/de-de-formal.msg | 4 +++- .../categories/authorization/en-eu.msg | 4 +++- routes | 4 +++- src/Application.hs | 1 + src/Auth/OAuth2.hs | 23 ++++++++++++++++++- src/Foundation/Instances.hs | 5 ++++ src/Foundation/Navigation.hs | 3 ++- src/Handler/SingleSignOut.hs | 23 +++++++++++++++++++ 8 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/Handler/SingleSignOut.hs diff --git a/messages/uniworx/categories/authorization/de-de-formal.msg b/messages/uniworx/categories/authorization/de-de-formal.msg index f9a26de23..4c0773001 100644 --- a/messages/uniworx/categories/authorization/de-de-formal.msg +++ b/messages/uniworx/categories/authorization/de-de-formal.msg @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -139,3 +139,5 @@ FormHoneypotNamePlaceholder: Name FormHoneypotComment: Kommentar FormHoneypotCommentPlaceholder: Kommentar FormHoneypotFilled: Bitte füllen Sie keines der verstecken Felder aus + +SingleSignOut: Abmeldung bei Azure diff --git a/messages/uniworx/categories/authorization/en-eu.msg b/messages/uniworx/categories/authorization/en-eu.msg index b539efbf1..7dc17b924 100644 --- a/messages/uniworx/categories/authorization/en-eu.msg +++ b/messages/uniworx/categories/authorization/en-eu.msg @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -140,3 +140,5 @@ FormHoneypotNamePlaceholder !ident-ok: Name FormHoneypotComment: Comment FormHoneypotCommentPlaceholder: Comment FormHoneypotFilled: Please do not fill in any of the hidden fields + +SingleSignOut: Azure logout diff --git a/routes b/routes index 2376c33af..e42a707e5 100644 --- a/routes +++ b/routes @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022-2023 Sarah Vaupel , Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt +-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel , Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -46,6 +46,8 @@ /static StaticR EmbeddedStatic appStatic !free /auth AuthR Auth getAuth !free +/ssout SSOutR GET !free -- single sign-out (OIDC) + /metrics MetricsR GET !free -- verify if this can be free /err ErrorR GET !free diff --git a/src/Application.hs b/src/Application.hs index 08fef42ee..215f4631d 100644 --- a/src/Application.hs +++ b/src/Application.hs @@ -164,6 +164,7 @@ import Handler.PrintCenter import Handler.ApiDocs import Handler.Swagger import Handler.Firm +import Handler.SingleSignOut import ServantApi () -- YesodSubDispatch instances import Servant.API diff --git a/src/Auth/OAuth2.hs b/src/Auth/OAuth2.hs index 613a1ddd5..c85af461b 100644 --- a/src/Auth/OAuth2.hs +++ b/src/Auth/OAuth2.hs @@ -11,12 +11,13 @@ module Auth.OAuth2 , mockPluginName , queryOAuth2User , UserDataException +, singleSignOut ) where import Data.Maybe (fromJust) import Data.Text -import Import.NoFoundation hiding (unpack) +import Import.NoFoundation hiding (pack, unpack) import Network.HTTP.Simple (httpJSONEither, getResponseBody, JSONException) @@ -148,3 +149,23 @@ instance Show RequestBody where show (RequestBodyLBS x) = show x show _ = error ":(" + + ----------------------- +---- Single Sign-Out ---- + ----------------------- + +singleSignOut :: forall a m. (MonadHandler m) + => Maybe Text -- ^ redirect uri + -> m a +singleSignOut mRedirect = do +# ifdef DEVELOPMENT + port <- liftIO $ fromJust <$> lookupEnv "OAUTH2_SERVER_PORT" + let base = "http://localhost:" <> pack port <> "/logout" +# else + let base = "" -- TODO find out fraport oidc end_session_endpoint +# endif + endpoint = case mRedirect of + Just r -> base <> "?post_logout_redirect_uri=" <> r + Nothing -> base + redirect endpoint + diff --git a/src/Foundation/Instances.hs b/src/Foundation/Instances.hs index ca9dc9ad3..e4d81cf88 100644 --- a/src/Foundation/Instances.hs +++ b/src/Foundation/Instances.hs @@ -174,6 +174,11 @@ instance YesodAuth UniWorX where addMessage Success . toHtml $ mr Auth.NowLoggedIn + -- onLogout = do + -- AppSettings{..} <- getsYesod appSettings' + -- when appSingleSignOn $ singleSignOut @UniWorX Nothing + + onErrorHtml dest msg = do addMessage Error $ toHtml msg redirect dest diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index bf486ed22..c0a642a2e 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -73,6 +73,7 @@ breadcrumb :: ( BearerAuthSite UniWorX => Route UniWorX -> m Breadcrumb breadcrumb (AuthR _) = i18nCrumb MsgMenuLogin $ Just NewsR +breadcrumb SSOutR = i18nCrumb MsgSingleSignOut Nothing breadcrumb (StaticR _) = i18nCrumb MsgBreadcrumbStatic Nothing breadcrumb (WellKnownR _) = i18nCrumb MsgBreadcrumbWellKnown Nothing breadcrumb MetricsR = i18nCrumb MsgBreadcrumbMetrics Nothing @@ -546,7 +547,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , navIcon = IconMenuLogout , navLink = NavLink { navLabel = MsgMenuLogout - , navRoute = AuthR LogoutR + , navRoute = SSOutR -- AuthR LogoutR , navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId , navType = NavTypeLink { navModal = False } , navQuick' = mempty diff --git a/src/Handler/SingleSignOut.hs b/src/Handler/SingleSignOut.hs new file mode 100644 index 000000000..44ec813a2 --- /dev/null +++ b/src/Handler/SingleSignOut.hs @@ -0,0 +1,23 @@ +-- SPDX-FileCopyrightText: 2024 David Mosbach +-- +-- SPDX-License-Identifier: AGPL-3.0-or-later + +module Handler.SingleSignOut + ( getSSOutR + ) where + +import Import +import Auth.OAuth2 (singleSignOut) +import qualified Network.Wai as W + + +getSSOutR :: Handler Html +getSSOutR = do + app <- getYesod + let logoutR = intercalate "/" . fst . renderRoute $ AuthR LogoutR + root = case approot of + ApprootRequest f -> f app W.defaultRequest + _ -> error "approt implementation changed" + AppSettings{..} <- getsYesod appSettings' + if appSingleSignOn then singleSignOut (Just $ root <> "/" <> logoutR) else redirect (AuthR LogoutR) + From 1e5c4df163bb14f29b835435fb62ada26eb6dd1c Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Sun, 10 Mar 2024 19:43:54 +0000 Subject: [PATCH 5/8] chore(auth): fix single sign out redirect route --- .../categories/authorization/de-de-formal.msg | 1 + .../uniworx/categories/authorization/en-eu.msg | 1 + routes | 3 ++- src/Auth/OAuth2.hs | 1 + src/Foundation/Navigation.hs | 1 + src/Handler/SingleSignOut.hs | 14 +++++++++++--- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/messages/uniworx/categories/authorization/de-de-formal.msg b/messages/uniworx/categories/authorization/de-de-formal.msg index 4c0773001..667051a51 100644 --- a/messages/uniworx/categories/authorization/de-de-formal.msg +++ b/messages/uniworx/categories/authorization/de-de-formal.msg @@ -140,4 +140,5 @@ FormHoneypotComment: Kommentar FormHoneypotCommentPlaceholder: Kommentar FormHoneypotFilled: Bitte füllen Sie keines der verstecken Felder aus +Logout: Abmeldung SingleSignOut: Abmeldung bei Azure diff --git a/messages/uniworx/categories/authorization/en-eu.msg b/messages/uniworx/categories/authorization/en-eu.msg index 7dc17b924..f31413299 100644 --- a/messages/uniworx/categories/authorization/en-eu.msg +++ b/messages/uniworx/categories/authorization/en-eu.msg @@ -141,4 +141,5 @@ FormHoneypotComment: Comment FormHoneypotCommentPlaceholder: Comment FormHoneypotFilled: Please do not fill in any of the hidden fields +Logout: Logout SingleSignOut: Azure logout diff --git a/routes b/routes index e42a707e5..13f6914f9 100644 --- a/routes +++ b/routes @@ -46,7 +46,8 @@ /static StaticR EmbeddedStatic appStatic !free /auth AuthR Auth getAuth !free -/ssout SSOutR GET !free -- single sign-out (OIDC) +/logout SOutR GET !free +/logout/ssout SSOutR GET !free -- single sign-out (OIDC) /metrics MetricsR GET !free -- verify if this can be free diff --git a/src/Auth/OAuth2.hs b/src/Auth/OAuth2.hs index c85af461b..5ed9921e2 100644 --- a/src/Auth/OAuth2.hs +++ b/src/Auth/OAuth2.hs @@ -167,5 +167,6 @@ singleSignOut mRedirect = do endpoint = case mRedirect of Just r -> base <> "?post_logout_redirect_uri=" <> r Nothing -> base + $logErrorS "\n\27[31mSSO\27[0m" endpoint redirect endpoint diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index c0a642a2e..b37d51416 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -73,6 +73,7 @@ breadcrumb :: ( BearerAuthSite UniWorX => Route UniWorX -> m Breadcrumb breadcrumb (AuthR _) = i18nCrumb MsgMenuLogin $ Just NewsR +breadcrumb SOutR = i18nCrumb MsgLogout Nothing breadcrumb SSOutR = i18nCrumb MsgSingleSignOut Nothing breadcrumb (StaticR _) = i18nCrumb MsgBreadcrumbStatic Nothing breadcrumb (WellKnownR _) = i18nCrumb MsgBreadcrumbWellKnown Nothing diff --git a/src/Handler/SingleSignOut.hs b/src/Handler/SingleSignOut.hs index 44ec813a2..8b89a19d0 100644 --- a/src/Handler/SingleSignOut.hs +++ b/src/Handler/SingleSignOut.hs @@ -3,7 +3,8 @@ -- SPDX-License-Identifier: AGPL-3.0-or-later module Handler.SingleSignOut - ( getSSOutR + ( getSOutR + , getSSOutR ) where import Import @@ -11,13 +12,20 @@ import Auth.OAuth2 (singleSignOut) import qualified Network.Wai as W +getSOutR :: Handler Html +getSOutR = do + $logErrorS "\27[31mSOut\27[0m" "Redirect to LogoutR" + redirect $ AuthR LogoutR + getSSOutR :: Handler Html getSSOutR = do app <- getYesod - let logoutR = intercalate "/" . fst . renderRoute $ AuthR LogoutR + let redir = intercalate "/" . fst . renderRoute $ SOutR root = case approot of ApprootRequest f -> f app W.defaultRequest _ -> error "approt implementation changed" + url = decodeUtf8 . urlEncode True . encodeUtf8 $ root <> "/" <> redir AppSettings{..} <- getsYesod appSettings' - if appSingleSignOn then singleSignOut (Just $ root <> "/" <> logoutR) else redirect (AuthR LogoutR) + $logErrorS "\27[31mSSOut\27[0m" "Redirect to auth server" + if appSingleSignOn then singleSignOut (Just url) else redirect (AuthR LogoutR) From 4c109538eeefa1125bb81539be5d69756b2379e6 Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Sun, 10 Mar 2024 22:15:20 +0000 Subject: [PATCH 6/8] chore(auth): new 'Account' section --- .../utils/navigation/menu/de-de-formal.msg | 3 +- .../uniworx/utils/navigation/menu/en-eu.msg | 3 +- shell.nix | 2 +- src/Foundation/Navigation.hs | 65 +++++++++---------- src/Utils/Icon.hs | 4 +- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/messages/uniworx/utils/navigation/menu/de-de-formal.msg b/messages/uniworx/utils/navigation/menu/de-de-formal.msg index 78e095b6d..77e7baa57 100644 --- a/messages/uniworx/utils/navigation/menu/de-de-formal.msg +++ b/messages/uniworx/utils/navigation/menu/de-de-formal.msg @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Winnie Ros +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Steffen Jost ,Winnie Ros ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -24,6 +24,7 @@ MenuPayments: Zahlungsbedingungen MenuInstance: Instanz-Identifikation MenuHealth: Instanz-Zustand MenuHelp: Hilfe +MenuAccount: Konto MenuProfile: Anpassen MenuLogin !ident-ok: Login MenuLogout !ident-ok: Logout diff --git a/messages/uniworx/utils/navigation/menu/en-eu.msg b/messages/uniworx/utils/navigation/menu/en-eu.msg index bb085c38e..f4d48aa93 100644 --- a/messages/uniworx/utils/navigation/menu/en-eu.msg +++ b/messages/uniworx/utils/navigation/menu/en-eu.msg @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros +# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen ,Sarah Vaupel ,Steffen Jost ,Winnie Ros ,David Mosbach # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -24,6 +24,7 @@ MenuPayments: Payment Terms MenuInstance: Instance identification MenuHealth: Instance health MenuHelp: Support +MenuAccount: Account MenuProfile: Settings MenuLogin: Login MenuLogout: Logout diff --git a/shell.nix b/shell.nix index 48d9cc57e..a5ca0056c 100644 --- a/shell.nix +++ b/shell.nix @@ -9,7 +9,7 @@ let haskellPackages = pkgs.haskellPackages; - oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=83d99e55303f5b1cd6cde30b2936d61419268f8c&ref=oidc").packages.x86_64-linux; + oauth2Flake = (builtins.getFlake "git+https://gitlab.uniworx.de/mosbach/oauth2-mock-server/?rev=7b995e6cffa963a24eb5d0373b2d29089533284f&ref=main").packages.x86_64-linux; oauth2MockServer = oauth2Flake.default; diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index b37d51416..7a38e0459 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -543,42 +543,37 @@ defaultLinks :: ( MonadHandler m , BearerAuthSite UniWorX ) => m [Nav] defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the header. - [ return NavHeader + [ return NavHeaderContainer { navHeaderRole = NavHeaderSecondary - , navIcon = IconMenuLogout - , navLink = NavLink - { navLabel = MsgMenuLogout - , navRoute = SSOutR -- AuthR LogoutR - , navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId - , navType = NavTypeLink { navModal = False } - , navQuick' = mempty - , navForceActive = False - } - } - , return NavHeader - { navHeaderRole = NavHeaderSecondary - , navIcon = IconMenuLogin - , navLink = NavLink - { navLabel = MsgMenuLogin - , navRoute = AuthR LoginR - , navAccess' = NavAccessHandler $ is _Nothing <$> maybeAuthId - , navType = NavTypeLink { navModal = True } - , navQuick' = mempty - , navForceActive = False - } - } - , return NavHeader - { navHeaderRole = NavHeaderSecondary - , navIcon = IconMenuProfile - , navLink = NavLink - { navLabel = MsgMenuProfile - , navRoute = ProfileR - , navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId - , navType = NavTypeLink { navModal = False } - , navQuick' = mempty - , navForceActive = False - } - } + , navLabel = SomeMessage MsgMenuAccount + , navIcon = IconMenuAccount + , navChildren = + [ NavLink + { navLabel = MsgMenuLogout + , navRoute = SSOutR -- AuthR LogoutR + , navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId + , navType = NavTypeLink { navModal = False } + , navQuick' = mempty + , navForceActive = False + } + , NavLink + { navLabel = MsgMenuLogin + , navRoute = AuthR LoginR + , navAccess' = NavAccessHandler $ is _Nothing <$> maybeAuthId + , navType = NavTypeLink { navModal = True } + , navQuick' = mempty + , navForceActive = False + } + , NavLink + { navLabel = MsgMenuProfile + , navRoute = ProfileR + , navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId + , navType = NavTypeLink { navModal = False } + , navQuick' = mempty + , navForceActive = False + } + ] + } , do mCurrentRoute <- getCurrentRoute diff --git a/src/Utils/Icon.hs b/src/Utils/Icon.hs index 07804c015..1f72ea042 100644 --- a/src/Utils/Icon.hs +++ b/src/Utils/Icon.hs @@ -1,4 +1,4 @@ --- SPDX-FileCopyrightText: 2022-23 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt ,Steffen Jost +-- SPDX-FileCopyrightText: 2022-24 Gregor Kleen ,Sarah Vaupel ,Sarah Vaupel ,Steffen Jost ,Wolfgang Witt ,Steffen Jost ,David Mosbach -- -- SPDX-License-Identifier: AGPL-3.0-or-later @@ -81,6 +81,7 @@ data Icon | IconNavContainerClose | IconPageActionChildrenClose | IconMenuNews | IconMenuHelp + | IconMenuAccount | IconMenuProfile | IconMenuLogin | IconMenuLogout | IconBreadcrumbsHome @@ -173,6 +174,7 @@ iconText = \case IconPageActionChildrenClose -> "chevron-up" IconMenuNews -> "megaphone" IconMenuHelp -> "question" + IconMenuAccount -> "user" IconMenuProfile -> "cogs" IconMenuLogin -> "sign-in-alt" IconMenuLogout -> "sign-out-alt" From 98562727341fd860f5434e8b6481fbf1e5b948c6 Mon Sep 17 00:00:00 2001 From: Sarah Vaupel Date: Mon, 11 Mar 2024 14:23:35 +0100 Subject: [PATCH 7/8] chore(login): do not login via modal --- src/Foundation/Navigation.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index 7a38e0459..a52cdbfb6 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -560,7 +560,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the { navLabel = MsgMenuLogin , navRoute = AuthR LoginR , navAccess' = NavAccessHandler $ is _Nothing <$> maybeAuthId - , navType = NavTypeLink { navModal = True } + , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False } From 05acba8cbeaa256494bfcd3899f3fb56335e69a2 Mon Sep 17 00:00:00 2001 From: Sarah Vaupel Date: Mon, 11 Mar 2024 14:30:44 +0100 Subject: [PATCH 8/8] chore(foundation): ditch redirectToReferrer in favour of SSOut --- src/Foundation/Instances.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Foundation/Instances.hs b/src/Foundation/Instances.hs index e4d81cf88..8321894f8 100644 --- a/src/Foundation/Instances.hs +++ b/src/Foundation/Instances.hs @@ -134,7 +134,7 @@ instance YesodAuth UniWorX where -- Where to send a user after logout logoutDest _ = NewsR -- Override the above two destinations when a Referer: header is present - redirectToReferer _ = True + redirectToReferer _ = False loginHandler = do plugins <- getsYesod authPlugins