diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index 4ebc674..0adfcdf 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -442,6 +442,12 @@ class CRUDComponent extends Component if (empty($data)) { throw new NotFoundException(__('Invalid {0}.', $this->ObjectAlias)); } + if (isset($params['beforeSave'])) { + $data = $params['beforeSave']($data); + if ($data === false) { + throw new NotFoundException(__('Could not save {0} due to the input failing to meet expectations. Your input is bad and you should feel bad.', $this->ObjectAlias)); + } + } $this->Controller->set('id', $data['id']); $this->Controller->set('data', $data); $this->Controller->set('bulkEnabled', false); @@ -453,6 +459,7 @@ class CRUDComponent extends Component $isBulk = count($ids) > 1; $bulkSuccesses = 0; foreach ($ids as $id) { + $skipExecution = false; $data = $this->Table->find()->where([$this->Table->getAlias() . '.id' => $id]); if (!empty($params['conditions'])) { $data->where($params['conditions']); @@ -460,15 +467,24 @@ class CRUDComponent extends Component if (!empty($params['contain'])) { $data->contain($params['contain']); } - $data = $data->first(); - if (!empty($data)) { - $success = $this->Table->delete($data); - $success = true; - } else { - $success = false; + if (isset($params['beforeSave'])) { + $data = $params['beforeSave']($data); + if ($data === false) { + $skipExecution = true; + $success = false; + } } - if ($success) { - $bulkSuccesses++; + if (!$skipExecution) { + $data = $data->first(); + if (!empty($data)) { + $success = $this->Table->delete($data); + $success = true; + } else { + $success = false; + } + if ($success) { + $bulkSuccesses++; + } } } $message = $this->getMessageBasedOnResult( diff --git a/src/Controller/EncryptionKeysController.php b/src/Controller/EncryptionKeysController.php index e04ebc0..324decb 100644 --- a/src/Controller/EncryptionKeysController.php +++ b/src/Controller/EncryptionKeysController.php @@ -57,47 +57,45 @@ class EncryptionKeysController extends AppController private function buildBeforeSave(array $params, $currentUser, array &$orgConditions, array &$individualConditions, array &$dropdownData): array { - $orgConditions = [ - 'id' => $currentUser['organisation_id'] - ]; - if (empty($currentUser['role']['perm_org_admin'])) { - $individualConditions = [ - 'id' => $currentUser['individual_id'] + if (empty($currentUser['role']['perm_admin'])) { + $orgConditions = [ + 'id' => $currentUser['organisation_id'] ]; - } - $params['beforeSave'] = function($entity) use($currentUser) { - if ($entity['owner_model'] === 'organisation') { - $entity['owner_id'] = $currentUser['organisation_id']; - } else { - if ($currentUser['role']['perm_org_admin']) { - $this->loadModel('Alignments'); - $validIndividuals = $this->Alignments->find('list', [ - 'keyField' => 'individual_id', - 'valueField' => 'id', - 'conditions' => ['organisation_id' => $currentUser['organisation_id']] - ])->toArray(); - if (!isset($validIndividuals[$entity['owner_id']])) { - throw new MethodNotAllowedException(__('Selected individual cannot be linked by the current user.')); + if (empty($currentUser['role']['perm_org_admin'])) { + $individualConditions = [ + 'id' => $currentUser['individual_id'] + ]; + } + $params['beforeSave'] = function($entity) use($currentUser) { + if ($entity['owner_model'] === 'organisation') { + if ($entity['owner_id'] !== $currentUser['organisation_id']) { + throw new MethodNotAllowedException(__('Selected organisation cannot be linked by the current user.')); } } else { - if ($entity['owner_id'] !== $currentUser['id']) { - throw new MethodNotAllowedException(__('Selected individual cannot be linked by the current user.')); + if ($currentUser['role']['perm_org_admin']) { + $this->loadModel('Alignments'); + $validIndividuals = $this->Alignments->find('list', [ + 'keyField' => 'individual_id', + 'valueField' => 'id', + 'conditions' => ['organisation_id' => $currentUser['organisation_id']] + ])->toArray(); + if (!isset($validIndividuals[$entity['owner_id']])) { + throw new MethodNotAllowedException(__('Selected individual cannot be linked by the current user.')); + } + } else { + if ($entity['owner_id'] !== $currentUser['id']) { + throw new MethodNotAllowedException(__('Selected individual cannot be linked by the current user.')); + } } } - } - return $entity; - }; + return $entity; + }; + } $this->loadModel('Organisations'); $this->loadModel('Individuals'); $dropdownData = [ - 'organisation' => $this->Organisations->find('list', [ - 'sort' => ['name' => 'asc'], - 'conditions' => $orgConditions - ]), - 'individual' => $this->Individuals->find('list', [ - 'sort' => ['email' => 'asc'], - 'conditions' => $individualConditions - ]) + 'organisation' => $this->Organisations->find('list')->order(['name' => 'asc'])->where($orgConditions)->all()->toArray(), + 'individual' => $this->Individuals->find('list')->order(['email' => 'asc'])->where($individualConditions)->all()->toArray() ]; return $params; } @@ -111,9 +109,7 @@ class EncryptionKeysController extends AppController $params = [ 'redirect' => $this->referer() ]; - if (empty($currentUser['role']['perm_admin'])) { - $params = $this->buildBeforeSave($params, $currentUser, $orgConditions, $individualConditions, $dropdownData); - } + $params = $this->buildBeforeSave($params, $currentUser, $orgConditions, $individualConditions, $dropdownData); $this->CRUD->add($params); $responsePayload = $this->CRUD->getResponsePayload(); if (!empty($responsePayload)) { diff --git a/src/Lib/default/local_tool_connectors/CommonConnectorTools.php b/src/Lib/default/local_tool_connectors/CommonConnectorTools.php index 179a238..213db17 100644 --- a/src/Lib/default/local_tool_connectors/CommonConnectorTools.php +++ b/src/Lib/default/local_tool_connectors/CommonConnectorTools.php @@ -2,6 +2,8 @@ namespace CommonConnectorTools; use Cake\ORM\Locator\LocatorAwareTrait; +use Cake\Log\Log; +use Cake\Log\Engine\FileLog; class CommonConnectorTools { @@ -20,6 +22,35 @@ class CommonConnectorTools const STATE_CANCELLED = 'Request cancelled'; const STATE_DECLINED = 'Request declined by remote'; + public function __construct() + { + Log::setConfig("LocalToolDebug", [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => "{$this->connectorName}-debug", + 'scopes' => [$this->connectorName], + 'levels' => ['notice', 'info', 'debug'], + ]); + Log::setConfig("LocalToolError", [ + 'className' => FileLog::class, + 'path' => LOGS, + 'file' => "{$this->connectorName}-error", + 'scopes' => [$this->connectorName], + 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], + ]); + + } + + protected function logDebug($message) + { + Log::debug($message, [$this->connectorName]); + } + + protected function logError($message, $scope=[]) + { + Log::error($message, [$this->connectorName]); + } + public function addExposedFunction(string $functionName): void { $this->exposedFunctions[] = $functionName; diff --git a/src/Lib/default/local_tool_connectors/MispConnector.php b/src/Lib/default/local_tool_connectors/MispConnector.php index a021839..4b6c653 100644 --- a/src/Lib/default/local_tool_connectors/MispConnector.php +++ b/src/Lib/default/local_tool_connectors/MispConnector.php @@ -188,6 +188,7 @@ class MispConnector extends CommonConnectorTools $settings = json_decode($connection->settings, true); $http = $this->genHTTPClient($connection, $options); $url = sprintf('%s%s', $settings['url'], $relativeURL); + $this->logDebug(sprintf('%s %s %s', __('Posting data') . PHP_EOL, "POST {$url}" . PHP_EOL, json_encode($data))); return $http->post($url, $data, $options); } @@ -239,14 +240,18 @@ class MispConnector extends CommonConnectorTools if (!empty($params['softError'])) { return $response; } - throw new NotFoundException(__('Could not retrieve the requested resource.')); + $errorMsg = __('Could not post to the requested resource for `{0}`. Remote returned:', $url) . PHP_EOL . $response->getStringBody(); + $this->logError($errorMsg); + throw new NotFoundException($errorMsg); } } private function postData(string $url, array $params): Response { if (empty($params['connection'])) { - throw new NotFoundException(__('No connection object received.')); + $errorMsg = __('No connection object received.'); + $this->logError($errorMsg); + throw new NotFoundException($errorMsg); } $url = $this->urlAppendParams($url, $params); if (!is_string($params['body'])) { @@ -256,7 +261,9 @@ class MispConnector extends CommonConnectorTools if ($response->isOk()) { return $response; } else { - throw new NotFoundException(__('Could not post to the requested resource. Remote returned:') . PHP_EOL . $response->getStringBody()); + $errorMsg = __('Could not post to the requested resource for `{0}`. Remote returned:', $url) . PHP_EOL . $response->getStringBody(); + $this->logError($errorMsg); + throw new NotFoundException($errorMsg); } }