{-# LANGUAGE AllowAmbiguousTypes #-} -- This file is part of the Wire Server implementation. -- -- Copyright (C) 2020 Wire Swiss GmbH -- -- This program is free software: you can redistribute it and/or modify it under -- the terms of the GNU Affero General Public License as published by the Free -- Software Foundation, either version 3 of the License, or (at your option) any -- later version. -- -- This program is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -- details. -- -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . module Web.Scim.Client ( HasScimClient, -- * config spConfig, getSchemas, schema, resourceTypes, -- * user scimClients, getUsers, getUser, postUser, putUser, patchUser, deleteUser, -- * group getGroups, getGroup, postGroup, putGroup, patchGroup, deleteGroup, ) where import Control.Exception import Data.Aeson (FromJSON, ToJSON, Value) import Data.Text import Servant.API import Servant.Client import Servant.Client.Generic import qualified Web.Scim.Capabilities.MetaSchema as MetaSchema import Web.Scim.Class.Auth import Web.Scim.Class.Group (Group, GroupId, StoredGroup) import Web.Scim.Class.User (StoredUser) import Web.Scim.Filter (Filter) import Web.Scim.Schema.ListResponse (ListResponse) import Web.Scim.Schema.PatchOp (PatchOp) import qualified Web.Scim.Schema.ResourceType as ResourceType import Web.Scim.Schema.User (User) import Web.Scim.Schema.UserTypes (UserExtra, UserId) import Web.Scim.Server type HasScimClient tag = ( AuthTypes tag, ToJSON (UserExtra tag), FromJSON (UserExtra tag), FromJSON (UserId tag), FromJSON (GroupId tag), ToHttpApiData (AuthData tag), ToHttpApiData (UserId tag), ToHttpApiData (GroupId tag) ) scimClients :: HasScimClient tag => ClientEnv -> Site tag (AsClientT IO) scimClients env = genericClientHoist $ \x -> runClientM x env >>= either throwIO return -- config spConfig :: forall tag. HasScimClient tag => ClientEnv -> IO MetaSchema.Configuration spConfig env = case config @tag (scimClients env) of ((r :<|> _) :<|> (_ :<|> _)) -> r getSchemas :: forall tag. HasScimClient tag => ClientEnv -> IO (ListResponse Value) getSchemas env = case config @tag (scimClients env) of ((_ :<|> r) :<|> (_ :<|> _)) -> r schema :: forall tag. HasScimClient tag => ClientEnv -> Text -> IO Value schema env = case config @tag (scimClients env) of ((_ :<|> _) :<|> (r :<|> _)) -> r resourceTypes :: forall tag. HasScimClient tag => ClientEnv -> IO (ListResponse ResourceType.Resource) resourceTypes env = case config @tag (scimClients env) of ((_ :<|> _) :<|> (_ :<|> r)) -> r -- users getUsers :: HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> Maybe Filter -> IO (ListResponse (StoredUser tag)) getUsers env tok = case users (scimClients env) tok of ((r :<|> (_ :<|> _)) :<|> (_ :<|> (_ :<|> _))) -> r getUser :: HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> UserId tag -> IO (StoredUser tag) getUser env tok = case users (scimClients env) tok of ((_ :<|> (r :<|> _)) :<|> (_ :<|> (_ :<|> _))) -> r postUser :: HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> (User tag) -> IO (StoredUser tag) postUser env tok = case users (scimClients env) tok of ((_ :<|> (_ :<|> r)) :<|> (_ :<|> (_ :<|> _))) -> r putUser :: HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> UserId tag -> (User tag) -> IO (StoredUser tag) putUser env tok = case users (scimClients env) tok of ((_ :<|> (_ :<|> _)) :<|> (r :<|> (_ :<|> _))) -> r patchUser :: HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> UserId tag -> PatchOp tag -> IO (StoredUser tag) patchUser env tok = case users (scimClients env) tok of ((_ :<|> (_ :<|> _)) :<|> (_ :<|> (r :<|> _))) -> r deleteUser :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> UserId tag -> IO NoContent deleteUser env tok = case users @tag (scimClients env) tok of ((_ :<|> (_ :<|> _)) :<|> (_ :<|> (_ :<|> r))) -> r -- groups getGroups :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> IO (ListResponse (StoredGroup tag)) getGroups = error "groups are not authenticated at the moment; implement that first!" getGroup :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> GroupId tag -> IO (StoredGroup tag) getGroup = error "groups are not authenticated at the moment; implement that first!" postGroup :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> Group -> IO (StoredGroup tag) postGroup = error "groups are not authenticated at the moment; implement that first!" putGroup :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> GroupId tag -> IO (StoredGroup tag) putGroup = error "groups are not authenticated at the moment; implement that first!" patchGroup :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> GroupId tag -> IO (StoredGroup tag) patchGroup = error "groups are not authenticated at the moment; implement that first!" deleteGroup :: forall tag. HasScimClient tag => ClientEnv -> Maybe (AuthData tag) -> GroupId tag -> IO DeleteNoContent deleteGroup = error "groups are not authenticated at the moment; implement that first!"