summaryrefslogtreecommitdiff
path: root/overlays/spm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'overlays/spm/lib')
-rw-r--r--overlays/spm/lib/Crypto/JWT/Instances.hs22
-rw-r--r--overlays/spm/lib/Data/CaseInsensitive/Instances.hs22
-rw-r--r--overlays/spm/lib/Data/UUID/Instances.hs18
-rw-r--r--overlays/spm/lib/Spm.hs5
-rw-r--r--overlays/spm/lib/Spm/Api.hs91
5 files changed, 158 insertions, 0 deletions
diff --git a/overlays/spm/lib/Crypto/JWT/Instances.hs b/overlays/spm/lib/Crypto/JWT/Instances.hs
new file mode 100644
index 00000000..fa3c83b0
--- /dev/null
+++ b/overlays/spm/lib/Crypto/JWT/Instances.hs
@@ -0,0 +1,22 @@
1{-# OPTIONS_GHC -fno-warn-orphans #-}
2
3module Crypto.JWT.Instances () where
4
5import Prelude
6import Control.Arrow
7
8import Crypto.JWT
9import Servant.API.ContentTypes
10
11
12instance MimeRender PlainText SignedJWT where
13 mimeRender _ = encodeCompact
14
15instance MimeRender OctetStream SignedJWT where
16 mimeRender _ = encodeCompact
17
18instance MimeUnrender PlainText SignedJWT where
19 mimeUnrender _ = left (show @Error) . decodeCompact
20
21instance MimeUnrender OctetStream SignedJWT where
22 mimeUnrender _ = left (show @Error) . decodeCompact
diff --git a/overlays/spm/lib/Data/CaseInsensitive/Instances.hs b/overlays/spm/lib/Data/CaseInsensitive/Instances.hs
new file mode 100644
index 00000000..1476b9d9
--- /dev/null
+++ b/overlays/spm/lib/Data/CaseInsensitive/Instances.hs
@@ -0,0 +1,22 @@
1{-# OPTIONS_GHC -fno-warn-orphans #-}
2
3module Data.CaseInsensitive.Instances () where
4
5import Prelude
6
7import Data.CaseInsensitive (CI)
8import qualified Data.CaseInsensitive as CI
9
10import Servant.API.ContentTypes
11
12import Data.Aeson
13
14
15instance MimeRender PlainText a => MimeRender PlainText (CI a) where
16 mimeRender p = mimeRender p . CI.original
17
18instance ToJSON a => ToJSON (CI a) where
19 toJSON = toJSON . CI.original
20
21instance (FromJSON a, CI.FoldCase a) => FromJSON (CI a) where
22 parseJSON = fmap CI.mk . parseJSON
diff --git a/overlays/spm/lib/Data/UUID/Instances.hs b/overlays/spm/lib/Data/UUID/Instances.hs
new file mode 100644
index 00000000..335937d8
--- /dev/null
+++ b/overlays/spm/lib/Data/UUID/Instances.hs
@@ -0,0 +1,18 @@
1{-# OPTIONS_GHC -fno-warn-orphans #-}
2
3module Data.UUID.Instances () where
4
5import Prelude
6import Data.UUID (UUID)
7import qualified Data.UUID as UUID
8import Servant.API.ContentTypes
9
10
11instance MimeRender PlainText UUID where
12 mimeRender p = mimeRender p . UUID.toText
13
14instance MimeRender JSON UUID where
15 mimeRender p = mimeRender p . UUID.toText
16
17instance MimeRender OctetStream UUID where
18 mimeRender p = mimeRender p . UUID.toByteString
diff --git a/overlays/spm/lib/Spm.hs b/overlays/spm/lib/Spm.hs
new file mode 100644
index 00000000..c7f7dfe5
--- /dev/null
+++ b/overlays/spm/lib/Spm.hs
@@ -0,0 +1,5 @@
1module Spm
2 ( module Spm.Api
3 ) where
4
5import Spm.Api
diff --git a/overlays/spm/lib/Spm/Api.hs b/overlays/spm/lib/Spm/Api.hs
new file mode 100644
index 00000000..14acfac4
--- /dev/null
+++ b/overlays/spm/lib/Spm/Api.hs
@@ -0,0 +1,91 @@
1{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
2
3module Spm.Api
4 ( SpmStyle(..), _SpmWords, _SpmConsonants
5 , SpmMailbox
6 , SpmApi, spmApi
7 ) where
8
9import Prelude
10
11import Servant.API
12
13import Data.Proxy (Proxy(..))
14
15import Data.Text (Text)
16
17import GHC.Generics (Generic)
18import Type.Reflection (Typeable)
19
20import Control.Lens.TH
21
22import Data.CaseInsensitive (CI)
23import qualified Data.CaseInsensitive as CI
24import Data.CaseInsensitive.Instances ()
25
26import Crypto.JOSE.JWK (JWKSet)
27import Crypto.JWT (SignedJWT)
28import Crypto.JWT.Instances ()
29
30import Data.UUID (UUID)
31import Data.UUID.Instances ()
32
33-- import Data.Aeson (ToJSON, FromJSON)
34
35
36data SpmStyle = SpmWords | SpmConsonants
37 deriving (Eq, Ord, Read, Show, Bounded, Enum)
38makePrisms ''SpmStyle
39
40instance ToHttpApiData SpmStyle where
41 toUrlPiece = \case
42 SpmWords -> "words"
43 SpmConsonants -> "consonants"
44instance FromHttpApiData SpmStyle where
45 parseUrlPiece t@(CI.mk -> t')
46 | t' == "words" = Right SpmWords
47 | t' == "consonants" = Right SpmConsonants
48 | otherwise = Left $ "Expected one of ‘words’ or ‘consonants’ but got ‘" <> t <> "’"
49
50
51newtype SpmMailbox = SpmMailbox { unSpmMailbox :: CI Text }
52 deriving stock (Eq, Ord, Read, Show, Generic, Typeable)
53 deriving newtype (MimeRender JSON, MimeRender PlainText)
54makeWrapped ''SpmMailbox
55-- newtype SpmLocal = SpmLocal
56-- { unSpmLocal :: CI Text
57-- } deriving stock (Eq, Ord, Read, Show, Generic, Typeable)
58-- deriving newtype (ToJSON, FromJSON)
59-- makeWrapped ''SpmLocal
60-- newtype SpmExtension = SpmExtension
61-- { unSpmExtension :: CI Text
62-- } deriving stock (Eq, Ord, Read, Show, Generic, Typeable)
63-- deriving newtype (ToJSON, FromJSON)
64-- makeWrapped ''SpmExtension
65
66-- newtype SpmMappingListing = SpmMappingListing { unSpmMappingListing :: Set SpmMapping }
67-- deriving stock (Eq, Ord, Read, Show, Generic, Typeable)
68-- instance ToJSON SpmMappingList where
69-- toJSON SpmMappingListing{..} = object [ "mappings" .= unSpmMappingListing ]
70
71-- data SpmMapping = SpmMapping
72-- { spmMappingLocal :: Maybe SpmLocal
73-- , spmMappingExtension :: Maybe SpmExtension
74-- } deriving stock (Eq, Ord, Read, Show, Generic, Typeable)
75-- instance ToJSON SpmMapping where
76-- toJSON SpmMapping{..} = object
77-- [ "local" .= spmMappingLocal
78-- , "extension" .= spmMappingExtension
79-- ]
80
81type SpmApi = "whoami" :> Get '[PlainText, JSON] SpmMailbox
82 :<|> "jwks.json" :> Get '[JSON] JWKSet
83 :<|> "instance-id" :> Get '[PlainText, JSON, OctetStream] UUID
84 :<|> "spm" :> "generate" :> QueryParam "style" SpmStyle :> Get '[PlainText, JSON, OctetStream] SignedJWT
85 :<|> "spm" :> "claim" :> ReqBody '[PlainText, JSON, OctetStream] SignedJWT :> PostNoContent
86 -- :<|> "mappings" :> Get '[PlainText, JSON] SpmMappingListing
87 -- :<|> "mappings" :> Capture SpmMapping :> GetNoContent
88 -- :<|> "mappings" :> Capture SpmMapping :> DeleteNoContent
89
90spmApi :: Proxy SpmApi
91spmApi = Proxy