From b076463bf47dff09c0fe559ff15517556337a79f Mon Sep 17 00:00:00 2001 From: Christophe Vandeplas Date: Sun, 28 Jan 2024 08:25:27 +0000 Subject: [PATCH 1/2] fix: [composer] slevomat coding-standard --- composer.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e3b645bcb..1aaac1cc5 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5", "psy/psysh": "@stable", - "sirbrillig/phpcs-variable-analysis": "^2.11" + "sirbrillig/phpcs-variable-analysis": "^2.11", + "slevomat/coding-standard": "~8.0" }, "suggest": { "markstory/asset_compress": "An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.", @@ -85,4 +86,4 @@ "php-http/discovery": true } } -} \ No newline at end of file +} From 7a9c8f5989d9270d6590f1f003a80e055534b92a Mon Sep 17 00:00:00 2001 From: Christophe Vandeplas Date: Sun, 28 Jan 2024 11:49:36 +0100 Subject: [PATCH 2/2] [3.x-migration] Cerebrates (#9507) * new: [Cerebrates] pullOrgs, pullSgs test * fix: [AppController] fix bug in harvestParameters() * fix: [Cerebrate] follow codingstyle * fix: [Cerebrate] more codingstyle * fix: [Cerebrates] strict types fixes * fix: [composer] slevomat coding-standard * fix: [Cerebrates] minor codestyle fix * fix: [codingstyle] --- src/Controller/AppController.php | 119 +++++++--- src/Controller/CerebratesController.php | 221 +++++++++++------- src/Lib/Tools/CurlAdvanced.php | 14 +- src/Model/Entity/Cerebrate.php | 193 ++++++++++----- src/Model/Table/CerebratesTable.php | 11 +- templates/Cerebrates/add.php | 37 +-- templates/Cerebrates/index.php | 204 ++++++++-------- templates/Cerebrates/preview_orgs.php | 95 ++++---- .../Cerebrates/preview_sharing_groups.php | 111 ++++----- templates/Cerebrates/view.php | 14 +- .../Api/Cerebrates/AddCerebrateApiTest.php | 7 +- .../Api/Cerebrates/DeleteCerebrateApiTest.php | 3 +- .../DownloadOrgCerebrateApiTest.php | 10 +- .../DownloadSharingGroupCerebrateApiTest.php | 12 +- .../Api/Cerebrates/EditCerebrateApiTest.php | 11 +- .../Api/Cerebrates/IndexCerebratesApiTest.php | 3 +- .../PreviewOrgsCerebrateApiTest.php | 9 +- .../PreviewSharingGroupsCerebrateApiTest.php | 9 +- .../Cerebrates/PullOrgsCerebrateApiTest.php | 60 +++++ .../Cerebrates/PullSgsCerebrateApiTest.php | 61 +++++ .../Api/Cerebrates/ViewCerebrateApiTest.php | 3 +- 21 files changed, 755 insertions(+), 452 deletions(-) create mode 100644 tests/TestCase/Api/Cerebrates/PullOrgsCerebrateApiTest.php create mode 100644 tests/TestCase/Api/Cerebrates/PullSgsCerebrateApiTest.php diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index cca48c29a..50a81fc85 100644 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -1,5 +1,4 @@ loadComponent( 'ParamHandler', [ - 'request' => $this->request + 'request' => $this->request, ] ); $this->loadModel('MetaFields'); @@ -85,7 +86,7 @@ class AppController extends Controller 'request' => $this->request, 'table' => $table, 'MetaFields' => $this->MetaFields, - 'MetaTemplates' => $this->MetaTemplates + 'MetaTemplates' => $this->MetaTemplates, ] ); $this->loadComponent('Authentication.Authentication'); @@ -93,7 +94,7 @@ class AppController extends Controller 'ACL', [ 'request' => $this->request, - 'Authentication' => $this->Authentication + 'Authentication' => $this->Authentication, ] ); $this->loadComponent( @@ -123,6 +124,12 @@ class AppController extends Controller //$this->loadComponent('FormProtection'); } + /** + * beforeFilter + * + * @param \Cake\Event\EventInterface $event the event + * @return void + */ public function beforeFilter(EventInterface $event) { $this->loadModel('Users'); @@ -137,13 +144,14 @@ class AppController extends Controller $user = $this->Users->get( $this->request->getAttribute('identity')->getIdentifier(), [ - 'contain' => ['Roles', 'Organisations' /*'UserSettings'*/] + 'contain' => ['Roles', 'Organisations' /*'UserSettings'*/], ] ); $this->__accessMonitor($user->toArray()); if (!empty($user['disabled'])) { $this->Authentication->logout(); $this->Flash->error(__('The user account is disabled.')); + return $this->redirect(\Cake\Routing\Router::url('/users/login')); } unset($user['password']); @@ -157,7 +165,7 @@ class AppController extends Controller $this->set('loggedUser', $this->ACL->getUser()); $this->set('roleAccess', $this->ACL->getRoleAccess(false, false)); } - } else if ($this->ParamHandler->isRest()) { + } elseif ($this->ParamHandler->isRest()) { throw new MethodNotAllowedException(__('Invalid user credentials.')); } @@ -199,6 +207,12 @@ class AppController extends Controller } } + /** + * beforeRender + * + * @param \Cake\Event\EventInterface $event the event + * @return void + */ public function beforeRender(EventInterface $event) { if (!empty($this->request->getAttribute('identity'))) { @@ -210,6 +224,11 @@ class AppController extends Controller } } + /** + * authApiUser + * + * @return void + */ private function authApiUser(): void { if (!empty($_SERVER['HTTP_AUTHORIZATION']) && strlen($_SERVER['HTTP_AUTHORIZATION'])) { @@ -225,7 +244,7 @@ class AppController extends Controller 'model' => 'Users', 'model_id' => $user['id'], 'model_title' => $user['username'], - 'changed' => [] + 'changed' => [], ] ); if (!empty($user)) { @@ -239,31 +258,50 @@ class AppController extends Controller 'model' => 'Users', 'model_id' => $user['id'], 'model_title' => $user['name'], - 'changed' => [] + 'changed' => [], ] ); } } } + /** + * generateUUID + * + * @return void + */ public function generateUUID() { $uuid = Text::uuid(); + return $this->RestResponse->viewData(['uuid' => $uuid], 'json'); } + /** + * queryACL + * + * @return void + */ public function queryACL() { return $this->RestResponse->viewData($this->ACL->findMissingFunctionNames()); } + /** + * getRoleAccess + * + * @return void + */ public function getRoleAccess() { return $this->RestResponse->viewData($this->ACL->getRoleAccess(false, false)); } /** - * Convert an array to the same array but with the values also as index instead of an interface_exists + * arrayToValuesIndexArray - Convert an array to the same array but with the values also as index instead of an interface_exists + * + * @param array $oldArray the original array + * @return array */ protected function arrayToValuesIndexArray(array $oldArray): array { @@ -271,10 +309,16 @@ class AppController extends Controller foreach ($oldArray as $value) { $newArray[$value] = $value; } + return $newArray; } - // checks if the currently logged user is a site administrator (an admin that can manage any user or event on the instance and create / edit the roles). + /** + * isSiteAdmin + * checks if the currently logged user is a site administrator (an admin that can manage any user or event on the instance and create / edit the roles). + * + * @return void + */ protected function isSiteAdmin() { return $this->ACL->getUser()->Role->perm_site_admin; @@ -282,34 +326,30 @@ class AppController extends Controller /** * Close session without writing changes to them and return current user. + * * @return array */ protected function closeSession() { $user = $this->ACL->getUser(); session_abort(); + return $user->toArray(); } /** * generic function to standardise on the collection of parameters. Accepts posted request objects, url params, named url params - * @param array $options - * @param CakeResponse $exception - * @param array $data + * + * @param array $options options + * @param mixed $exception exception + * @param array $data data * @return array|false */ protected function harvestParameters($options, &$exception = null, $data = []) { $request = $options['request'] ?? $this->request; if ($request->is('post')) { - if (empty($request->data)) { - $exception = $this->RestResponse->throwException( - 400, - __('Either specify the search terms in the url, or POST a json with the filter parameters.'), - '/' . $request->params['controller'] . '/' . $request->action - ); - return false; - } else { + if (!empty($request->data)) { if (isset($request->data['request'])) { $temp = $request->data['request']; } else { @@ -327,6 +367,14 @@ class AppController extends Controller } } } + } elseif (empty($request->data) && !$this->ParamHandler->isRest()) { + $exception = $this->RestResponse->throwException( + 400, + __('Either specify the search terms in the url, or POST a json with the filter parameters.'), + '/' . $request->params['controller'] . '/' . $request->action + ); + + return false; } } /* @@ -385,21 +433,32 @@ class AppController extends Controller } } } + return $data; } + /** + * captureParam + * + * @param mixed $data data + * @param mixed $param param + * @param mixed $value value + * @return mixed + */ private function captureParam($data, $param, $value) { $table = $this->getTableLocator()->get($this->defaultModel); if ($table->checkParam($param)) { $data[$param] = $value; } + return $data; } /** * Decode JSON with proper error handling. - * @param string $dataToDecode + * + * @param string $dataToDecode data to decode * @return mixed */ protected function _jsonDecode($dataToDecode) @@ -411,6 +470,11 @@ class AppController extends Controller } } + /** + * setResponseType + * + * @return static|void + */ private function setResponseType() { foreach ($this->request->getHeader('Accept') as $accept) { @@ -426,12 +490,13 @@ class AppController extends Controller protected function _remoteIp() { $ipHeader = Configure::read('MISP.log_client_ip_header') ?: 'REMOTE_ADDR'; + return isset($_SERVER[$ipHeader]) ? trim($_SERVER[$ipHeader]) : $_SERVER['REMOTE_ADDR']; } /** - * @param array $user - * @throws Exception + * @param array $user affected user + * @throws \Exception */ private function __accessMonitor(array $user) { @@ -450,7 +515,7 @@ class AppController extends Controller if ($shouldBeLogged) { $includeRequestBody = !empty(Configure::read('MISP.log_paranoid_include_post_body')) || $userMonitoringEnabled; - /** @var AccessLog $accessLog */ + /** @var \App\Model\Entity\AccessLog $accessLog */ $accessLogsTable = $this->fetchTable('AccessLogs'); $accessLogsTable->logRequest($user, $this->_remoteIp(), $this->request, $includeRequestBody); } @@ -460,7 +525,7 @@ class AppController extends Controller $shouldBeLogged ) { $change = 'HTTP method: ' . $_SERVER['REQUEST_METHOD'] . PHP_EOL . 'Target: ' . $this->request->getAttribute('here'); - ; + if ( ( $this->request->is('post') || diff --git a/src/Controller/CerebratesController.php b/src/Controller/CerebratesController.php index a7003c72b..8e7197d0d 100644 --- a/src/Controller/CerebratesController.php +++ b/src/Controller/CerebratesController.php @@ -1,12 +1,10 @@ ['Organisations'], 'filters' => ['name', 'url', 'uuid'], - 'quickFilters' => ['name'] + 'quickFilters' => ['name'], ]; $this->CRUD->index($params); @@ -39,13 +37,14 @@ class CerebratesController extends AppController /** * View method * - * @param string|null $id Cerebrate id. + * @param int|null $id Cerebrate id. * @return \Cake\Http\Response|null|void Renders view * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ - public function view($id = null) + public function view(int|null $id = null) { - $this->CRUD->view($id, + $this->CRUD->view( + $id, ['contain' => ['Organisations']] ); $responsePayload = $this->CRUD->getResponsePayload(); @@ -70,13 +69,16 @@ class CerebratesController extends AppController return $responsePayload; } - $orgs = $this->Cerebrates->Organisations->find('list', [ - 'recursive' => -1, - 'fields' => ['id', 'name'], - 'order' => ['lower(name)' => 'ASC'] - ]); + $orgs = $this->Cerebrates->Organisations->find( + 'list', + [ + 'recursive' => -1, + 'fields' => ['id', 'name'], + 'order' => ['lower(name)' => 'ASC'], + ] + ); $dropdownData = [ - 'org_id' => $orgs + 'org_id' => $orgs, ]; $this->set(compact('dropdownData')); } @@ -84,11 +86,11 @@ class CerebratesController extends AppController /** * Edit method * - * @param string|null $id Cerebrate id. + * @param int|null $id Cerebrate id. * @return \Cake\Http\Response|null|void Redirects on successful edit, renders view otherwise. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ - public function edit($id = null) + public function edit(int|null $id = null) { $params = []; $this->CRUD->edit($id, $params); @@ -97,13 +99,16 @@ class CerebratesController extends AppController return $responsePayload; } - $orgs = $this->Cerebrates->Organisations->find('list', [ - 'recursive' => -1, - 'fields' => ['id', 'name'], - 'order' => ['lower(name)' => 'ASC'] - ]); + $orgs = $this->Cerebrates->Organisations->find( + 'list', + [ + 'recursive' => -1, + 'fields' => ['id', 'name'], + 'order' => ['lower(name)' => 'ASC'], + ] + ); $dropdownData = [ - 'org_id' => $orgs + 'org_id' => $orgs, ]; $this->set(compact('dropdownData')); $this->render('add'); @@ -112,11 +117,11 @@ class CerebratesController extends AppController /** * Delete method * - * @param string|null $id Cerebrate id. + * @param int|null $id Cerebrate id. * @return \Cake\Http\Response|null|void Redirects to index. * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ - public function delete($id = null) + public function delete(int|null $id = null) { $this->CRUD->delete($id); $responsePayload = $this->CRUD->getResponsePayload(); @@ -125,9 +130,13 @@ class CerebratesController extends AppController } } - - - public function pullOrgs($id) + /** + * pullOrgs + * + * @param int $id of the org + * @return void + */ + public function pullOrgs(int $id) { // FIXME chri - $this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateOrgs']); /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -135,17 +144,21 @@ class CerebratesController extends AppController if (empty($cerebrate)) { throw new NotFoundException(__('Invalid Cerebrate instance ID provided.')); } - + if ($this->request->is('post')) { - $orgs = $cerebrate->queryInstance([ - 'path' => '/organisations/index', - 'params' => $this->harvestParameters([ - 'name', - 'uuid', - 'quickFilter' - ]), - 'type' => 'GET' - ]); + $orgs = $cerebrate->queryInstance( + [ + 'path' => '/organisations/index', + 'params' => $this->harvestParameters( + [ + 'name', + 'uuid', + 'quickFilter', + ] + ), + 'type' => 'GET', + ] + ); $result = $cerebrate->saveRemoteOrgs($orgs); $message = __('Added {0} new organisations, updated {1} existing organisations, {2} failures.', $result['add'], $result['edit'], $result['fails']); if ($this->ParamHandler->isRest()) { @@ -165,7 +178,13 @@ class CerebratesController extends AppController } } - public function pullSgs($id) + /** + * pullSgs + * + * @param int $id id of the Sharing Group + * @return void + */ + public function pullSgs(int $id) { // $this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateSgs']); /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -175,15 +194,19 @@ class CerebratesController extends AppController } if ($this->request->is('post')) { - $sgs = $cerebrate->queryInstance([ - 'path' => '/sharingGroups/index', - 'params' => $this->harvestParameters([ - 'name', - 'uuid', - 'quickFilter' - ]), - 'type' => 'GET' - ]); + $sgs = $cerebrate->queryInstance( + [ + 'path' => '/sharingGroups/index', + 'params' => $this->harvestParameters( + [ + 'name', + 'uuid', + 'quickFilter', + ] + ), + 'type' => 'GET', + ] + ); $result = $cerebrate->saveRemoteSgs($sgs, $this->ACL->getUser()); $message = __('Added {0} new sharing groups, updated {1} existing sharing groups, {2} failures.', $result['add'], $result['edit'], $result['fails']); if ($this->ParamHandler->isRest()) { @@ -203,7 +226,13 @@ class CerebratesController extends AppController } } - public function previewOrgs($id = null) + /** + * previewOrgs + * + * @param int $id id of the org + * @return void + */ + public function previewOrgs(int|null $id = null) { // FIXME chri - $this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateOrgs']); /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -212,15 +241,19 @@ class CerebratesController extends AppController throw new NotFoundException(__('Invalid Cerebrate instance ID provided.')); } - $orgs = $cerebrate->queryInstance([ - 'path' => '/organisations/index', - 'params' => $this->harvestParameters([ - 'name', - 'uuid', - 'quickFilter' - ]), - 'type' => 'GET' - ]); + $orgs = $cerebrate->queryInstance( + [ + 'path' => '/organisations/index', + 'params' => $this->harvestParameters( + [ + 'name', + 'uuid', + 'quickFilter', + ] + ), + 'type' => 'GET', + ] + ); $result = $cerebrate->checkRemoteOrgs($orgs); if ($this->ParamHandler->isRest()) { return $this->RestResponse->viewData($result, $this->response->getType()); @@ -234,7 +267,14 @@ class CerebratesController extends AppController } } - public function downloadOrg($cerebrate_id, $org_id) + /** + * downloadOrg + * + * @param int $cerebrate_id id of the cerebrate instance + * @param int $org_id id of the org + * @return void + */ + public function downloadOrg(int $cerebrate_id, int $org_id) { if ($this->request->is('post')) { /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -242,10 +282,12 @@ class CerebratesController extends AppController if (empty($cerebrate)) { throw new NotFoundException(__('Invalid Cerebrate instance ID provided.')); } - $result = $cerebrate->queryInstance([ - 'path' => '/organisations/view/' . $org_id, - 'type' => 'GET' - ]); + $result = $cerebrate->queryInstance( + [ + 'path' => '/organisations/view/' . $org_id, + 'type' => 'GET', + ] + ); $saveResult = $cerebrate->captureOrg($result); if ($this->ParamHandler->isRest()) { if (is_array($saveResult)) { @@ -272,7 +314,13 @@ class CerebratesController extends AppController } } - public function previewSharingGroups($id) + /** + * previewSharingGroups + * + * @param int $id id of the Sharing Group + * @return void + */ + public function previewSharingGroups(int $id) { // $this->set('menuData', ['menuList' => 'sync', 'menuItem' => 'previewCerebrateSGs']); /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -280,18 +328,24 @@ class CerebratesController extends AppController if (empty($cerebrate)) { throw new NotFoundException(__('Invalid Cerebrate instance ID provided.')); } - $sgs = $cerebrate->queryInstance([ - 'path' => '/sharingGroups/index', - 'params' => $this->harvestParameters([ - 'name', - 'uuid', - 'quickFilter' - ]), - 'type' => 'GET' - ]); - if (!empty($sgs)) + $sgs = $cerebrate->queryInstance( + [ + 'path' => '/sharingGroups/index', + 'params' => $this->harvestParameters( + [ + 'name', + 'uuid', + 'quickFilter', + ] + ), + 'type' => 'GET', + ] + ); + if (!empty($sgs)) { $result = $cerebrate->checkRemoteSharingGroups($sgs); - else $result = []; + } else { + $result = []; + } if ($this->ParamHandler->isRest()) { return $this->RestResponse->viewData($result, $this->response->getType()); } else { @@ -304,7 +358,14 @@ class CerebratesController extends AppController } } - public function downloadSg($cerebrate_id, $sg_id) + /** + * downloadSg + * + * @param int $cerebrate_id id of the cerebrate instance + * @param int $sg_id id of the Sharing Group + * @return void + */ + public function downloadSg(int $cerebrate_id, int $sg_id) { if ($this->request->is('post')) { /** @var \App\Model\Entity\Cerebrate $cerebrate */ @@ -312,10 +373,12 @@ class CerebratesController extends AppController if (empty($cerebrate)) { throw new NotFoundException(__('Invalid Cerebrate instance ID provided.')); } - $result = $cerebrate->queryInstance([ - 'path' => '/sharingGroups/view/' . $sg_id, - 'type' => 'GET' - ]); + $result = $cerebrate->queryInstance( + [ + 'path' => '/sharingGroups/view/' . $sg_id, + 'type' => 'GET', + ] + ); $saveResult = $cerebrate->captureSg($result, $this->ACL->getUser()); if ($this->ParamHandler->isRest()) { if (is_array($saveResult)) { diff --git a/src/Lib/Tools/CurlAdvanced.php b/src/Lib/Tools/CurlAdvanced.php index e92762fe9..d61c1667f 100644 --- a/src/Lib/Tools/CurlAdvanced.php +++ b/src/Lib/Tools/CurlAdvanced.php @@ -1,4 +1,5 @@ true, // ask curl for the certificate information + CURLOPT_CERTINFO => true, // ask curl for the certificate information // CURLOPT_VERBOSE => true, - CURLOPT_NOBODY => true, // no need for the body + CURLOPT_NOBODY => true, // no need for the body ]; - + $options = $this->buildOptions($request, $options); curl_setopt_array($ch, $options); diff --git a/src/Model/Entity/Cerebrate.php b/src/Model/Entity/Cerebrate.php index 8b4732f46..40ea984a2 100644 --- a/src/Model/Entity/Cerebrate.php +++ b/src/Model/Entity/Cerebrate.php @@ -1,19 +1,16 @@ true, ]; - /** * queryInstance - Query a remote Cerebrate instance for a specific path * @@ -79,10 +75,11 @@ class Cerebrate extends AppModel $response = $httpTool->get( $url, [], - (isset($options['params']) ? $options['params'] : [])); + ($options['params'] ?? []) + ); } if ($response->isOk()) { - return json_decode($response->getBody(), true); + return json_decode($response->getBody()->__toString(), true); } } catch (NetworkException $e) { throw new BadRequestException(__('Something went wrong. Error returned: {0}', $e->getMessage())); @@ -93,26 +90,32 @@ class Cerebrate extends AppModel throw new BadRequestException(__('Something went wrong with the request or the remote side is having issues.')); } - public function convertOrg($org_data) + /** + * convertOrg + * + * @param mixed $org_data organisation data + * @return array + */ + public function convertOrg($org_data) { $mapping = [ 'name' => [ 'field' => 'name', - 'required' => 1 + 'required' => 1, ], 'uuid' => [ 'field' => 'uuid', - 'required' => 1 + 'required' => 1, ], 'nationality' => [ - 'field' => 'nationality' + 'field' => 'nationality', ], 'sector' => [ - 'field' => 'sector' + 'field' => 'sector', ], 'type' => [ - 'field' => 'type' - ] + 'field' => 'type', + ], ]; $org = []; foreach ($mapping as $cerebrate_field => $field_data) { @@ -125,12 +128,12 @@ class Cerebrate extends AppModel } $org[$field_data['field']] = $org_data[$cerebrate_field]; } + return $org; } - /** - * saveRemoteOrgs - + * saveRemoteOrgs - * * @param array $orgs An array of organisations with name, uuid, sector, nationality, type * @return array {'add': int, 'edit': int, 'fails': int} @@ -140,7 +143,7 @@ class Cerebrate extends AppModel $outcome = [ 'add' => 0, 'edit' => 0, - 'fails' => 0 + 'fails' => 0, ]; foreach ($orgs as $org) { $isEdit = false; @@ -158,14 +161,15 @@ class Cerebrate extends AppModel } } } + return $outcome; } - + /** * saveRemoteSgs * - * @param mixed $sgs - * @param mixed $user + * @param mixed $sgs SharingGroups + * @param mixed $user user * @return array ['add'=> 0, 'edit' => 0, 'fails' => 0] */ public function saveRemoteSgs($sgs, $user) @@ -173,7 +177,7 @@ class Cerebrate extends AppModel $outcome = [ 'add' => 0, 'edit' => 0, - 'fails' => 0 + 'fails' => 0, ]; foreach ($sgs as $sg) { $isEdit = false; @@ -191,27 +195,31 @@ class Cerebrate extends AppModel } } } + return $outcome; } - + /** * captureOrg - save or update an Org locally that comes from a Remote Cerebrate server * * @param array $org_data The Org array from the remote Cerebrate server * @param bool $edit Returns if the org was edited or not - * @param bool $noChange Returns + * @param bool $noChange Returns * @return string|array Error message or Organisation array */ - public function captureOrg($org_data, &$edit=false, &$noChange=false) + public function captureOrg($org_data, &$edit = false, &$noChange = false) { $org = $this->convertOrg($org_data); if ($org) { /** @var \App\Model\Table\OrganisationsTable $organisationTable */ $organisationTable = TableRegistry::getTableLocator()->get('Organisations'); - $existingOrg = $organisationTable->find('all', [ - 'recursive' => -1, - 'conditions' => ['uuid' => $org['uuid']] - ])->first(); + $existingOrg = $organisationTable->find( + 'all', + [ + 'recursive' => -1, + 'conditions' => ['uuid' => $org['uuid']], + ] + )->first(); if (!empty($existingOrg)) { $fieldsToSave = ['name', 'sector', 'nationality', 'type']; unset($org['uuid']); @@ -243,36 +251,48 @@ class Cerebrate extends AppModel } if ($dirty) { // verify if the name exists, if so generate a new name - $nameCheck = $organisationTable->find('all', [ - 'recursive' => -1, - 'conditions' => ['name' => $orgToSave->name], - 'fields' => ['id'] - ])->first(); + $nameCheck = $organisationTable->find( + 'all', + [ + 'recursive' => -1, + 'conditions' => ['name' => $orgToSave->name], + 'fields' => ['id'], + ] + )->first(); if (!empty($nameCheck)) { $orgToSave['name'] = $orgToSave['name'] . '_' . mt_rand(0, 9999); } // save the organisation $savedOrganisation = $organisationTable->save($orgToSave); if ($savedOrganisation) { - return $organisationTable->find('all', [ - 'recursive' => -1, - 'conditions' => ['id' => $savedOrganisation->id] - ])->first()->toArray(); + return $organisationTable->find( + 'all', + [ + 'recursive' => -1, + 'conditions' => ['id' => $savedOrganisation->id], + ] + )->first()->toArray(); } else { return __('The organisation could not be saved.'); } } else { $noChange = true; + return $existingOrg->toArray(); } } + return __('The retrieved data isn\'t a valid organisation.'); } - /* + /** + * checkRemoteOrgs * Checks remote for the current status of each organisation * Adds the exists_locally field with a boolean status * If exists_loally is true, adds a list with the differences (keynames) + * + * @param array $orgs orgs + * @return array */ public function checkRemoteOrgs($orgs) { @@ -281,9 +301,11 @@ class Cerebrate extends AppModel $organisationTable = TableRegistry::getTableLocator()->get('Organisations'); $existingOrgs = $organisationTable->find('all') ->where(['uuid']) - ->where(function (QueryExpression $exp, Query $q) use ($uuids) { - return $exp->in('uuid', array_values($uuids)); - }); + ->where( + function (QueryExpression $exp, Query $q) use ($uuids) { + return $exp->in('uuid', array_values($uuids)); + } + ); $rearranged = []; foreach ($existingOrgs as $existingOrg) { $rearranged[$existingOrg->uuid] = $existingOrg->toArray(); @@ -310,9 +332,17 @@ class Cerebrate extends AppModel } } } + return $orgs; } + /** + * __compareNames + * + * @param string $name1 orgname + * @param string $name2 orgname + * @return bool + */ private function __compareNames($name1, $name2) { if (preg_match('/\_[0-9]{4}$/i', $name1)) { @@ -322,9 +352,17 @@ class Cerebrate extends AppModel return false; } } + return false; } + /** + * __compareMembers + * + * @param array $existingMembers members + * @param array $remoteMembers members + * @return bool + */ private function __compareMembers($existingMembers, $remoteMembers) { $memberFound = []; @@ -342,13 +380,18 @@ class Cerebrate extends AppModel $memberNotFound[] = $remoteMember['uuid']; } } + return empty($memberNotFound); } - /* - * Checks remote for the current status of each sharing groups - * Adds the exists_locally field with a boolean status - * If exists_loally is true, adds a list with the differences (keynames) + /** + * checkRemoteSharingGroups + * Checks remote for the current status of each sharing groups + * Adds the exists_locally field with a boolean status + * If exists_loally is true, adds a list with the differences (keynames) + * + * @param array $sgs SharingGroups + * @return array */ public function checkRemoteSharingGroups($sgs) { @@ -356,11 +399,13 @@ class Cerebrate extends AppModel $sharingGroupTable = TableRegistry::getTableLocator()->get('SharingGroups'); $uuids = Hash::extract($sgs, '{n}.uuid'); $existingSgs = $sharingGroupTable->find('all') - ->contain(['SharingGroupOrgs'=> 'Organisations', 'Organisations']) + ->contain(['SharingGroupOrgs' => 'Organisations', 'Organisations']) ->where(['SharingGroups.uuid']) - ->where(function (QueryExpression $exp, Query $q) use ($uuids) { - return $exp->in('SharingGroups.uuid', array_values($uuids)); - }); + ->where( + function (QueryExpression $exp, Query $q) use ($uuids) { + return $exp->in('SharingGroups.uuid', array_values($uuids)); + } + ); $rearranged = []; foreach ($existingSgs as $existingSg) { $existingSg = $existingSg->toArray(); @@ -375,9 +420,17 @@ class Cerebrate extends AppModel $sgs[$k]['differences'] = $this->compareSgs($rearranged[$sg['uuid']], $sgs[$k]); } } + return $sgs; } + /** + * compareSgs + * + * @param array $existingSg existing SharingGroup + * @param array $remoteSg remote Sharing Group + * @return array + */ private function compareSgs($existingSg, $remoteSg) { $differences = []; @@ -399,25 +452,32 @@ class Cerebrate extends AppModel if (!$this->__compareMembers(Hash::extract($existingSg['SharingGroupOrg'], '{n}.Organisation'), $remoteSg['sharing_group_orgs'])) { $differences[] = 'members'; } + return $differences; } + /** + * convertSg + * + * @param array $sg_data Sharing Group data + * @return array + */ private function convertSg($sg_data) { $mapping = [ 'name' => [ 'field' => 'name', - 'required' => 1 + 'required' => 1, ], 'uuid' => [ 'field' => 'uuid', - 'required' => 1 + 'required' => 1, ], 'releasability' => [ - 'field' => 'releasability' + 'field' => 'releasability', ], 'description' => [ - 'field' => 'description' + 'field' => 'description', ], ]; $sg = []; @@ -442,24 +502,26 @@ class Cerebrate extends AppModel $sg['SharingGroupOrg'][$k]['extend'] = false; } foreach ($org as $ok => $ov) { - if ($ov === null) unset($sg['SharingGroupOrg'][$k][$ok]); + if ($ov === null) { + unset($sg['SharingGroupOrg'][$k][$ok]); + } } } } + return $sg; } - /** * captureSg * - * @param array $sg_data - * @param App\Model\Entity\User $user - * @param bool $edit - * @param bool $noChange - * @return mixed + * @param array $sg_data Sharing Group data + * @param \App\Model\Entity\User $user user + * @param bool $edit data was changed or not + * @param bool $noChange noChange + * @return string|array */ - public function captureSg($sg_data, $user, &$edit=false, &$noChange=false) + public function captureSg($sg_data, $user, &$edit = false, &$noChange = false) { /** @var \App\Model\Table\SharingGroupsTable $sharingGroupTable */ $sharingGroupTable = TableRegistry::getTableLocator()->get('SharingGroups'); @@ -472,12 +534,15 @@ class Cerebrate extends AppModel $captureResult = $sharingGroupTable->captureSG($sg, $user->toArray(), false); if (!empty($captureResult)) { $savedSg = $sharingGroupTable->findById($captureResult) - ->contain(['SharingGroupOrgs'=> 'Organisations', 'Organisations']) + ->contain(['SharingGroupOrgs' => 'Organisations', 'Organisations']) ->first(); + return $savedSg->toArray(); } + return __('The organisation could not be saved.'); } + return __('The retrieved data isn\'t a valid sharing group.'); } } diff --git a/src/Model/Table/CerebratesTable.php b/src/Model/Table/CerebratesTable.php index 2df55be52..0adfb5cee 100644 --- a/src/Model/Table/CerebratesTable.php +++ b/src/Model/Table/CerebratesTable.php @@ -1,13 +1,8 @@ false, 'cascadeCallbacks' => false, 'foreignKey' => 'org_id', - 'propertyName' => 'Organisation' + 'propertyName' => 'Organisation', ] ); diff --git a/templates/Cerebrates/add.php b/templates/Cerebrates/add.php index ef2f689cc..ef0f1706f 100644 --- a/templates/Cerebrates/add.php +++ b/templates/Cerebrates/add.php @@ -4,29 +4,29 @@ $edit = $this->request->getParam('action') === 'edit' ? true : false; $fields = [ [ 'field' => 'name', - 'class' => 'span6' + 'class' => 'span6', ], [ 'field' => 'url', - 'class' => 'span6' + 'class' => 'span6', ], [ 'field' => 'authkey', 'class' => 'span6', 'autocomplete' => 'off', - 'type' => 'text' + 'type' => 'text', ], [ 'field' => 'org_id', 'label' => 'Owner Organisation', 'options' => $dropdownData['org_id'], 'class' => 'span6', - 'type' => 'dropdown' + 'type' => 'dropdown', ], [ 'field' => 'description', 'type' => 'textarea', - 'class' => 'input span6' + 'class' => 'input span6', ], [ 'field' => 'pull_orgs', @@ -37,17 +37,20 @@ $fields = [ 'field' => 'pull_sharing_groups', 'label' => __('Pull Sharing Groups'), 'type' => 'checkbox', - ] + ], ]; -echo $this->element('genericElements/Form/genericForm', [ - 'data' => [ - 'description' => false, - 'model' => 'Cerebrate', - 'title' => $edit ? __('Edit Cerebrate connection') : __('Add Cerebrate connection'), - 'fields' => $fields, - 'submit' => [ - 'action' => $this->request->getParam('action'), - 'ajaxSubmit' => 'submitGenericFormInPlace();' - ] +echo $this->element( + 'genericElements/Form/genericForm', + [ + 'data' => [ + 'description' => false, + 'model' => 'Cerebrate', + 'title' => $edit ? __('Edit Cerebrate connection') : __('Add Cerebrate connection'), + 'fields' => $fields, + 'submit' => [ + 'action' => $this->request->getParam('action'), + 'ajaxSubmit' => 'submitGenericFormInPlace();', + ], + ], ] -]); +); diff --git a/templates/Cerebrates/index.php b/templates/Cerebrates/index.php index a499389c2..509c396e8 100644 --- a/templates/Cerebrates/index.php +++ b/templates/Cerebrates/index.php @@ -1,111 +1,113 @@ __('ID'), - 'sort' => 'id', - 'class' => 'short', - 'data_path' => 'id' - ], - [ - 'name' => __('Owner Org'), - 'sort' => 'Organisation', - 'data_path' => 'Organisation', - 'element' => 'org' - ], - [ - 'name' => __('Name'), - 'sort' => 'name', - 'data_path' => 'name' - ], - [ - 'name' => __('URL'), - 'sort' => 'url', - 'data_path' => 'url' - ], - [ - 'name' => __('Description'), - 'sort' => 'description', - 'data_path' => 'description' - ], - [ - 'name' => __('Pull Orgs'), - 'sort' => 'pull_orgs', - 'data_path' => 'pull_orgs', - 'element' => 'boolean' - ], - [ - 'name' => __('Pull SGs'), - 'sort' => 'pull_sharing_groups', - 'data_path' => 'pull_sharing_groups', - 'element' => 'boolean' - ] - ]; +$fields = [ + [ + 'name' => __('ID'), + 'sort' => 'id', + 'class' => 'short', + 'data_path' => 'id', + ], + [ + 'name' => __('Owner Org'), + 'sort' => 'Organisation', + 'data_path' => 'Organisation', + 'element' => 'org', + ], + [ + 'name' => __('Name'), + 'sort' => 'name', + 'data_path' => 'name', + ], + [ + 'name' => __('URL'), + 'sort' => 'url', + 'data_path' => 'url', + ], + [ + 'name' => __('Description'), + 'sort' => 'description', + 'data_path' => 'description', + ], + [ + 'name' => __('Pull Orgs'), + 'sort' => 'pull_orgs', + 'data_path' => 'pull_orgs', + 'element' => 'boolean', + ], + [ + 'name' => __('Pull SGs'), + 'sort' => 'pull_sharing_groups', + 'data_path' => 'pull_sharing_groups', + 'element' => 'boolean', + ], +]; -echo $this->element('genericElements/IndexTable/index_table', [ - 'data' => [ - 'data' => $data, - 'top_bar' => [ - 'children' => [ - [ - 'type' => 'simple', - 'children' => [ - 'data' => [ - 'type' => 'simple', - 'icon' => 'plus', - 'text' => __('Add Cerebrate'), - 'class' => 'btn btn-primary', - 'popover_url' => '/cerebrates/add', - 'button' => [ +echo $this->element( + 'genericElements/IndexTable/index_table', + [ + 'data' => [ + 'data' => $data, + 'top_bar' => [ + 'children' => [ + [ + 'type' => 'simple', + 'children' => [ + 'data' => [ + 'type' => 'simple', 'icon' => 'plus', - ] - ] - ] + 'text' => __('Add Cerebrate'), + 'class' => 'btn btn-primary', + 'popover_url' => '/cerebrates/add', + 'button' => [ + 'icon' => 'plus', + ], + ], + ], + ], + [ + 'type' => 'search', + 'button' => __('Search'), + 'placeholder' => __('Enter value to search'), + 'data' => '', + 'searchKey' => 'value', + 'allowFilering' => true, + ], + [ + 'type' => 'table_action', + ], + ], + ], + 'fields' => $fields, + 'title' => __('Linked Cerebrates'), + 'description' => __('You can connect your MISP to one or several Cerebrate instances to act as lookup directories for organisation and sharing group information.'), + 'actions' => [ + [ + 'url' => '/cerebrates/view', + 'url_params_data_paths' => ['id'], + 'icon' => 'eye', ], [ - 'type' => 'search', - 'button' => __('Search'), - 'placeholder' => __('Enter value to search'), - 'data' => '', - 'searchKey' => 'value', - 'allowFilering' => true + 'open_modal' => '/cerebrates/pull_orgs/[onclick_params_data_path]', + 'onclick_params_data_path' => 'id', + 'title' => __('Pull all organisations'), + 'icon' => 'arrow-circle-down', ], [ - 'type' => 'table_action', + 'open_modal' => '/cerebrates/pull_sgs/[onclick_params_data_path]', + 'onclick_params_data_path' => 'id', + 'title' => __('Pull all sharing groups'), + 'icon' => 'arrow-circle-down', ], - ] + [ + 'open_modal' => '/cerebrates/edit/[onclick_params_data_path]', + 'modal_params_data_path' => 'id', + 'icon' => 'edit', + ], + [ + 'open_modal' => '/cerebrates/delete/[onclick_params_data_path]', + 'modal_params_data_path' => 'id', + 'icon' => 'trash', + ], + ], ], - 'fields' => $fields, - 'title' => __('Linked Cerebrates'), - 'description' => __('You can connect your MISP to one or several Cerebrate instances to act as lookup directories for organisation and sharing group information.'), - 'actions' => [ - [ - 'url' => '/cerebrates/view', - 'url_params_data_paths' => ['id'], - 'icon' => 'eye' - ], - [ - 'open_modal' => '/cerebrates/pull_orgs/[onclick_params_data_path]', - 'onclick_params_data_path' => 'id', - 'title' => __('Pull all organisations'), - 'icon' => 'arrow-circle-down' - ], - [ - 'open_modal' => '/cerebrates/pull_sgs/[onclick_params_data_path]', - 'onclick_params_data_path' => 'id', - 'title' => __('Pull all sharing groups'), - 'icon' => 'arrow-circle-down' - ], - [ - 'open_modal' => '/cerebrates/edit/[onclick_params_data_path]', - 'modal_params_data_path' => 'id', - 'icon' => 'edit' - ], - [ - 'open_modal' => '/cerebrates/delete/[onclick_params_data_path]', - 'modal_params_data_path' => 'id', - 'icon' => 'trash' - ] - ] ] -]); - +); diff --git a/templates/Cerebrates/preview_orgs.php b/templates/Cerebrates/preview_orgs.php index efb463249..8e6017d7f 100644 --- a/templates/Cerebrates/preview_orgs.php +++ b/templates/Cerebrates/preview_orgs.php @@ -1,38 +1,40 @@ __('Id'), - 'sort' => 'id', - 'data_path' => 'id' - ], - [ - 'name' => __('Known locally'), - 'sort' => 'exists_locally', - 'element' => 'remote_status', - ], - [ - 'name' => __('UUID'), - 'sort' => 'uuid', - 'data_path' => 'uuid' - ], - [ - 'name' => __('Name'), - 'sort' => 'name', - 'data_path' => 'name' - ], - [ - 'name' => __('Sector'), - 'sort' => 'sector', - 'data_path' => 'sector' - ], - [ - 'name' => __('Nationality'), - 'sort' => 'nationality', - 'data_path' => 'nationality' - ] - ]; +$fields = [ + [ + 'name' => __('Id'), + 'sort' => 'id', + 'data_path' => 'id', + ], + [ + 'name' => __('Known locally'), + 'sort' => 'exists_locally', + 'element' => 'remote_status', + ], + [ + 'name' => __('UUID'), + 'sort' => 'uuid', + 'data_path' => 'uuid', + ], + [ + 'name' => __('Name'), + 'sort' => 'name', + 'data_path' => 'name', + ], + [ + 'name' => __('Sector'), + 'sort' => 'sector', + 'data_path' => 'sector', + ], + [ + 'name' => __('Nationality'), + 'sort' => 'nationality', + 'data_path' => 'nationality', + ], +]; - echo $this->element('genericElements/IndexTable/index_table', [ +echo $this->element( + 'genericElements/IndexTable/index_table', + [ 'data' => [ 'data' => $data, 'top_bar' => [ @@ -44,37 +46,38 @@ 'placeholder' => __('Enter value to search'), 'data' => '', 'preserve_url_params' => [$cerebrate['id']], - 'searchKey' => 'quickFilter' - ] - ] + 'searchKey' => 'quickFilter', + ], + ], ], 'fields' => $fields, 'title' => empty($ajax) ? __( - 'Organisations list via Cerebrate {0} ({1})', - h($cerebrate['id']), - h($cerebrate['name']) - ) : false, + 'Organisations list via Cerebrate {0} ({1})', + h($cerebrate['id']), + h($cerebrate['name']) + ) : false, 'description' => empty($ajax) ? __('Preview of the organisations known to the remote Cerebrate instance.') : false, 'actions' => [ [ 'onclick' => sprintf( - 'openGenericModal(\'{0}/cerebrates/download_org/{1}/[onclick_params_data_path]\');', + 'openGenericModal(\'%s/cerebrates/download_org/%d/[onclick_params_data_path]\');', $baseurl, h($cerebrate['id']) ), 'onclick_params_data_path' => 'id', 'icon' => 'download', - 'title' => __('Fetch organisation object') - ] + 'title' => __('Fetch organisation object'), + ], ], 'paginatorOptions' => array_merge( ['url' => [$cerebrate['id']]], $passedParams ), - 'persistUrlParams' => [0, 'quickFilter'] + 'persistUrlParams' => [0, 'quickFilter'], ], - 'containerId' => 'preview_orgs_container' - ]); + 'containerId' => 'preview_orgs_container', + ] +); ?>