From 9760f1144fcb13fb013124cef7e9424415b03966 Mon Sep 17 00:00:00 2001 From: iglocska Date: Fri, 2 Feb 2018 08:46:14 +0100 Subject: [PATCH] new: New APIs to add/remove orgs and servers from sharing groups, fixes #2888 - added functions to manage the additions/removals of objects from sharing groups - the following APIs are included: - /sharingGroups/addOrg/[sg_id]/[org_id]/[extend] - /sharingGroups/removeOrg/[sg_id]/[org_id] - /sharingGroups/addServer/[sg_id]/[server_id]/[all_orgs] - /sharingGroups/removeServer/[sg_id]/[server_id] - All parameters are optional and can instead be passed as JSON objects such as: { "org_uuid": "55f6ea5e-2c60-40e5-964f-47a8950d210f", "sg_id": "49", "extend": 1 } - The API is extremely flexible with how to name objects, the following parameters are allowed: - Organisations: - org_id (The organisation's local instance ID) - org_uuid (The organisation's global UUID) - org_name (The organisation's identifier as known to the curent instance) - Server: - server_id (The server's local instance ID) - server_url (The URL of the server) - server_name (The local name of the server as assigned when adding the server) The sharing groups can also be addressed by ID or UUID. --- app/Controller/SharingGroupsController.php | 153 +++++++++++++++++++++ app/Model/Organisation.php | 15 ++ app/Model/Server.php | 16 +++ app/Model/SharingGroup.php | 29 ++++ 4 files changed, 213 insertions(+) diff --git a/app/Controller/SharingGroupsController.php b/app/Controller/SharingGroupsController.php index 1fb7688ef..9eb621662 100644 --- a/app/Controller/SharingGroupsController.php +++ b/app/Controller/SharingGroupsController.php @@ -285,4 +285,157 @@ class SharingGroupsController extends AppController { $this->set('id', $id); $this->set('sg', $sg); } + + private function __initialiseSGQuickEdit($id, $request) { + if (!$this->request->is('post') || !$this->_isRest()) { + //throw new MethodNotAllowedException('This action only accepts POST requests coming from the API.'); + } + // allow passing the sg_id via a JSON object + if (!$id) { + $validParams = array('sg_id', 'sg_uuid', 'id', 'uuid'); + foreach ($validParams as $param) { + if (!empty($request[$param])) { + $id = $request[$param]; + break; + } + } + if (empty($id)) throw new MethodNotAllowedException('No valid sharing group ID provided.'); + } + $sg = $this->SharingGroup->fetchSG($id, $this->Auth->user(), false); + if (empty($sg)) { + throw new MethodNotAllowedException('Invalid sharing group or no editing rights.'); + } + return $sg; + } + + private function __initialiseSGQuickEditObject($id, $request, $type = 'org') { + $params = array( + 'org' => array( + 'org_id', 'org_uuid', 'org_name' + ), + 'server' => array( + 'server_id', 'server_url', 'server_baseurl', 'server_name' + ) + ); + if (!empty($id)) { + if ($type == 'org') { + return $this->SharingGroup->SharingGroupOrg->Organisation->fetchOrg($id); + } else { + return $this->SharingGroup->SharingGroupServer->Server->fetchServer($id); + } + } + if ($type !== 'org' && $type !== 'server') return false; + foreach ($params[$type] as $param) { + if (!empty($request[$param])) { + if ($type == 'org') { + return $this->SharingGroup->SharingGroupOrg->Organisation->fetchOrg($request[$param]); + } else { + return $this->SharingGroup->SharingGroupServer->Server->fetchServer($request[$param]); + } + } + } + } + + public function addOrg($sg_id = false, $object_id = false, $extend = false) { + $sg = $this->__initialiseSGQuickEdit($sg_id, $this->request->data); + $org = $this->__initialiseSGQuickEditObject($object_id, $this->request->data, $type = 'org'); + if (empty($org)) throw new MethodNotAllowedException('Invalid organisation.'); + if (isset($this->request->data['extend'])) { + $extend = $this->request->data['extend']; + } + $addOrg = true; + if (!empty($sg['SharingGroupOrg'])) { + foreach ($sg['SharingGroupOrg'] as $sgo) { + if ($sgo['org_id'] == $org['Organisation']['id']) { + $addOrg = false; + } + } + } + if (!$addOrg) return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Organisation is already in the sharing group.', $this->response->type()); + $this->SharingGroup->SharingGroupOrg->create(); + $sgo = array( + 'SharingGroupOrg' => array( + 'org_id' => $org['Organisation']['id'], + 'sharing_group_id' => $sg['SharingGroup']['id'], + 'extend' => $extend ? 1:0 + ) + ); + $result = $this->SharingGroup->SharingGroupOrg->save($sgo); + return $this->__sendQuickSaveResponse($this->action, $result, 'Organisation'); + } + + public function removeOrg($sg_id = false, $object_id = false) { + $sg = $this->__initialiseSGQuickEdit($sg_id, $this->request->data); + $org = $this->__initialiseSGQuickEditObject($object_id, $this->request->data, $type = 'org'); + if (empty($org)) throw new MethodNotAllowedException('Invalid organisation.'); + $removeOrg = false; + if (!empty($sg['SharingGroupOrg'])) { + foreach ($sg['SharingGroupOrg'] as $sgo) { + if ($sgo['org_id'] == $org['Organisation']['id']) { + $removeOrg = $sgo['id']; + break; + } + } + } + if (false === $removeOrg) return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Organisation is not in the sharing group.', $this->response->type()); + $result = $this->SharingGroup->SharingGroupOrg->delete($removeOrg); + return $this->__sendQuickSaveResponse($this->action, $result, 'Organisation'); + } + + public function addServer($sg_id = false, $object_id = false, $all = false) { + $sg = $this->__initialiseSGQuickEdit($sg_id, $this->request->data); + $server = $this->__initialiseSGQuickEditObject($object_id, $this->request->data, $type = 'server'); + if (empty($server)) throw new MethodNotAllowedException('Invalid Server.'); + if (isset($this->request->data['all'])) $all = $this->request->data['all']; + if (isset($this->request->data['all_orgs'])) $all = $this->request->data['all_orgs']; + $addServer = true; + if (!empty($sg['SharingGroupServer'])) { + foreach ($sg['SharingGroupServer'] as $sgs) { + if ($sgs['server_id'] == $server['Server']['id']) { + $addServer = false; + } + } + } + if (!$addServer) return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Server is already in the sharing group.', $this->response->type()); + $this->SharingGroup->SharingGroupServer->create(); + $sgs = array( + 'SharingGroupServer' => array( + 'server_id' => $server['Server']['id'], + 'sharing_group_id' => $sg['SharingGroup']['id'], + 'all_orgs' => $all ? 1:0 + ) + ); + $result = $this->SharingGroup->SharingGroupServer->save($sgs); + return $this->__sendQuickSaveResponse($this->action, $result); + } + + public function removeServer($sg_id = false, $object_id = false) { + $sg = $this->__initialiseSGQuickEdit($sg_id, $this->request->data); + $server = $this->__initialiseSGQuickEditObject($object_id, $this->request->data, $type = 'server'); + if (empty($server)) throw new MethodNotAllowedException('Invalid Server.'); + $removeServer = false; + if (!empty($sg['SharingGroupServer'])) { + foreach ($sg['SharingGroupServer'] as $sgs) { + if ($sgs['server_id'] == $server['Server']['id']) { + $removeServer = $server['Server']['id']; + break; + } + } + } + if (false === $addServer) return $this->RestResponse->saveFailResponse('SharingGroup', $this->action, false, 'Server is not in the sharing group.', $this->response->type()); + $result = $this->SharingGroup->SharingGroupServer->delete($removeServer); + return $this->__sendQuickSaveResponse($this->action, $result); + } + + private function __sendQuickSaveResponse($action, $result, $object_type = 'Server') { + $actionType = 'added to'; + if (strpos($action, 'remove') !== false) { + $actionType = 'removed from'; + } + if ($result) { + return $this->RestResponse->saveSuccessResponse('SharingGroup', $action, false, $this->response->type(), $object_type . ' ' . $actionType . ' the sharing group.'); + } else { + return $this->RestResponse->saveFailResponse('SharingGroup', $action, false, $object_type . ' could not be ' . $actionType . ' the sharing group.', $this->response->type()); + } + } } diff --git a/app/Model/Organisation.php b/app/Model/Organisation.php index 05f67ee3c..75892deae 100644 --- a/app/Model/Organisation.php +++ b/app/Model/Organisation.php @@ -304,4 +304,19 @@ class Organisation extends AppModel{ $logFile->close(); return $success; } + + public function fetchOrg($id) { + if (empty($id)) return false; + $conditions = array('Organisation.id' => $id); + if (Validation::uuid($id)) { + $conditions = array('Organisation.uuid' => $id); + } else if (!is_numeric($id)) { + $conditions = array('LOWER(Organisation.name)' => strtolower($id)); + } + $org = $this->find('first', array( + 'conditions' => $conditions, + 'recursive' => -1 + )); + return (empty($org)) ? false : $org; + } } diff --git a/app/Model/Server.php b/app/Model/Server.php index 315e663f6..7ab8554d4 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -3679,4 +3679,20 @@ class Server extends AppModel { public function getDefaultAttachments_dir() { return APP . 'files'; } + + public function fetchServer($id) { + if (empty($id)) return false; + $conditions = array('Server.id' => $id); + if (!is_numeric($id)) { + $conditions = array('OR' => array( + 'LOWER(Server.name)' => strtolower($id), + 'LOWER(Server.url)' => strtolower($id) + )); + } + $server = $this->find('first', array( + 'conditions' => $conditions, + 'recursive' => -1 + )); + return (empty($server)) ? false : $server; + } } diff --git a/app/Model/SharingGroup.php b/app/Model/SharingGroup.php index 9733731a8..c3be97b93 100644 --- a/app/Model/SharingGroup.php +++ b/app/Model/SharingGroup.php @@ -625,4 +625,33 @@ class SharingGroup extends AppModel { } } } + + // Fetch the Sharing Group passed as ID/uuid. Can be queried for read only and for write operations. + public function fetchSG($id, $user, $readOnly = true) { + if (empty($id)) return false; + if (Validation::uuid($id)) { + $id = $this->find('first', array( + 'conditions' => array('SharingGroup.uuid' => $id), + 'recursive' => -1, + 'fields' => array('SharingGroup.id') + )); + if (empty($id)) return false; + else $id = $id['SharingGroup']['id']; + } else { + $temp = $this->find('first', array( + 'conditions' => array('SharingGroup.id' => $id), + 'recursive' => -1, + 'fields' => array('SharingGroup.id') + )); + if (empty($temp)) return false; + } + if ($readOnly) { + if (!$this->checkIfAuthorised($user, $id)) return false; + } else { + if (!$this->checkIfAuthorisedExtend($user, $id)) return false; + } + $sg = $this->fetchAllAuthorised($user, 'full', false, $id); + if (empty($sg)) return false; + return $sg[0]; + } }