ebook-manager/backend/src/API/Users.hs

70 lines
2.3 KiB
Haskell
Raw Normal View History

2018-08-03 23:36:38 +03:00
{-# Language DataKinds #-}
{-# Language TypeFamilies #-}
{-# Language OverloadedStrings #-}
{-# Language NoImplicitPrelude #-}
{-# Language TypeOperators #-}
{-# Language DuplicateRecordFields #-}
2018-08-04 22:05:41 +03:00
{-# Language TypeApplications #-}
module API.Users where
2018-08-03 23:36:38 +03:00
2018-11-12 21:32:42 +02:00
import ClassyPrelude
import Control.Monad.Catch (throwM, MonadThrow)
import Data.Aeson
import Database (runDB)
import Database.Schema
import Database.User
import Servant
import Servant.Auth as SA
import Servant.Auth.Server as SAS
import qualified Servant.Docs as Docs
import Server.Auth
import Types
import Web.FormUrlEncoded
2018-08-03 23:36:38 +03:00
2018-08-04 22:05:41 +03:00
data RegisterForm = RegisterForm { username :: Username
, email :: Email
, password :: PlainPassword
, passwordAgain :: PlainPassword }
2018-08-03 23:36:38 +03:00
deriving (Generic, Show)
2018-11-12 21:32:42 +02:00
instance Docs.ToSample RegisterForm
2018-08-04 22:05:41 +03:00
data LoginStatus = LoginStatus ( Maybe SafeUser ) deriving Generic
2018-08-03 23:36:38 +03:00
data RegisterStatus = RegisterStatus deriving Generic
2018-11-12 21:32:42 +02:00
instance Docs.ToSample RegisterStatus
2018-08-03 23:36:38 +03:00
instance ToJSON LoginStatus
instance FromJSON LoginStatus
2018-11-12 21:32:42 +02:00
instance Docs.ToSample LoginStatus
2018-08-03 23:36:38 +03:00
instance FromJSON RegisterForm
instance ToJSON RegisterForm
instance ToJSON RegisterStatus
instance FromJSON RegisterStatus
instance FromForm RegisterForm
instance ToForm RegisterForm
2018-08-04 23:43:26 +03:00
2018-08-05 23:13:49 +03:00
type API = Auth '[SA.BasicAuth, SA.JWT] SafeUser :> "login" :> Get '[JSON] LoginStatus
2018-08-03 23:36:38 +03:00
:<|> "register" :> ReqBody '[JSON, FormUrlEncoded] RegisterForm :> Post '[JSON] RegisterStatus
handler :: ServerT API AppM
handler = loginHandler :<|> registerHandler
2018-08-04 23:43:26 +03:00
loginHandler :: AuthResult SafeUser -> AppM LoginStatus
loginHandler (Authenticated u) = return (LoginStatus (Just u))
loginHandler _ = return (LoginStatus Nothing)
2018-08-03 23:36:38 +03:00
registerHandler :: RegisterForm -> AppM RegisterStatus
registerHandler RegisterForm{..} =
case () of
() | password /= passwordAgain -> noMatch
| otherwise ->
2018-08-04 22:05:41 +03:00
either (const alreadyExists) (const (pure RegisterStatus)) =<< runDB (insertUser username email password)
2018-08-03 23:36:38 +03:00
where
noMatch = throwM err403{errBody = "passwords don't match"}
alreadyExists = throwM err403{errBody = "User already exists"}