From f2b20f2dfbcdeb571d1882834d061cffe0ab96f8 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Wed, 2 Nov 2022 01:02:12 +0000 Subject: [PATCH 1/5] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 17833fcb..723d8ab2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ result-* .attr-cache tags TAGS +beam/task/backend/psql-test* From 6cc2fa85397e27fc5e865b1ec01a2de29297845f Mon Sep 17 00:00:00 2001 From: cidkidnix Date: Tue, 28 Mar 2023 07:56:17 -0500 Subject: [PATCH 2/5] Fix cabal definitions --- beam/db/rhyolite-beam-db.cabal | 1 - beam/orphans/rhyolite-beam-orphans.cabal | 1 - beam/task/backend/rhyolite-beam-task-worker-backend.cabal | 1 - beam/task/types/rhyolite-beam-task-worker-types.cabal | 1 - .../signed-data-clientsession/signed-data-clientsession.cabal | 1 - 5 files changed, 5 deletions(-) diff --git a/beam/db/rhyolite-beam-db.cabal b/beam/db/rhyolite-beam-db.cabal index 3ca7afd0..ee163805 100644 --- a/beam/db/rhyolite-beam-db.cabal +++ b/beam/db/rhyolite-beam-db.cabal @@ -10,7 +10,6 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems copyright: 2021 Obsidian Systems LLC category: Web -extra-source-files: README.md library exposed-modules: diff --git a/beam/orphans/rhyolite-beam-orphans.cabal b/beam/orphans/rhyolite-beam-orphans.cabal index e5a67756..dc5b5eb3 100644 --- a/beam/orphans/rhyolite-beam-orphans.cabal +++ b/beam/orphans/rhyolite-beam-orphans.cabal @@ -10,7 +10,6 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems copyright: 2021 Obsidian Systems LLC category: Web -extra-source-files: README.md library exposed-modules: diff --git a/beam/task/backend/rhyolite-beam-task-worker-backend.cabal b/beam/task/backend/rhyolite-beam-task-worker-backend.cabal index f4867a40..883f4004 100644 --- a/beam/task/backend/rhyolite-beam-task-worker-backend.cabal +++ b/beam/task/backend/rhyolite-beam-task-worker-backend.cabal @@ -10,7 +10,6 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems copyright: 2021 Obsidian Systems LLC category: Web -extra-source-files: README.md library exposed-modules: diff --git a/beam/task/types/rhyolite-beam-task-worker-types.cabal b/beam/task/types/rhyolite-beam-task-worker-types.cabal index 200acf0b..6f5a8745 100644 --- a/beam/task/types/rhyolite-beam-task-worker-types.cabal +++ b/beam/task/types/rhyolite-beam-task-worker-types.cabal @@ -10,7 +10,6 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems copyright: 2021 Obsidian Systems LLC category: Web -extra-source-files: README.md library exposed-modules: diff --git a/signed-data/signed-data-clientsession/signed-data-clientsession.cabal b/signed-data/signed-data-clientsession/signed-data-clientsession.cabal index 77ac4f22..8e38187f 100644 --- a/signed-data/signed-data-clientsession/signed-data-clientsession.cabal +++ b/signed-data/signed-data-clientsession/signed-data-clientsession.cabal @@ -13,7 +13,6 @@ author: Obsidian Systems LLC maintainer: maintainer@obsidian.systems copyright: 2021 Obsidian Systems LLC category: Data -extra-source-files: CHANGELOG.md library exposed-modules: Data.Signed.ClientSession From 2092eb3f78272d3b3afae9e487ac46f78f7f3e72 Mon Sep 17 00:00:00 2001 From: Cale Gibbard Date: Wed, 17 May 2023 22:05:18 -0400 Subject: [PATCH 3/5] Purify the function used to decrypt tokens in authentication because doing database queries inside it results in unacceptable performance. --- common/Rhyolite/Vessel/AuthMapV.hs | 17 ++++++++++------- common/Rhyolite/Vessel/AuthenticatedV.hs | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/common/Rhyolite/Vessel/AuthMapV.hs b/common/Rhyolite/Vessel/AuthMapV.hs index 2c0bc85a..9ef38a03 100644 --- a/common/Rhyolite/Vessel/AuthMapV.hs +++ b/common/Rhyolite/Vessel/AuthMapV.hs @@ -140,8 +140,10 @@ instance -- user is typically 'Id Account', iso to 'AuthToken Identity' handleAuthMapQuery :: (Monad m, Ord token, View v) - => (token -> m (Maybe user)) - -- ^ How to figure out the identity corresponding to a token + => (token -> Maybe user) + -- ^ How to figure out the identity corresponding to a token. Note: this is pure because it absolutely must be cheap, and we don't want people + -- attempting to put a database query inside it, which would result in terrible performance failures. Fast IO would be permissible, but generally + -- decrypting a token with a known CSK can be done with a pure function. -> (v Proxy -> m (v Identity)) -- ^ Handle the aggregate query for all identities -> AuthMapV token v Proxy @@ -150,7 +152,7 @@ handleAuthMapQuery handleAuthMapQuery readToken handler (AuthMapV vt) = do let unfilteredVt = getSubVessel vt unvalidatedTokens = MMap.keys unfilteredVt - validTokens <- Set.fromList <$> witherM (\t -> (t <$) <$> readToken t) unvalidatedTokens + validTokens = Set.fromList (filter (isJust . readToken) unvalidatedTokens) let filteredVt = MMap.intersectionWith const unfilteredVt (MMap.fromSet (\_ -> ()) validTokens) invalidTokens = MMap.fromSet (\_ -> failureErrorV ()) $ Set.difference (Set.fromList unvalidatedTokens) validTokens @@ -183,8 +185,9 @@ type instance ViewQueryResult (TaggedQuery w a) = (w, a) handlePersonalAuthMapQuery :: forall m token v user. (Monad m, Ord token, View v, Ord user) - => (token -> m (Maybe user)) - -- ^ How to figure out the identity corresponding to a token + => (token -> Maybe user) + -- ^ How to figure out the identity corresponding to a token. Note: this is pure because it absolutely must be cheap. See the corresponding comment on + -- 'handleAuthMapQuery'. -> (forall f g. ViewQueryResult f ~ g => (forall x. x -> f x -> g x) @@ -198,8 +201,8 @@ handlePersonalAuthMapQuery handlePersonalAuthMapQuery readToken handler vt = do let unauthorisedAuthMapSingleton token = Map.singleton token $ failureErrorV () - authoriseAction t v = do - lift (readToken t) >>= \case + authoriseAction t v = + case readToken t of Nothing -> do tell $ unauthorisedAuthMapSingleton t pure Nothing diff --git a/common/Rhyolite/Vessel/AuthenticatedV.hs b/common/Rhyolite/Vessel/AuthenticatedV.hs index a1979965..22ee5d6c 100644 --- a/common/Rhyolite/Vessel/AuthenticatedV.hs +++ b/common/Rhyolite/Vessel/AuthenticatedV.hs @@ -162,7 +162,7 @@ handleAuthenticatedQuery' public private personal (AuthenticatedV q) = fmap Auth -- handler bakes this assumption in. handleAuthenticatedQuery :: (Monad m, Ord token, View public, View private, View personal, Ord user) - => (token -> m (Maybe user)) + => (token -> Maybe user) -> (public Proxy -> m (public Identity)) -> (private Proxy -> m (private Identity)) -- ^ The result of private queries is only available to authenticated identities From 5e2696c8366fd52f4ba23999c155a044edae8709 Mon Sep 17 00:00:00 2001 From: Cale Gibbard Date: Wed, 17 May 2023 22:15:28 -0400 Subject: [PATCH 4/5] Add changelog. --- ChangeLog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index ca23d11e..edfbb096 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -2,6 +2,15 @@ This project's release branch is `master`. This log is written from the perspective of the release branch: when changes hit `master`, they are considered released, and the date should reflect that release. +## Unreleased +* Breaking: handleAuthMapQuery and handlePersonalAuthMapQuery now take pure functions for decrypting user + tokens. This is fine in practice because it should almost always be readSignedWithKey from signed-data, + partially applied to a CSK. We had a major performance issue when someone stuck a database query inside + the function, and it ran in a loop for every connected user on every database notification, so we want + to defend against that sort of thing happening. There may still be legitimate reasons to do other IO + inside such a thing (e.g. if a different encryption mechanism were used), but if that's needed, we'll + reconsider the API further. + ## 2023-01-26 * Breaking: Rhyolite.Frontend.Cookie now always Base64 encodes cookies * change taskWorker to not manage the hasRun flag. For the old behavior, use `taskWorker1` which adds back the at-most-once execution behavior. The old `_task_hasRun` field of Task is a separate argument. From 0813f3a9306245cf13d3c5c2e84d9f702fef3993 Mon Sep 17 00:00:00 2001 From: Cale Gibbard Date: Wed, 24 May 2023 11:04:47 -0400 Subject: [PATCH 5/5] Remove Witherable --- common/Rhyolite/Vessel/AuthMapV.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/common/Rhyolite/Vessel/AuthMapV.hs b/common/Rhyolite/Vessel/AuthMapV.hs index 9ef38a03..bd20d076 100644 --- a/common/Rhyolite/Vessel/AuthMapV.hs +++ b/common/Rhyolite/Vessel/AuthMapV.hs @@ -32,7 +32,6 @@ import Data.Vessel import Data.Vessel.SubVessel import Data.Vessel.Vessel import Data.Vessel.ViewMorphism -import Data.Witherable import GHC.Generics import Reflex.Query.Class