From 45debf40cd171f78a4de38f608a6cfd3be73b91a Mon Sep 17 00:00:00 2001 From: David Mosbach Date: Sun, 18 Feb 2024 22:58:02 +0000 Subject: [PATCH] added SSO test link route --- app/Main.hs | 3 +- app/SSO.hs | 42 +++++++ flake.nix | 4 +- oauth2-mock-server.cabal | 1 + package.yaml | 3 + src/Server.hs | 60 +++++----- users.yaml | 231 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 310 insertions(+), 34 deletions(-) create mode 100644 app/SSO.hs diff --git a/app/Main.hs b/app/Main.hs index 4fc8172..52a7adb 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -9,6 +9,7 @@ module Main (main) where import UniWorX import Server +import SSO (SSOTest, routes) import Control.Applicative ((<|>)) import Database.Persist (Entity(..)) import System.Environment (lookupEnv) @@ -20,7 +21,7 @@ main = do port <- determinePort putStrLn $ "Try: http://localhost:" ++ show port ++ "/auth?scope=ID%20Profile&client_id=42&response_type=code&redirect_uri=http:%2F%2Flocalhost:0000%2F" initDB - runMockServer @(Entity User) @(M.Map T.Text T.Text) port + runMockServerWithRoutes @(Entity User) @(M.Map T.Text T.Text) @SSOTest port routes where determinePort :: IO Int determinePort = do diff --git a/app/SSO.hs b/app/SSO.hs new file mode 100644 index 0000000..75d4631 --- /dev/null +++ b/app/SSO.hs @@ -0,0 +1,42 @@ +-- SPDX-FileCopyrightText: 2024 UniWorX Systems +-- SPDX-FileContributor: David Mosbach +-- +-- SPDX-License-Identifier: AGPL-3.0-or-later + +{-# Language DataKinds, TypeOperators, OverloadedStrings #-} + +module SSO (SSOTest, routes) where + +import Prelude hiding (head) + +import UniWorX +import Server + +import Data.String (IsString(..)) +import Data.Text (Text) + +import Database.Persist (Entity(..)) + +import Servant.API + +import Text.Blaze.Html5 +import qualified Text.Blaze.Html5.Attributes as A + + +type SSOTest = "test-sso" :> Get '[HTML] Html + +routes :: AuthServer (Entity User) SSOTest +routes = return ssoLink + where + ssoLink :: Html + ssoLink = docTypeHtml $ head' >> body' + where + t = "OIDC SSO Test" + head' = head $ do + meta ! A.charset "UTF-8" + meta ! A.name "viewport" ! A.content "width=device-width, initial-scale=1.0" + title t + body' = body $ do + h1 t + a ! A.href "https:..." $ "Go to FraDrive" + diff --git a/flake.nix b/flake.nix index 4e81d4e..58a405c 100644 --- a/flake.nix +++ b/flake.nix @@ -41,11 +41,12 @@ LD_LIBRARY_PATH=${libPath} mkdir -p $HOME/.stack stack build --verbose + rm -rf $HOME/.stack ''; installPhase = '' mkdir -p $out/bin mv .stack-work/install/${system}/*/*/bin/${name}-exe $out/bin/${name} - echo "moved" + rm -rf .stack-work ''; }; mkDB = builtins.readFile ./mkDB.sh; @@ -77,6 +78,7 @@ ${mkDB} zsh ${killDB} + exit ''; }; }; diff --git a/oauth2-mock-server.cabal b/oauth2-mock-server.cabal index 37004ba..6214f61 100644 --- a/oauth2-mock-server.cabal +++ b/oauth2-mock-server.cabal @@ -56,6 +56,7 @@ library executable oauth2-mock-server-exe main-is: Main.hs other-modules: + SSO UniWorX Paths_oauth2_mock_server autogen-modules: diff --git a/package.yaml b/package.yaml index 158730d..27500e6 100644 --- a/package.yaml +++ b/package.yaml @@ -76,6 +76,9 @@ executables: - conduit - mtl - yaml + - servant + - servant-server + - blaze-html tests: oauth2-mock-server-test: diff --git a/src/Server.hs b/src/Server.hs index 6942e9b..f995719 100644 --- a/src/Server.hs +++ b/src/Server.hs @@ -12,13 +12,18 @@ , RecordWildCards , AllowAmbiguousTypes , LambdaCase + , FlexibleContexts #-} module Server -{-( insecureOAuthMock' +( insecureOAuthMock , runMockServer --- , runMockServer' -)-} where +, runMockServerWithRoutes +, HTML +, Html +, AuthServer +, AuthHandler +) where import AuthCode import LoginForm @@ -101,14 +106,6 @@ type QAuth = Text type QParam = QueryParam' [Required, Strict] --- type Oauth2Params = QParam "scope" QScope --- :> QParam "client_id" QClient --- :> QParam "response_type" QResType --- :> QParam "redirect_uri" QRedirect --- :> QueryParam "state" QState - --- type ProtectedAuth user = BasicAuth "login" user :> "auth" :> Auth -- Prompts for username & password --- type QuickAuth = "qauth" :> Auth -- Prompts for username only type Auth = "auth" :> QParam "scope" QScope :> QParam "client_id" QClient @@ -339,35 +336,34 @@ routing = loginServer @user @userData --- insecureOAuthMock :: Application --- insecureOAuthMock = authAPI `serve` exampleAuthServer - -insecureOAuthMock' :: forall user userData . UserData user userData => AuthState user -> Application -insecureOAuthMock' s = serve authAPI $ hoistServer authAPI (toHandler @user @userData s) (routing @user @userData) +insecureOAuthMock :: forall user userData routes . + (UserData user userData, HasServer routes '[]) + => AuthState user + -> AuthServer user routes + -> Application +insecureOAuthMock s r = serve authAPI $ hoistServer authAPI (toHandler @user @userData s) (routing @user @userData :<|> r) where - authAPI = Proxy @(Routing user userData) + authAPI = Proxy @(Routing user userData :<|> routes) --- authenticate :: [User] -> BasicAuthCheck User --- authenticate users = BasicAuthCheck $ \authData -> do --- let --- (uEmail, uPass) = (,) <$> (decodeUtf8 . basicAuthUsername) <*> (decodeUtf8 . basicAuthPassword) $ authData --- case (find (\u -> email u == uEmail) users) of --- Nothing -> return NoSuchUser --- Just u -> return $ if uPass == password u then Authorized u else BadPassword - --- frontend :: BasicAuthData -> ClientM (Map.Map Text Text) --- frontend ba = client authAPI ba "[ID]" "42" "code" "" - -runMockServer :: forall user userData . UserData user userData => Int -> IO () -runMockServer port = do +runMockServerWithRoutes :: forall user userData routes . + (UserData user userData, HasServer routes '[]) + => Int + -> AuthServer user routes + -> IO () +runMockServerWithRoutes port server = do state <- mkState @user @userData - run port $ insecureOAuthMock' @user @userData state + run port $ insecureOAuthMock @user @userData @routes state server + +runMockServer :: forall user userData . UserData user userData + => Int + -> IO () +runMockServer port = runMockServerWithRoutes @user @userData @EmptyAPI port emptyServer -- runMockServer' :: Int -> IO () -- runMockServer' port = do -- mgr <- newManager defaultManagerSettings -- state <- mkState --- bracket (forkIO . run port $ insecureOAuthMock' testUsers state) killThread $ \_ -> +-- bracket (forkIO . run port $ insecureOAuthMock testUsers state) killThread $ \_ -> -- runClientM (frontend $ BasicAuthData "foo@bar.com" "0000") (mkClientEnv mgr (BaseUrl Http "localhost" port "")) -- >>= print diff --git a/users.yaml b/users.yaml index e69de29..17ea6d1 100644 --- a/users.yaml +++ b/users.yaml @@ -0,0 +1,231 @@ +# SPDX-FileCopyrightText: 2024 David Mosbach +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +special-users: + + - default: &default-user + userIdent: null + userAuthentication: AuthLDAP + userLastAuthentication: null + userTokensIssuedAfter: null + userMatrikelnummer: null + userEmail: "" + userDisplayEmail: null + userDisplayName: null + userSurname: "" + userFirstName: "" + userTitle: null + userMaxFavourites: userDefaultMaxFavourites + userMaxFavouriteTerms: userDefaultMaxFavouriteTerms + userTheme: ThemeDefault + userDateTimeFormat: userDefaultDateTimeFormat + userDateFormat: userDefaultDateFormat + userTimeFormat: userDefaultTimeFormat + userDownloadFiles: userDefaultDownloadFiles + userWarningDays: userDefaultWarningDays + userLanguages: null + userCreated: now + userNotificationSettings: def + userLastLdapSynchronisation: null + userLdapPrimaryKey: null + userCsvOptions: def + userSex: null + userBirthday: null + userShowSex: userDefaultShowSex + userTelephone: null + userMobile: null + userCompanyPersonalNumber: null + userCompanyDepartment: null + userPinPassword: null + userPostAddress: null + userPostLastUpdate: null + userPrefersPostal: true + userExamOfficeGetSynced: userDefaultExamOfficeGetSynced + userExamOfficeGetLabels: userDefaultExamOfficeGetLabels + + - gkleen: + <<: *default-user + userIdent: "G.Kleen@campus.lmu.de" + userLastAuthentication: now + userTokensIssuedAfter: now + userEmail: "G.Kleen@campus.lmu.de" + userDisplayEmail: "gregor.kleen@ifi.lmu.de" + userDisplayName: "Gregor Kleen" + userSurname: "Kleen" + userFirstName: "Gregor Julius Arthur" + userMaxFavourites: 6 + userMaxFavouriteTerms: 1 + userLanguages: ["en"] + # userCsvOptions = def { csvFormat = csvPreset # CsvPresetRFC } + userSex: SexMale + userCompanyPersonalNumber: "00000" + userPostAddress: "Büro 127 \nMathematisches Institut der Ludwig-Maximilians-Universität München \nTheresienstr. 39 \nD-80333 München" + + - fhamann: + <<: *default-user + userIdent: "felix.hamann@campus.lmu.de" + userEmail: "noEmailKnown" + userDisplayEmail: "felix.hamann@campus.lmu.de" + userDisplayName: "Felix Hamann" + userSurname: "Hamann" + userFirstName: "Felix" + # userCsvOptions = def { csvFormat = csvPreset # CsvPresetExcel } + userSex: SexMale + userPinPassword: "tomatenmarmelade" + userPostAddress: "Erdbeerweg 24 \n12345 Schlumpfhausen \nTraumland" + + - jost: + <<: *default-user + userIdent: "jost@tcs.ifi.lmu.de" + userAuthentication: pwSimple + userMatrikelnummer: "12345678" + userEmail: "S.Jost@Fraport.de" + userDisplayEmail: "jost@tcs.ifi.lmu.de" + userDisplayName: "Steffen Jost" + userSurname: "Jost" + userFirstName: "Steffen" + userTitle: "Dr." + userMaxFavourites: 14 + userMaxFavouriteTerms: 4 + userTheme: ThemeMossGreen + userSex: SexMale + # userBirthday = Just $ n_day $ 35 * (-365) + userTelephone: "+49 69 690-71706" + userMobile: "0173 69 99 646" + userCompanyPersonalNumber: "57138" + userCompanyDepartment: "AVN-AR2" + + - maxMuster: + <<: *default-user + userIdent: "max@campus.lmu.de" + userLastAuthentication: now + userMatrikelnummer: "1299" + userEmail: "max@campus.lmu.de" + userDisplayEmail: "max@max.com" + userDisplayName: "Max Musterstudent" + userSurname: "Musterstudent" + userFirstName: "Max" + userMaxFavourites: 7 + userTheme: ThemeAberdeenReds + userLanguages: ["de"] + userSex: SexMale + # userBirthday = Just $ n_day $ 27 * (-365) + userPrefersPostal: false + + - tinaTester: + <<: *default-user + userIdent: "tester@campus.lmu.de" + userAuthentication: null + userMatrikelnummer: "999" + userEmail: "tester@campus.lmu.de" + userDisplayEmail: "tina@tester.example" + userDisplayName: "Tina Tester" + userSurname: "vön Tërrör¿" + userFirstName: "Sabrina" + userTitle: "Magister" + userMaxFavourites: 5 + userTheme: ThemeAberdeenReds + userLanguages: ["sn"] + userSex: SexNotApplicable + # userBirthday = Just $ n_day 3 + userCompanyPersonalNumber: "12345" + userPrefersPostal: false + + - svaupel: + <<: *default-user + userIdent: "vaupel.sarah@campus.lmu.de" + userEmail: "vaupel.sarah@campus.lmu.de" + userDisplayEmail: "vaupel.sarah@campus.lmu.de" + userDisplayName: "Sarah Vaupel" + userSurname: "Vaupel" + userFirstName: "Sarah" + userMaxFavourites: 14 + userMaxFavouriteTerms: 4 + userTheme: ThemeMossGreen + userLanguages: null + userSex: SexFemale + userPrefersPostal: false + + - sbarth: + <<: *default-user + userIdent: "Stephan.Barth@campus.lmu.de" + userEmail: "Stephan.Barth@lmu.de" + userDisplayEmail: "stephan.barth@ifi.lmu.de" + userDisplayName: "Stephan Barth" + userSurname: "Barth" + userFirstName: "Stephan" + userTheme: ThemeMossGreen + userSex: SexMale + userPrefersPostal: false + userExamOfficeGetSynced: false + userExamOfficeGetLabels: true + + - _stranger1: + userIdent: "AVSID:996699" + userEmail: "E996699@fraport.de" + userDisplayEmail: "" + userDisplayName: "Stranger One" + userSurname: "One" + userFirstName: "Stranger" + userTheme: ThemeMossGreen + userSex: SexMale + userCompanyPersonalNumber: "E996699" + userCompanyDepartment: "AVN-Strange" + userPrefersPostal: false + userExamOfficeGetSynced: false + userExamOfficeGetLabels: true + + - _stranger2: + userIdent: "AVSID:669966" + userEmail: "E669966@fraport.de" + userDisplayEmail: "" + userDisplayName: "Stranger Two" + userSurname: "Stranger" + userFirstName: "Two" + userTheme: ThemeMossGreen + userSex: SexMale + userCompanyPersonalNumber: "669966" + userCompanyDepartment: "AVN-Strange" + userPrefersPostal: false + userExamOfficeGetSynced: false + userExamOfficeGetLabels: true + + - _stranger3: + userIdent: "AVSID:6969" + userEmail: "E6969@fraport.de" + userDisplayEmail: "" + userDisplayName: "Stranger 3 Three" + userSurname: "Three" + userFirstName: "Stranger" + userTheme: ThemeMossGreen + userSex: SexMale + userCompanyPersonalNumber: "E996699" + userCompanyDepartment: "AVN-Strange" + userPostAddress: "Kartoffelweg 12 \n666 Höllensumpf \nFreiland" + userPrefersPostal: false + userExamOfficeGetSynced: false + userExamOfficeGetLabels: true + + +random-users: + firstNames: [ "James", "John", "Robert", "Michael" + , "William", "David", "Mary", "Richard" + , "Joseph", "Thomas", "Charles", "Daniel" + , "Matthew", "Patricia", "Jennifer", "Linda" + , "Elizabeth", "Barbara", "Anthony", "Donald" + , "Mark", "Paul", "Steven", "Andrew" + , "Kenneth", "Joshua", "George", "Kevin" + , "Brian", "Edward", "Susan", "Ronald" + ] + surnames: [ "Smith", "Johnson", "Williams", "Brown" + , "Jones", "Miller", "Davis", "Garcia" + , "Rodriguez", "Wilson", "Martinez", "Anderson" + , "Taylor", "Thomas", "Hernandez", "Moore" + , "Martin", "Jackson", "Thompson", "White" + , "Lopez", "Lee", "Gonzalez", "Harris" + , "Clark", "Lewis", "Robinson", "Walker" + , "Perez", "Hall", "Young", "Allen" + ] + middlenames: [ null, "Jamesson" ] +