Skip to content

Commit 341f7a1

Browse files
authored
Spar Polysemy: In-memory interpreters (#1920)
* Now and AssIDStore interpreters * Add AReqIDStore.Mem * add boolTTL helper * Add BindCookieStore.Mem * Add SAMLUserStore.Mem * Make format * Add DefaultSsoCode.Mem * Add ScimExternalIdStore.Mem * Add ScimTokenStore.Mem * Add ScimUserTimesStore.Mem * make format * Changelog * Pull out VerdictFormatStore * Remove stale comment * Also emit internal state * Hi CI
1 parent 50ee901 commit 341f7a1

File tree

16 files changed

+265
-3
lines changed

16 files changed

+265
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add in-memory interpreters for most Spar effects

libs/wire-api/src/Wire/API/Cookie.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ instance ToParamSchema SetBindCookie where
3636
toParamSchema _ = toParamSchema (Proxy @String)
3737

3838
newtype BindCookie = BindCookie {fromBindCookie :: ST}
39+
deriving (Eq, Ord)
3940

4041
instance ToParamSchema BindCookie where
4142
toParamSchema _ = toParamSchema (Proxy @String)

libs/wire-api/src/Wire/API/User/Scim.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ userSchemas =
108108
--
109109
-- For SCIM authentication and token handling logic, see "Spar.Scim.Auth".
110110
newtype ScimToken = ScimToken {fromScimToken :: Text}
111-
deriving (Eq, Show, FromJSON, ToJSON, FromByteString, ToByteString)
111+
deriving (Eq, Ord, Show, FromJSON, ToJSON, FromByteString, ToByteString)
112112

113113
newtype ScimTokenHash = ScimTokenHash {fromScimTokenHash :: Text}
114114
deriving (Eq, Show)

services/spar/spar.cabal

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cabal-version: 1.12
44
--
55
-- see: https://github.com/sol/hpack
66
--
7-
-- hash: f787f064cceffbeeef6ac5c1ca7475e519a51afc3fdd173bf7a7a86a9016b238
7+
-- hash: 34138a2c7fa249191ae03bc1581a7c95c94b12080f104da084a9bc37ac54c9ad
88

99
name: spar
1010
version: 0.1
@@ -38,14 +38,18 @@ library
3838
Spar.Scim.User
3939
Spar.Sem.AReqIDStore
4040
Spar.Sem.AReqIDStore.Cassandra
41+
Spar.Sem.AReqIDStore.Mem
4142
Spar.Sem.AssIDStore
4243
Spar.Sem.AssIDStore.Cassandra
44+
Spar.Sem.AssIDStore.Mem
4345
Spar.Sem.BindCookieStore
4446
Spar.Sem.BindCookieStore.Cassandra
47+
Spar.Sem.BindCookieStore.Mem
4548
Spar.Sem.BrigAccess
4649
Spar.Sem.BrigAccess.Http
4750
Spar.Sem.DefaultSsoCode
4851
Spar.Sem.DefaultSsoCode.Cassandra
52+
Spar.Sem.DefaultSsoCode.Mem
4953
Spar.Sem.GalleyAccess
5054
Spar.Sem.GalleyAccess.Http
5155
Spar.Sem.IdP
@@ -57,6 +61,7 @@ library
5761
Spar.Sem.Logger
5862
Spar.Sem.Logger.TinyLog
5963
Spar.Sem.Now
64+
Spar.Sem.Now.Input
6065
Spar.Sem.Now.IO
6166
Spar.Sem.Random
6267
Spar.Sem.Random.IO
@@ -68,14 +73,19 @@ library
6873
Spar.Sem.SamlProtocolSettings.Servant
6974
Spar.Sem.SAMLUserStore
7075
Spar.Sem.SAMLUserStore.Cassandra
76+
Spar.Sem.SAMLUserStore.Mem
7177
Spar.Sem.ScimExternalIdStore
7278
Spar.Sem.ScimExternalIdStore.Cassandra
79+
Spar.Sem.ScimExternalIdStore.Mem
7380
Spar.Sem.ScimTokenStore
7481
Spar.Sem.ScimTokenStore.Cassandra
82+
Spar.Sem.ScimTokenStore.Mem
7583
Spar.Sem.ScimUserTimesStore
7684
Spar.Sem.ScimUserTimesStore.Cassandra
85+
Spar.Sem.ScimUserTimesStore.Mem
7786
Spar.Sem.VerdictFormatStore
7887
Spar.Sem.VerdictFormatStore.Cassandra
88+
Spar.Sem.VerdictFormatStore.Mem
7989
other-modules:
8090
Paths_spar
8191
hs-source-dirs:
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
2+
3+
module Spar.Sem.AReqIDStore.Mem where
4+
5+
import qualified Data.Map as M
6+
import Imports
7+
import Polysemy
8+
import Polysemy.State
9+
import qualified SAML2.WebSSO.Types as SAML
10+
import Spar.Sem.AReqIDStore
11+
import Spar.Sem.Now
12+
import Wire.API.User.Saml (AReqId)
13+
14+
aReqIDStoreToMem ::
15+
Member Now r =>
16+
Sem (AReqIDStore ': r) a ->
17+
Sem r (Map AReqId SAML.Time, a)
18+
aReqIDStoreToMem = (runState mempty .) $
19+
reinterpret $ \case
20+
Store areqid ti -> modify $ M.insert areqid ti
21+
UnStore areqid -> modify $ M.delete areqid
22+
IsAlive areqid ->
23+
gets (M.lookup areqid) >>= \case
24+
Just time -> do
25+
boolTTL False True time
26+
Nothing -> pure False
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
2+
3+
module Spar.Sem.AssIDStore.Mem where
4+
5+
import qualified Data.Map as M
6+
import Imports
7+
import Polysemy
8+
import Polysemy.State
9+
import qualified SAML2.WebSSO.Types as SAML
10+
import Spar.Sem.AssIDStore
11+
import Spar.Sem.Now
12+
import Wire.API.User.Saml (AssId)
13+
14+
assIdStoreToMem ::
15+
Member Now r =>
16+
Sem (AssIDStore ': r) a ->
17+
Sem r (Map AssId SAML.Time, a)
18+
assIdStoreToMem = (runState mempty .) $
19+
reinterpret $ \case
20+
Store assid ti -> modify $ M.insert assid ti
21+
UnStore assid -> modify $ M.delete assid
22+
IsAlive assid ->
23+
gets (M.lookup assid) >>= \case
24+
Just time -> boolTTL False True time
25+
Nothing -> pure False
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module Spar.Sem.BindCookieStore.Mem where
2+
3+
import Data.Id (UserId)
4+
import qualified Data.Map as M
5+
import Data.String.Conversions (cs)
6+
import Imports
7+
import Polysemy
8+
import Polysemy.State
9+
import SAML2.WebSSO
10+
import qualified SAML2.WebSSO.Cookie as SAML
11+
import qualified SAML2.WebSSO.Types as SAML
12+
import Spar.Sem.BindCookieStore
13+
import Spar.Sem.Now
14+
import qualified Spar.Sem.Now as Now
15+
import qualified Web.Cookie as Cky
16+
import Wire.API.Cookie
17+
18+
bindCookieStoreToMem :: Member Now r => Sem (BindCookieStore ': r) a -> Sem r (Map BindCookie (SAML.Time, UserId), a)
19+
bindCookieStoreToMem = (runState mempty .) $
20+
reinterpret $ \case
21+
Insert sbc uid ndt -> do
22+
let ckyval = BindCookie . cs . Cky.setCookieValue . SAML.fromSimpleSetCookie . getSimpleSetCookie $ sbc
23+
now <- Now.get
24+
modify $ M.insert ckyval (addTime ndt now, uid)
25+
Lookup bc -> do
26+
gets (M.lookup bc) >>= \case
27+
Just (time, uid) -> boolTTL Nothing (Just uid) time
28+
Nothing -> pure Nothing
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
2+
3+
module Spar.Sem.DefaultSsoCode.Mem where
4+
5+
import Imports
6+
import Polysemy
7+
import Polysemy.State (get, put, runState)
8+
import qualified SAML2.WebSSO as SAML
9+
import Spar.Sem.DefaultSsoCode (DefaultSsoCode (..))
10+
11+
defaultSsoCodeToMem :: Sem (DefaultSsoCode ': r) a -> Sem r (Maybe SAML.IdPId, a)
12+
defaultSsoCodeToMem = (runState Nothing .) $
13+
reinterpret $ \case
14+
Get -> get
15+
Store ipi -> put $ Just ipi
16+
Delete -> put Nothing

services/spar/src/Spar/Sem/Now.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
module Spar.Sem.Now where
22

3+
import Imports
34
import Polysemy
45
import qualified SAML2.WebSSO as SAML
56

67
data Now m a where
78
Get :: Now m SAML.Time
89

910
makeSem ''Now
11+
12+
-- | Check a time against 'Now', checking if it's still alive (hasn't occurred yet.)
13+
boolTTL ::
14+
Member Now r =>
15+
-- | The value to return if the TTL is expired
16+
a ->
17+
-- | The value to return if the TTL is alive
18+
a ->
19+
SAML.Time -> -- The time to check
20+
Sem r a
21+
boolTTL f t time = do
22+
now <- get
23+
pure $ bool f t $ now <= time
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Spar.Sem.Now.Input where
2+
3+
import Imports
4+
import Polysemy
5+
import Polysemy.Input
6+
import qualified SAML2.WebSSO as SAML
7+
import Spar.Sem.Now
8+
9+
nowToInput ::
10+
Member (Input SAML.Time) r =>
11+
Sem (Now ': r) a ->
12+
Sem r a
13+
nowToInput = interpret $ \case
14+
Get -> input

0 commit comments

Comments
 (0)