Compare commits
3 Commits
f5f6c9ced9
...
dc32120ca8
Author | SHA1 | Date | |
---|---|---|---|
dc32120ca8 | |||
a580138e0d | |||
786927ccbd |
@ -18,20 +18,20 @@ cabal-version: >=1.10
|
||||
executable backend
|
||||
main-is: Main.hs
|
||||
other-modules: Devel.Main
|
||||
, API
|
||||
, API.Books
|
||||
, API.Catalogue
|
||||
, API.Channels
|
||||
, API.Users
|
||||
, Database
|
||||
, Database.Book
|
||||
, Database.Channel
|
||||
, Database.Tag
|
||||
, Database.Schema
|
||||
, Database.Tag
|
||||
, Database.User
|
||||
, Datastore
|
||||
, Servant.XML
|
||||
, Server
|
||||
, Server.API
|
||||
, Server.API.Books
|
||||
, Server.API.Catalogue
|
||||
, Server.API.Channels
|
||||
, Server.API.Users
|
||||
, Server.Auth
|
||||
, Types
|
||||
, View
|
||||
|
@ -18,9 +18,6 @@ newtype PlainPassword = PlainPassword Text deriving (Show, ToJSON, FromJSON, ToH
|
||||
newtype HashedPassword = HashedPassword {unHashed :: ByteString}
|
||||
data NoPassword = NoPassword
|
||||
|
||||
newtype Email = Email { unEmail :: Text } deriving (Show, ToJSON, FromJSON, ToHttpApiData, FromHttpApiData)
|
||||
|
||||
newtype Username = Username { unUsername :: Text } deriving (Show, ToJSON, FromJSON, ToHttpApiData, FromHttpApiData)
|
||||
|
||||
instance SqlType HashedPassword where
|
||||
mkLit = LCustom . LBlob . unHashed
|
||||
|
@ -12,7 +12,7 @@
|
||||
{-# Language TypeApplications #-}
|
||||
module Server where
|
||||
|
||||
import qualified API as API
|
||||
import qualified Server.API as API
|
||||
import Server.Auth (authCheck)
|
||||
import Servant
|
||||
import Types
|
||||
|
@ -9,7 +9,7 @@
|
||||
{-# Language RecordWildCards #-}
|
||||
{-# Language DeriveGeneric #-}
|
||||
{-# Language FlexibleInstances #-}
|
||||
module API (API, handler) where
|
||||
module Server.API (API, handler) where
|
||||
|
||||
|
||||
import Servant
|
||||
@ -18,10 +18,10 @@ import Types
|
||||
|
||||
import View
|
||||
|
||||
import qualified API.Users as Users
|
||||
import qualified API.Channels as Channels
|
||||
import qualified API.Books as Books
|
||||
import qualified API.Catalogue as Catalogue
|
||||
import qualified Server.API.Users as Users
|
||||
import qualified Server.API.Channels as Channels
|
||||
import qualified Server.API.Books as Books
|
||||
import qualified Server.API.Catalogue as Catalogue
|
||||
|
||||
data Index = Index
|
||||
|
@ -13,7 +13,7 @@
|
||||
{-# Language TypeApplications #-}
|
||||
{-# Language DataKinds #-}
|
||||
{-# Language NamedFieldPuns #-}
|
||||
module API.Books where
|
||||
module Server.API.Books where
|
||||
|
||||
import Servant hiding (contentType)
|
||||
import Types
|
@ -14,7 +14,7 @@
|
||||
{-# Language TemplateHaskell #-}
|
||||
{-# Language MultiParamTypeClasses #-}
|
||||
{-# Language ScopedTypeVariables #-}
|
||||
module API.Catalogue (VersionedAPI, handler) where
|
||||
module Server.API.Catalogue (VersionedAPI, handler) where
|
||||
|
||||
import Types
|
||||
import Servant hiding (contentType)
|
||||
@ -26,7 +26,7 @@ import Servant.XML
|
||||
import qualified Database.Channel as Channel
|
||||
import Database.Book (Book(..))
|
||||
import Database
|
||||
import qualified API.Books
|
||||
import qualified Server.API.Books as API.Books
|
||||
|
||||
-- This is my first try on going to versioned apis, things might change
|
||||
-- I think my rule of thumb is that you can add new things as you want, but
|
@ -13,7 +13,7 @@
|
||||
{-# Language DataKinds #-}
|
||||
{-# Language DuplicateRecordFields #-}
|
||||
{-# Language NamedFieldPuns #-}
|
||||
module API.Channels (API, handler, JsonChannel(..)) where
|
||||
module Server.API.Channels (API, handler, JsonChannel(..)) where
|
||||
|
||||
import Servant
|
||||
import Types
|
@ -5,7 +5,7 @@
|
||||
{-# Language TypeOperators #-}
|
||||
{-# Language DuplicateRecordFields #-}
|
||||
{-# Language TypeApplications #-}
|
||||
module API.Users where
|
||||
module Server.API.Users where
|
||||
|
||||
import Servant
|
||||
import ClassyPrelude
|
@ -24,21 +24,8 @@ import Control.Lens (view)
|
||||
import Data.Generics.Product
|
||||
import Servant (err401)
|
||||
import Control.Monad.Logger
|
||||
import Auth (SafeUser(..))
|
||||
|
||||
-- generic-lens can convert similar types to this
|
||||
-- I'm trying out servant-auth-server which uses a jwt style login. IIRC anyone
|
||||
-- can open the jwt token and view what's inside, you just can't modify it.
|
||||
--
|
||||
-- Is it a problem that a human readable username and email are visible?
|
||||
data SafeUser = SafeUser { email :: Email
|
||||
, username :: Username
|
||||
, role :: Role }
|
||||
deriving (Show, Generic)
|
||||
|
||||
instance ToJSON SafeUser where
|
||||
instance FromJSON SafeUser where
|
||||
instance ToJWT SafeUser where
|
||||
instance FromJWT SafeUser where
|
||||
|
||||
type instance BasicAuthCfg = BasicAuthData -> IO (AuthResult SafeUser)
|
||||
|
||||
|
@ -15,14 +15,27 @@ cabal-version: >=1.10
|
||||
library
|
||||
exposed-modules: Configuration
|
||||
, Data.Versioned
|
||||
, API
|
||||
, API.Books
|
||||
, API.Catalogue
|
||||
, API.Channels
|
||||
, API.Users
|
||||
, Auth
|
||||
-- other-extensions:
|
||||
build-depends: base >=4.10 && <4.11
|
||||
, aeson
|
||||
, classy-prelude
|
||||
, dhall
|
||||
, foreign-store
|
||||
, generic-lens
|
||||
, lens
|
||||
, mtl
|
||||
, servant
|
||||
, servant-auth
|
||||
, servant-auth-server
|
||||
, servant-docs
|
||||
, servant-lucid
|
||||
, servant-multipart
|
||||
, text
|
||||
, transformers
|
||||
hs-source-dirs: src
|
||||
@ -30,4 +43,6 @@ library
|
||||
, NoImplicitPrelude
|
||||
, OverloadedStrings
|
||||
, RecordWildCards
|
||||
, TypeOperators
|
||||
, DataKinds
|
||||
default-language: Haskell2010
|
||||
|
1
common/src/API.hs
Normal file
1
common/src/API.hs
Normal file
@ -0,0 +1 @@
|
||||
module API where
|
1
common/src/API/Books.hs
Normal file
1
common/src/API/Books.hs
Normal file
@ -0,0 +1 @@
|
||||
module API.Books where
|
1
common/src/API/Catalogue.hs
Normal file
1
common/src/API/Catalogue.hs
Normal file
@ -0,0 +1 @@
|
||||
module API.Catalogue where
|
27
common/src/API/Channels.hs
Normal file
27
common/src/API/Channels.hs
Normal file
@ -0,0 +1,27 @@
|
||||
{-# Language DuplicateRecordFields #-}
|
||||
module API.Channels (API) where
|
||||
|
||||
import Auth
|
||||
import ClassyPrelude
|
||||
import Data.Aeson
|
||||
import Servant.API
|
||||
import Servant.Auth as SA
|
||||
|
||||
data JsonChannel = JsonChannel { channel :: Text
|
||||
, visibility :: Visibility }
|
||||
deriving (Show, Generic)
|
||||
data UpdateChannel = UpdateChannel { identifier :: ChannelID
|
||||
, channel :: Text
|
||||
, visibility :: Visibility }
|
||||
deriving (Show, Generic)
|
||||
|
||||
instance ToJSON JsonChannel
|
||||
instance FromJSON JsonChannel
|
||||
instance ToJSON UpdateChannel
|
||||
instance FromJSON UpdateChannel
|
||||
|
||||
type API = Auth '[SA.BasicAuth, SA.Cookie, SA.JWT] SafeUser :> BaseAPI
|
||||
|
||||
type BaseAPI = "channels" :> ReqBody '[JSON] JsonChannel :> Post '[JSON] UpdateChannel
|
||||
:<|> "channels" :> Capture "channel_id" ChannelID :> ReqBody '[JSON] UpdateChannel :> Put '[JSON] UpdateChannel
|
||||
:<|> "channels" :> Get '[JSON] [JsonChannel]
|
1
common/src/API/Users.hs
Normal file
1
common/src/API/Users.hs
Normal file
@ -0,0 +1 @@
|
||||
module API.Users where
|
26
common/src/Auth.hs
Normal file
26
common/src/Auth.hs
Normal file
@ -0,0 +1,26 @@
|
||||
{-# Language GeneralizedNewtypeDeriving #-}
|
||||
module Auth where
|
||||
|
||||
import ClassyPrelude
|
||||
import Data.Aeson
|
||||
import Servant.Auth.Server (ToJWT, FromJWT)
|
||||
import Servant.API
|
||||
|
||||
-- generic-lens can convert similar types to this
|
||||
-- I'm trying out servant-auth-server which uses a jwt style login. IIRC anyone
|
||||
-- can open the jwt token and view what's inside, you just can't modify it.
|
||||
--
|
||||
-- Is it a problem that a human readable username and email are visible?
|
||||
newtype Email = Email { unEmail :: Text } deriving (Show, ToJSON, FromJSON, ToHttpApiData, FromHttpApiData)
|
||||
|
||||
newtype Username = Username { unUsername :: Text } deriving (Show, ToJSON, FromJSON, ToHttpApiData, FromHttpApiData)
|
||||
|
||||
data SafeUser = SafeUser { email :: Email
|
||||
, username :: Username
|
||||
}
|
||||
deriving (Show, Generic)
|
||||
|
||||
instance ToJSON SafeUser where
|
||||
instance FromJSON SafeUser where
|
||||
instance ToJWT SafeUser where
|
||||
instance FromJWT SafeUser where
|
@ -21,13 +21,13 @@ let
|
||||
mkShell = name: pkg:
|
||||
let
|
||||
n = "${name}-shell";
|
||||
deps = haskellPackages.ghcWithPackages (pkgs: pkg.nativeBuildInputs);
|
||||
deps = haskellPackages.ghcWithPackages (pkgs: pkg.buildInputs);
|
||||
in
|
||||
{
|
||||
name = "${n}";
|
||||
value = nixpkgs.buildEnv {
|
||||
name = "${n}";
|
||||
paths = tools;
|
||||
paths = tools ++ [deps];
|
||||
buildInputs = tools ++ [deps];
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user