{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures #-}
module Web.Scim.Class.User
( UserDB (..),
StoredUser,
UserSite (..),
userServer,
)
where
import Data.Aeson.Types (FromJSON)
import Servant
import Servant.API.Generic
import Servant.Server.Generic
import Web.Scim.Class.Auth
import Web.Scim.ContentType
import Web.Scim.Filter
import Web.Scim.Handler
import Web.Scim.Schema.Common
import Web.Scim.Schema.ListResponse hiding (schemas)
import Web.Scim.Schema.Meta
import Web.Scim.Schema.PatchOp
import Web.Scim.Schema.User
type StoredUser tag = WithMeta (WithId (UserId tag) (User tag))
data UserSite tag route = UserSite
{ forall tag route.
UserSite tag route
-> route
:- (QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)))
usGetUsers ::
route
:- QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)),
forall tag route.
UserSite tag route
-> route
:- (Capture "id" (UserId tag) :> Get '[SCIM] (StoredUser tag))
usGetUser ::
route
:- Capture "id" (UserId tag)
:> Get '[SCIM] (StoredUser tag),
forall tag route.
UserSite tag route
-> route
:- (ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag))
usPostUser ::
route
:- ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag),
forall tag route.
UserSite tag route
-> route
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (User tag) :> Put '[SCIM] (StoredUser tag)))
usPutUser ::
route
:- Capture "id" (UserId tag)
:> ReqBody '[SCIM] (User tag)
:> Put '[SCIM] (StoredUser tag),
forall tag route.
UserSite tag route
-> route
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (PatchOp tag)
:> Patch '[SCIM] (StoredUser tag)))
usPatchUser ::
route
:- Capture "id" (UserId tag)
:> ReqBody '[SCIM] (PatchOp tag)
:> Patch '[SCIM] (StoredUser tag),
forall tag route.
UserSite tag route
-> route :- (Capture "id" (UserId tag) :> DeleteNoContent)
usDeleteUser ::
route
:- Capture "id" (UserId tag)
:> DeleteNoContent
}
deriving ((forall x. UserSite tag route -> Rep (UserSite tag route) x)
-> (forall x. Rep (UserSite tag route) x -> UserSite tag route)
-> Generic (UserSite tag route)
forall x. Rep (UserSite tag route) x -> UserSite tag route
forall x. UserSite tag route -> Rep (UserSite tag route) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall tag route x.
Rep (UserSite tag route) x -> UserSite tag route
forall tag route x.
UserSite tag route -> Rep (UserSite tag route) x
$cfrom :: forall tag route x.
UserSite tag route -> Rep (UserSite tag route) x
from :: forall x. UserSite tag route -> Rep (UserSite tag route) x
$cto :: forall tag route x.
Rep (UserSite tag route) x -> UserSite tag route
to :: forall x. Rep (UserSite tag route) x -> UserSite tag route
Generic)
class (Monad m, AuthTypes tag, UserTypes tag) => UserDB tag m where
getUsers ::
AuthInfo tag ->
Maybe Filter ->
ScimHandler m (ListResponse (StoredUser tag))
getUser ::
AuthInfo tag ->
UserId tag ->
ScimHandler m (StoredUser tag)
postUser ::
AuthInfo tag ->
User tag ->
ScimHandler m (StoredUser tag)
putUser ::
AuthInfo tag ->
UserId tag ->
User tag ->
ScimHandler m (StoredUser tag)
patchUser ::
AuthInfo tag ->
UserId tag ->
PatchOp tag ->
ScimHandler m (StoredUser tag)
default patchUser ::
(Patchable (UserExtra tag), FromJSON (UserExtra tag)) =>
AuthInfo tag ->
UserId tag ->
PatchOp tag ->
ScimHandler m (StoredUser tag)
patchUser AuthInfo tag
info UserId tag
uid PatchOp tag
op' = do
(WithMeta Meta
_ (WithId UserId tag
_ (User tag
user :: User tag))) <- AuthInfo tag -> UserId tag -> ScimHandler m (StoredUser tag)
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> UserId tag -> ScimHandler m (StoredUser tag)
getUser AuthInfo tag
info UserId tag
uid
(User tag
newUser :: User tag) <- User tag -> PatchOp tag -> ExceptT ScimError m (User tag)
forall tag (m :: * -> *).
(Patchable (UserExtra tag), FromJSON (UserExtra tag),
MonadError ScimError m, UserTypes tag) =>
User tag -> PatchOp tag -> m (User tag)
applyPatch User tag
user PatchOp tag
op'
AuthInfo tag
-> UserId tag -> User tag -> ScimHandler m (StoredUser tag)
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag
-> UserId tag -> User tag -> ScimHandler m (StoredUser tag)
putUser AuthInfo tag
info UserId tag
uid User tag
newUser
deleteUser ::
AuthInfo tag ->
UserId tag ->
ScimHandler m ()
userServer ::
forall tag m.
(AuthDB tag m, UserDB tag m) =>
Maybe (AuthData tag) ->
UserSite tag (AsServerT (ScimHandler m))
userServer :: forall tag (m :: * -> *).
(AuthDB tag m, UserDB tag m) =>
Maybe (AuthData tag) -> UserSite tag (AsServerT (ScimHandler m))
userServer Maybe (AuthData tag)
authData =
UserSite
{ usGetUsers :: AsServerT (ExceptT ScimError m)
:- (QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)))
usGetUsers = \Maybe Filter
mbFilter -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag
-> Maybe Filter -> ScimHandler m (ListResponse (StoredUser tag))
getUsers @tag AuthInfo tag
auth Maybe Filter
mbFilter,
usGetUser :: AsServerT (ExceptT ScimError m)
:- (Capture "id" (UserId tag) :> Get '[SCIM] (StoredUser tag))
usGetUser = \UserId tag
uid -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> UserId tag -> ScimHandler m (StoredUser tag)
getUser @tag AuthInfo tag
auth UserId tag
uid,
usPostUser :: AsServerT (ExceptT ScimError m)
:- (ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag))
usPostUser = \User tag
user -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> User tag -> ScimHandler m (StoredUser tag)
postUser @tag AuthInfo tag
auth User tag
user,
usPutUser :: AsServerT (ExceptT ScimError m)
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (User tag) :> Put '[SCIM] (StoredUser tag)))
usPutUser = \UserId tag
uid User tag
user -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag
-> UserId tag -> User tag -> ScimHandler m (StoredUser tag)
putUser @tag AuthInfo tag
auth UserId tag
uid User tag
user,
usPatchUser :: AsServerT (ExceptT ScimError m)
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (PatchOp tag)
:> Patch '[SCIM] (StoredUser tag)))
usPatchUser = \UserId tag
uid PatchOp tag
patch -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag
-> UserId tag -> PatchOp tag -> ScimHandler m (StoredUser tag)
patchUser @tag @m AuthInfo tag
auth UserId tag
uid PatchOp tag
patch,
usDeleteUser :: AsServerT (ExceptT ScimError m)
:- (Capture "id" (UserId tag) :> DeleteNoContent)
usDeleteUser = \UserId tag
uid -> do
AuthInfo tag
auth <- forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> UserId tag -> ScimHandler m ()
deleteUser @tag AuthInfo tag
auth UserId tag
uid
NoContent -> ExceptT ScimError m NoContent
forall a. a -> ExceptT ScimError m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure NoContent
NoContent
}