{-# 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
{ UserSite tag route
-> route
:- (QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)))
usGetUsers ::
route
:- QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)),
UserSite tag route
-> route
:- (Capture "id" (UserId tag) :> Get '[SCIM] (StoredUser tag))
usGetUser ::
route
:- Capture "id" (UserId tag)
:> Get '[SCIM] (StoredUser tag),
UserSite tag route
-> route
:- (ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag))
usPostUser ::
route
:- ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag),
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),
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),
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
$cto :: forall tag route x.
Rep (UserSite tag route) x -> UserSite tag route
$cfrom :: forall tag route x.
UserSite tag route -> Rep (UserSite tag route) x
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 :: Maybe (AuthData tag) -> UserSite tag (AsServerT (ScimHandler m))
userServer Maybe (AuthData tag)
authData =
UserSite :: forall tag route.
(route
:- (QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag))))
-> (route
:- (Capture "id" (UserId tag) :> Get '[SCIM] (StoredUser tag)))
-> (route
:- (ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag)))
-> (route
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (User tag) :> Put '[SCIM] (StoredUser tag))))
-> (route
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (PatchOp tag)
:> Patch '[SCIM] (StoredUser tag))))
-> (route :- (Capture "id" (UserId tag) :> DeleteNoContent))
-> UserSite tag route
UserSite
{ usGetUsers :: AsServerT (ScimHandler m)
:- (QueryParam "filter" Filter
:> Get '[SCIM] (ListResponse (StoredUser tag)))
usGetUsers = \Maybe Filter
mbFilter -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag
-> Maybe Filter
-> ExceptT ScimError m (ListResponse (StoredUser tag))
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 (ScimHandler m)
:- (Capture "id" (UserId tag) :> Get '[SCIM] (StoredUser tag))
usGetUser = \UserId tag
uid -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag -> UserId tag -> ExceptT ScimError m (StoredUser tag)
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> UserId tag -> ScimHandler m (StoredUser tag)
getUser @tag AuthInfo tag
auth UserId tag
uid,
usPostUser :: AsServerT (ScimHandler m)
:- (ReqBody '[SCIM] (User tag)
:> PostCreated '[SCIM] (StoredUser tag))
usPostUser = \User tag
user -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag -> User tag -> ExceptT ScimError m (StoredUser tag)
forall tag (m :: * -> *).
UserDB tag m =>
AuthInfo tag -> User tag -> ScimHandler m (StoredUser tag)
postUser @tag AuthInfo tag
auth User tag
user,
usPutUser :: AsServerT (ScimHandler m)
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (User tag) :> Put '[SCIM] (StoredUser tag)))
usPutUser = \UserId tag
uid User tag
user -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag
-> UserId tag -> User tag -> ExceptT ScimError m (StoredUser tag)
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 (ScimHandler m)
:- (Capture "id" (UserId tag)
:> (ReqBody '[SCIM] (PatchOp tag)
:> Patch '[SCIM] (StoredUser tag)))
usPatchUser = \UserId tag
uid PatchOp tag
patch -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag
-> UserId tag
-> PatchOp tag
-> ExceptT ScimError m (StoredUser tag)
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 (ScimHandler m)
:- (Capture "id" (UserId tag) :> DeleteNoContent)
usDeleteUser = \UserId tag
uid -> do
AuthInfo tag
auth <- Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
forall tag (m :: * -> *).
AuthDB tag m =>
Maybe (AuthData tag) -> ScimHandler m (AuthInfo tag)
authCheck @tag Maybe (AuthData tag)
authData
AuthInfo tag -> UserId tag -> ScimHandler m ()
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 (f :: * -> *) a. Applicative f => a -> f a
pure NoContent
NoContent
}