mirror of https://github.com/MISP/MISP
Merge branch '3.x' into feature/3.x_HttpTool
commit
3927609cb6
|
@ -158,15 +158,15 @@ class ACLComponent extends Component
|
|||
'view' => ['perm_admin'],
|
||||
],
|
||||
'Organisations' => [
|
||||
'add' => ['perm_admin'],
|
||||
'delete' => ['perm_admin'],
|
||||
'edit' => ['perm_admin'],
|
||||
'add' => ['perm_site_admin'],
|
||||
'delete' => ['perm_site_admin'],
|
||||
'edit' => ['perm_site_admin', 'perm_admin'],
|
||||
'filtering' => ['*'],
|
||||
'index' => ['*'],
|
||||
'tag' => ['perm_tagger'],
|
||||
'untag' => ['perm_tagger'],
|
||||
'tag' => ['AND' => ['perm_tagger', 'OR' => ['perm_site_admin', 'perm_admin']]],
|
||||
'untag' => ['AND' => ['perm_tagger', 'OR' => ['perm_site_admin', 'perm_admin']]],
|
||||
'view' => ['*'],
|
||||
'viewTags' => ['*']
|
||||
'viewTags' => ['*'],
|
||||
],
|
||||
'Outbox' => [
|
||||
'createEntry' => ['perm_admin'],
|
||||
|
@ -506,7 +506,7 @@ class ACLComponent extends Component
|
|||
// we have to be in a publically allowed scope otherwise the Auth component will kick us out anyway.
|
||||
return true;
|
||||
}
|
||||
if (!empty($this->user->Role->perm_admin)) {
|
||||
if (!empty($this->user->Role->perm_site_admin)) {
|
||||
return true;
|
||||
}
|
||||
//$this->__checkLoggedActions($user, $controller, $action);
|
||||
|
@ -700,7 +700,7 @@ class ACLComponent extends Component
|
|||
}
|
||||
foreach ($this->aclList as $controller => $actions) {
|
||||
foreach ($actions as $action => $permissions) {
|
||||
if ($role['perm_admin']) {
|
||||
if ($role['perm_site_admin']) {
|
||||
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
|
||||
} elseif (in_array('*', $permissions)) {
|
||||
$results = $this->__formatControllerAction($results, $controller, $action, $url_mode);
|
||||
|
|
|
@ -424,7 +424,7 @@ class CRUDComponent extends Component
|
|||
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));
|
||||
}
|
||||
}
|
||||
$savedData = $this->Table->save($data);
|
||||
$savedData = $this->Table->save($data); // FIXME catch exceptions thrown by DB constraints, as otherwise we get 500 Internal Server Errors
|
||||
if ($savedData !== false) {
|
||||
if (isset($params['afterSave'])) {
|
||||
$params['afterSave']($data);
|
||||
|
@ -458,7 +458,7 @@ class CRUDComponent extends Component
|
|||
);
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
$this->Controller->restResponsePayload = $this->RestResponse->viewData($message, 'json');
|
||||
} else if ($this->Controller->ParamHandler->isAjax()) {
|
||||
} elseif ($this->Controller->ParamHandler->isAjax()) {
|
||||
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'add', $data, $message, $validationErrors);
|
||||
} else {
|
||||
$this->Controller->Flash->error($message);
|
||||
|
@ -715,32 +715,16 @@ class CRUDComponent extends Component
|
|||
$params['afterSave']($data);
|
||||
}
|
||||
$message = __('{0} `{1}` updated.', $this->ObjectAlias, $savedData->{$this->Table->getDisplayField()});
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
$this->Controller->restResponsePayload = $this->RestResponse->viewData($savedData, 'json');
|
||||
} else if ($this->Controller->ParamHandler->isAjax()) {
|
||||
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxSuccessResponse($this->ObjectAlias, 'edit', $savedData, $message);
|
||||
} else {
|
||||
$this->Controller->Flash->success($message);
|
||||
if (empty($params['redirect'])) {
|
||||
$this->Controller->redirect(['action' => 'view', $id]);
|
||||
} else {
|
||||
$this->Controller->redirect($params['redirect']);
|
||||
}
|
||||
}
|
||||
$this->setResponseForController('edit', true, $message, $data, null, $params);
|
||||
} else {
|
||||
$validationErrors = $data->getErrors();
|
||||
$validationMessage = $this->prepareValidationError($data);
|
||||
$validationMessage = $this->prepareValidationMessage($validationErrors);
|
||||
$message = __(
|
||||
'{0} could not be modified.{1}',
|
||||
$this->ObjectAlias,
|
||||
empty($validationMessage) ? '' : PHP_EOL . __('Reason: {0}', $validationMessage)
|
||||
);
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
} else if ($this->Controller->ParamHandler->isAjax()) {
|
||||
$this->Controller->ajaxResponsePayload = $this->RestResponse->ajaxFailResponse($this->ObjectAlias, 'edit', $data, $message, $validationErrors);
|
||||
} else {
|
||||
$this->Controller->Flash->error($message);
|
||||
}
|
||||
$this->setResponseForController('edit', false, $message, $data, null, $params);
|
||||
}
|
||||
}
|
||||
if (!empty($params['fields'])) {
|
||||
|
@ -1187,6 +1171,7 @@ class CRUDComponent extends Component
|
|||
} else {
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
$data = $data ?? $message;
|
||||
// FIXME show error in the JSON response, and return with an HTTP error code
|
||||
$this->Controller->restResponsePayload = $this->RestResponse->viewData($data, 'json');
|
||||
} elseif ($this->Controller->ParamHandler->isAjax()) {
|
||||
if (!empty($additionalData['redirect'])) { // If a redirection occurs, we need to make sure the flash message gets displayed
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
use Cake\Utility\Hash;
|
||||
use Cake\Utility\Text;
|
||||
use Cake\Database\Expression\QueryExpression;
|
||||
use Cake\Http\Exception\NotFoundException;
|
||||
use App\Model\Entity\Organisation;
|
||||
use Cake\Http\Exception\MethodNotAllowedException;
|
||||
use Cake\Http\Exception\ForbiddenException;
|
||||
|
||||
class OrganisationsController extends AppController
|
||||
{
|
||||
|
||||
public $quickFilterFields = [['name' => true], 'uuid', 'nationality', 'sector', 'type', 'url', 'local'];
|
||||
public $filterFields = [
|
||||
'name', 'uuid', 'nationality', 'sector', 'type', 'url', 'local'
|
||||
'name', 'uuid', 'nationality', 'sector', 'type', 'url', 'local',
|
||||
];
|
||||
public $containFields = [];
|
||||
public $statisticsFields = ['nationality', 'sector'];
|
||||
|
||||
/**
|
||||
* Display the list of organizations.
|
||||
*
|
||||
* @return \Cake\Http\Response|null
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$customContextFilters = [
|
||||
[
|
||||
'label' => __('Local orgs'),
|
||||
'filterCondition' => ['local' => 1]
|
||||
'filterCondition' => ['local' => 1],
|
||||
],
|
||||
[
|
||||
'label' => __('External orgs'),
|
||||
'filterCondition' => ['local' => 0]
|
||||
]
|
||||
'filterCondition' => ['local' => 0],
|
||||
],
|
||||
];
|
||||
$loggedUserOrganisationNationality = $this->ACL->getUser()['Organisation']['nationality'];
|
||||
if (!empty($loggedUserOrganisationNationality)) {
|
||||
|
@ -38,54 +38,79 @@ class OrganisationsController extends AppController
|
|||
'label' => __('Country: {0}', $loggedUserOrganisationNationality),
|
||||
'filterCondition' => [
|
||||
'nationality' => $loggedUserOrganisationNationality,
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$this->CRUD->index([
|
||||
'filters' => $this->filterFields,
|
||||
'quickFilters' => $this->quickFilterFields,
|
||||
'quickFilterForMetaField' => ['enabled' => true, 'wildcard_search' => true],
|
||||
'contextFilters' => [
|
||||
'custom' => $customContextFilters,
|
||||
],
|
||||
'afterFind' => function($entity) {
|
||||
$entity->setVirtual(['user_count']);
|
||||
return $entity;
|
||||
},
|
||||
'contain' => $this->containFields,
|
||||
'statisticsFields' => $this->statisticsFields,
|
||||
]);
|
||||
$this->CRUD->index(
|
||||
[
|
||||
'filters' => $this->filterFields,
|
||||
'quickFilters' => $this->quickFilterFields,
|
||||
'quickFilterForMetaField' => ['enabled' => true, 'wildcard_search' => true],
|
||||
'contextFilters' => [
|
||||
'custom' => $customContextFilters,
|
||||
],
|
||||
'afterFind' => function ($entity) {
|
||||
$entity->setVirtual(['user_count']);
|
||||
|
||||
return $entity;
|
||||
},
|
||||
'contain' => $this->containFields,
|
||||
'statisticsFields' => $this->statisticsFields,
|
||||
]
|
||||
);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtering function.
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$this->CRUD->filtering();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new organization.
|
||||
*
|
||||
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->CRUD->add();
|
||||
$params = [
|
||||
'beforeSave' => function (Organisation $org) {
|
||||
$org['created_by'] = $this->ACL->getUser()['id'];
|
||||
|
||||
return $org;
|
||||
},
|
||||
];
|
||||
$this->CRUD->add($params);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
$this->set('countries',
|
||||
$this->set(
|
||||
'countries',
|
||||
array_merge(
|
||||
[
|
||||
'' => __('Not specified')
|
||||
'' => __('Not specified'),
|
||||
],
|
||||
//$this->_arrayToValuesIndexArray($this->Organisation->getCountries())
|
||||
)
|
||||
),
|
||||
);
|
||||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
||||
public function view($id)
|
||||
/**
|
||||
* View an organization.
|
||||
*
|
||||
* @param int $id The ID of the organization.
|
||||
* @return \Cake\Http\Response|null The response payload.
|
||||
*/
|
||||
public function view(int $id)
|
||||
{
|
||||
$this->CRUD->view($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
|
@ -95,15 +120,24 @@ class OrganisationsController extends AppController
|
|||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
/**
|
||||
* Edit an organization.
|
||||
*
|
||||
* @param int $id The ID of the organization.
|
||||
* @return \Cake\Http\Response|null The response payload.
|
||||
*/
|
||||
public function edit(int $id)
|
||||
{
|
||||
$currentUser = $this->ACL->getUser();
|
||||
if (
|
||||
!($currentUser['Organisation']['id'] == $id && $currentUser['Role']['perm_org_admin']) &&
|
||||
!$currentUser['Role']['perm_admin']
|
||||
!(
|
||||
$currentUser['Role']['perm_site_admin'] ||
|
||||
($currentUser['Organisation']['id'] == $id && $currentUser['Role']['perm_admin'])
|
||||
)
|
||||
) {
|
||||
throw new MethodNotAllowedException(__('You cannot modify that organisation.'));
|
||||
}
|
||||
// FIXME prevent change of the created_by field
|
||||
$this->CRUD->edit($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
|
@ -113,7 +147,13 @@ class OrganisationsController extends AppController
|
|||
$this->render('add');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
/**
|
||||
* Delete an organization.
|
||||
*
|
||||
* @param int $id The ID of the organization.
|
||||
* @return \Cake\Http\Response|null The response payload.
|
||||
*/
|
||||
public function delete(int $id)
|
||||
{
|
||||
$this->CRUD->delete($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
|
@ -123,30 +163,48 @@ class OrganisationsController extends AppController
|
|||
$this->set('metaGroup', 'ContactDB');
|
||||
}
|
||||
|
||||
public function tag($id)
|
||||
{
|
||||
$this->CRUD->tag($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * Tag an organization.
|
||||
// *
|
||||
// * @param int $id The ID of the organization.
|
||||
// * @return \Cake\Http\Response|null The response payload.
|
||||
// */
|
||||
// public function tag(int $id)
|
||||
// {
|
||||
// $this->CRUD->tag($id);
|
||||
// $responsePayload = $this->CRUD->getResponsePayload();
|
||||
// if (!empty($responsePayload)) {
|
||||
// return $responsePayload;
|
||||
// }
|
||||
// }
|
||||
|
||||
public function untag($id)
|
||||
{
|
||||
$this->CRUD->untag($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * Untag an organization.
|
||||
// *
|
||||
// * @param int $id The ID of the organization.
|
||||
// * @return \Cake\Http\Response|null The response payload.
|
||||
// */
|
||||
// public function untag(int $id)
|
||||
// {
|
||||
// $this->CRUD->untag($id);
|
||||
// $responsePayload = $this->CRUD->getResponsePayload();
|
||||
// if (!empty($responsePayload)) {
|
||||
// return $responsePayload;
|
||||
// }
|
||||
// }
|
||||
|
||||
public function viewTags($id)
|
||||
{
|
||||
$this->CRUD->viewTags($id);
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * View tags for an organization.
|
||||
// *
|
||||
// * @param int $id The ID of the organization.
|
||||
// * @return \Cake\Http\Response|null The response payload.
|
||||
// */
|
||||
// public function viewTags(int $id)
|
||||
// {
|
||||
// $this->CRUD->viewTags($id);
|
||||
// $responsePayload = $this->CRUD->getResponsePayload();
|
||||
// if (!empty($responsePayload)) {
|
||||
// return $responsePayload;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -535,7 +535,7 @@ class SharingGroupsController extends AppController
|
|||
return $sg;
|
||||
}
|
||||
|
||||
private function __initialiseSGQuickEditObject($id, $request, $type = 'org')
|
||||
private function __initialiseSGQuickEditObject(int $id, $request, $type = 'org')
|
||||
{
|
||||
$params = [
|
||||
'org' => [
|
||||
|
|
|
@ -1,18 +1,62 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model\Behavior;
|
||||
|
||||
use Cake\ORM\Behavior;
|
||||
use Cake\Event\EventInterface;
|
||||
use Cake\Datasource\EntityInterface;
|
||||
use ArrayObject;
|
||||
use Cake\Datasource\EntityInterface;
|
||||
use Cake\Event\EventInterface;
|
||||
use Cake\ORM\Behavior;
|
||||
use Cake\Utility\Text;
|
||||
use Cake\Validation\Validator;
|
||||
|
||||
class UUIDBehavior extends Behavior
|
||||
{
|
||||
/**
|
||||
* beforeSave
|
||||
*
|
||||
* @param \Cake\Event\EventInterface $event the efent
|
||||
* @param \Cake\Datasource\EntityInterface; $entity the entity
|
||||
* @param array $options extra options
|
||||
* @return void
|
||||
*/
|
||||
public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options)
|
||||
{
|
||||
if ($entity->isNew() && empty($entity['uuid'])) {
|
||||
$entity['uuid'] = Text::uuid();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* buildValidator
|
||||
*
|
||||
* @param \Cake\Event\EventInterface $event the event
|
||||
* @param \Cake\Validation\Validator $validator the validator
|
||||
* @param string $name the string to validate
|
||||
* @return \Cake\Validation\Validator
|
||||
*/
|
||||
public function buildValidator(EventInterface $event, Validator $validator, string $name)
|
||||
{
|
||||
$validator
|
||||
->notEmptyString('uuid')
|
||||
->add(
|
||||
'uuid',
|
||||
'valid',
|
||||
[
|
||||
'rule' => 'uuid',
|
||||
'message' => 'The UUID is not valid',
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'uuid',
|
||||
'unique',
|
||||
[
|
||||
'rule' => 'validateUnique',
|
||||
'provider' => 'table',
|
||||
'message' => 'The UUID name must be unique.',
|
||||
]
|
||||
);
|
||||
|
||||
return $validator;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model\Table;
|
||||
|
||||
use App\Model\Table\AppTable;
|
||||
use ArrayObject;
|
||||
use Cake\Datasource\EntityInterface;
|
||||
use Cake\Event\EventInterface;
|
||||
|
@ -11,6 +11,12 @@ use Cake\Validation\Validator;
|
|||
|
||||
class OrganisationsTable extends AppTable
|
||||
{
|
||||
/**
|
||||
* Initialize method.
|
||||
*
|
||||
* @param array $config The configuration for the table.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(array $config): void
|
||||
{
|
||||
parent::initialize($config);
|
||||
|
@ -23,42 +29,101 @@ class OrganisationsTable extends AppTable
|
|||
$this->setDisplayField('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method called before saving an entity.
|
||||
*
|
||||
* @param \Cake\Event\EventInterface $event The event instance.
|
||||
* @param \Cake\Datasource\EntityInterface $entity The entity being saved.
|
||||
* @param \ArrayObject $options The options passed to the save method.
|
||||
* @return void
|
||||
*/
|
||||
public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options)
|
||||
{
|
||||
if ($entity->isNew()) {
|
||||
$entity->date_created = date('Y-m-d H:i:s');
|
||||
}
|
||||
$entity->date_modified = date('Y-m-d H:i:s');
|
||||
return;
|
||||
// $entity->created_by = $this->ACL->getUser(); // FIXME force the value in the model, see also https://github.com/usemuffin/footprint
|
||||
}
|
||||
|
||||
/**
|
||||
* Default validation rules for the table.
|
||||
*
|
||||
* @param \Cake\Validation\Validator $validator The validator instance.
|
||||
* @return \Cake\Validation\Validator The updated validator instance.
|
||||
*/
|
||||
public function validationDefault(Validator $validator): Validator
|
||||
{
|
||||
$validator
|
||||
->notEmptyString('name')
|
||||
->notEmptyString('uuid')
|
||||
->requirePresence(['name', 'uuid'], 'create');
|
||||
->requirePresence(['name', 'uuid'], 'create')
|
||||
->add(
|
||||
'name',
|
||||
[
|
||||
'unique' => [
|
||||
'rule' => 'validateUnique',
|
||||
'provider' => 'table',
|
||||
'message' => 'The organisation name must be unique.',
|
||||
],
|
||||
'maxLength' => [
|
||||
'rule' => ['maxLength', 255],
|
||||
'message' => 'Name cannot be more than 255 chars.',
|
||||
],
|
||||
]
|
||||
)
|
||||
->add(
|
||||
'type',
|
||||
'maxLength',
|
||||
[
|
||||
'rule' => ['maxLength', 255],
|
||||
'message' => 'Type cannot be more than 255 chars.',
|
||||
],
|
||||
)
|
||||
->add(
|
||||
'nationality',
|
||||
'maxLength',
|
||||
[
|
||||
'rule' => ['maxLength', 255],
|
||||
'message' => 'Nationality cannot be more than 255 chars.',
|
||||
],
|
||||
)
|
||||
->add(
|
||||
'sector',
|
||||
'maxLength',
|
||||
[
|
||||
'rule' => ['maxLength', 255],
|
||||
'message' => 'Sector cannot be more than 255 chars.',
|
||||
],
|
||||
);
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture the organization.
|
||||
*
|
||||
* @param mixed $org The organization to capture.
|
||||
* @return int|null The captured organization ID, or null if capture failed.
|
||||
*/
|
||||
public function captureOrg($org): ?int
|
||||
{
|
||||
if (!empty($org['uuid'])) {
|
||||
$existingOrg = $this->find()->where(
|
||||
[
|
||||
'uuid' => $org['uuid']
|
||||
'uuid' => $org['uuid'],
|
||||
]
|
||||
)->first();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (empty($existingOrg)) {
|
||||
/** @var \App\Model\Entity\Organisation $entityToSave */
|
||||
$entityToSave = $this->newEmptyEntity();
|
||||
$this->patchEntity(
|
||||
$entityToSave,
|
||||
$org,
|
||||
[
|
||||
'accessibleFields' => $entityToSave->getAccessibleFieldForNew()
|
||||
'accessibleFields' => $entityToSave->getAccessibleFieldForNew(),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
|
@ -70,10 +135,17 @@ class OrganisationsTable extends AppTable
|
|||
if (!$savedEntity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $savedEntity->id;
|
||||
}
|
||||
|
||||
public function fetchOrg($id)
|
||||
/**
|
||||
* Fetches an organization by its ID.
|
||||
*
|
||||
* @param int $id The ID of the organization to fetch.
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOrg(int $id)
|
||||
{
|
||||
if (empty($id)) {
|
||||
return false;
|
||||
|
@ -87,10 +159,11 @@ class OrganisationsTable extends AppTable
|
|||
$org = $this->find(
|
||||
'all',
|
||||
[
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1
|
||||
'conditions' => $conditions,
|
||||
'recursive' => -1,
|
||||
]
|
||||
)->disableHydration()->first();
|
||||
return (empty($org)) ? false : $org;
|
||||
|
||||
return empty($org) ? false : $org;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class OrganisationsFixture extends TestFixture
|
|||
'contacts' => '',
|
||||
'description' => 'ORGANISATION A',
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
[
|
||||
'id' => self::ORGANISATION_B_ID,
|
||||
|
@ -48,7 +48,7 @@ class OrganisationsFixture extends TestFixture
|
|||
'contacts' => '',
|
||||
'description' => 'ORGANISATION B',
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
[
|
||||
'id' => self::ORGANISATION_C_ID,
|
||||
|
@ -61,8 +61,8 @@ class OrganisationsFixture extends TestFixture
|
|||
'contacts' => '',
|
||||
'description' => 'ORGANISATION C',
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
]
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
];
|
||||
parent::init();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class UsersFixture extends TestFixture
|
|||
'disabled' => 0,
|
||||
'org_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
[
|
||||
'id' => self::USER_SYNC_ID,
|
||||
|
@ -57,7 +57,7 @@ class UsersFixture extends TestFixture
|
|||
'disabled' => 0,
|
||||
'org_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
[
|
||||
'id' => self::USER_ORG_ADMIN_ID,
|
||||
|
@ -68,7 +68,7 @@ class UsersFixture extends TestFixture
|
|||
'disabled' => 0,
|
||||
'org_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
[
|
||||
'id' => self::USER_REGULAR_USER_ID,
|
||||
|
@ -79,8 +79,8 @@ class UsersFixture extends TestFixture
|
|||
'disabled' => 0,
|
||||
'org_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
'date_modified' => $faker->dateTime()->getTimestamp()
|
||||
]
|
||||
'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
],
|
||||
];
|
||||
parent::init();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\Helper;
|
||||
|
@ -23,28 +22,49 @@ trait ApiTestTrait
|
|||
IntegrationTestTrait::_sendRequest as _sendRequestOriginal;
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_authToken = '';
|
||||
|
||||
/** @var ValidatorBuilder */
|
||||
/**
|
||||
* @var ValidatorBuilder
|
||||
*/
|
||||
private $_validator;
|
||||
|
||||
/** @var RequestValidator */
|
||||
/**
|
||||
* @var RequestValidator
|
||||
*/
|
||||
private $_requestValidator;
|
||||
|
||||
/** @var ResponseValidator */
|
||||
/**
|
||||
* @var ResponseValidator
|
||||
*/
|
||||
private $_responseValidator;
|
||||
|
||||
/** @var ServerRequest */
|
||||
/**
|
||||
* @var ServerRequest
|
||||
*/
|
||||
protected $_psrRequest;
|
||||
|
||||
/** @var boolean */
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_skipOpenApiValidations = false;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->initializeOpenApiValidator();
|
||||
|
||||
$this->configRequest(
|
||||
[
|
||||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function setAuthToken(string $authToken): void
|
||||
|
@ -59,8 +79,8 @@ trait ApiTestTrait
|
|||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
'Authorization' => $this->_authToken,
|
||||
'Content-Type' => 'application/json'
|
||||
]
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +109,7 @@ trait ApiTestTrait
|
|||
public function initializeOpenApiValidator(): void
|
||||
{
|
||||
if (!$this->_skipOpenApiValidations) {
|
||||
$this->_validator = Configure::read('App.OpenAPIValidator');
|
||||
$this->_validator = Configure::read('App.OpenAPIValidator');
|
||||
if ($this->_validator === null) {
|
||||
throw new \Exception('OpenAPI validator is not configured');
|
||||
}
|
||||
|
@ -127,7 +147,6 @@ trait ApiTestTrait
|
|||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException
|
||||
*
|
||||
* @see https://book.cakephp.org/4/en/orm-query-builder.html
|
||||
*/
|
||||
public function assertDbRecordExists(string $table, array $conditions): void
|
||||
|
@ -147,7 +166,6 @@ trait ApiTestTrait
|
|||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws \Cake\Datasource\Exception\RecordNotFoundException
|
||||
*
|
||||
* @see https://book.cakephp.org/4/en/orm-query-builder.html
|
||||
*/
|
||||
public function assertDbRecordNotExists(string $table, array $conditions): void
|
||||
|
@ -191,8 +209,8 @@ trait ApiTestTrait
|
|||
* This method intercepts IntegrationTestTrait::_buildRequest()
|
||||
* in the quest to get a PSR-7 request object and saves it for
|
||||
* later inspection, also validates it against the OpenAPI spec.
|
||||
* @see \Cake\TestSuite\IntegrationTestTrait::_buildRequest()
|
||||
*
|
||||
* @see \Cake\TestSuite\IntegrationTestTrait::_buildRequest()
|
||||
* @param string $url The URL
|
||||
* @param string $method The HTTP method
|
||||
* @param array|string $data The request data.
|
||||
|
@ -229,7 +247,6 @@ trait ApiTestTrait
|
|||
* and validates the response against the OpenAPI spec.
|
||||
*
|
||||
* @see \Cake\TestSuite\IntegrationTestTrait::_sendRequest()
|
||||
*
|
||||
* @param array|string $url The URL
|
||||
* @param string $method The HTTP method
|
||||
* @param array|string $data The request data.
|
||||
|
@ -274,8 +291,8 @@ trait ApiTestTrait
|
|||
|
||||
/**
|
||||
* Create a PSR-7 request from the request spec.
|
||||
* @see \Cake\TestSuite\MiddlewareDispatcher::_createRequest()
|
||||
*
|
||||
* @see \Cake\TestSuite\MiddlewareDispatcher::_createRequest()
|
||||
* @param array<string, mixed> $spec The request spec.
|
||||
* @return \Cake\Http\ServerRequest
|
||||
*/
|
||||
|
@ -292,6 +309,7 @@ trait ApiTestTrait
|
|||
if (strpos($environment['PHP_SELF'], 'phpunit') !== false) {
|
||||
$environment['PHP_SELF'] = '/';
|
||||
}
|
||||
|
||||
return ServerRequestFactory::fromGlobals(
|
||||
$environment,
|
||||
$spec['query'],
|
||||
|
|
|
@ -43,4 +43,15 @@ class DeleteCerebrateApiTest extends TestCase
|
|||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordExists('Cerebrates', ['id' => CerebratesFixture::SERVER_A_ID]);
|
||||
}
|
||||
|
||||
public function testDeleteCerebrateNotAllowedAsOrgAdmin(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
$this->setAuthToken(AuthKeysFixture::ORG_ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, CerebratesFixture::SERVER_A_ID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordExists('Cerebrates', ['id' => CerebratesFixture::SERVER_A_ID]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Organisations;
|
||||
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Fixture\OrganisationsFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use Cake\TestSuite\TestCase;
|
||||
|
||||
class AddOrganisationsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/organisations/add';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
];
|
||||
|
||||
private function addOrganisation(array $org_data): void
|
||||
{
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordExists(
|
||||
'Organisations',
|
||||
$org_data
|
||||
);
|
||||
}
|
||||
|
||||
private function addNotAllowed(array $org_data): void
|
||||
{
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'name' => $org_data['name'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddOrganisationAsAdmin(): void
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'IT',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$this->addOrganisation($org_data);
|
||||
}
|
||||
|
||||
public function testAddNotAllowedAsRegularUser(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'IT',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$this->addNotAllowed($org_data);
|
||||
}
|
||||
|
||||
public function testAddNotAllowedAsOrgAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ORG_ADMIN_API_KEY); // user from org A
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'IT',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$this->addNotAllowed($org_data);
|
||||
}
|
||||
|
||||
public function testAddNameAlreadyExists(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => 'Organisation A',
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'DUPLICATE ENTRY',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'name' => 'Organisation A',
|
||||
'sector' => 'DUPLICATE ENTRY',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddUuidAlreadyExists(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => OrganisationsFixture::ORGANISATION_A_UUID,
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'DUPLICATE ENTRY',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'name' => $org_data['name'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testBadUuid(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => '11111111-1111-1111-1111-111111111111',
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'DUPLICATE ENTRY',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'name' => $org_data['name'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddLongName(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => 'This is a very long name that is longer than 255 characters and should not be allowed. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'IT',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
// 'created_by' => 0,
|
||||
];
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'name' => $org_data['name'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddCreatedBy(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$faker = \Faker\Factory::create();
|
||||
$org_data = [
|
||||
'uuid' => $faker->uuid(),
|
||||
'name' => $faker->text(10),
|
||||
'description' => $faker->text(10),
|
||||
'nationality' => $faker->countryCode,
|
||||
'sector' => 'IT',
|
||||
'type' => '',
|
||||
'contacts' => '',
|
||||
'local' => 1,
|
||||
'restricted_to_domain' => '',
|
||||
'landingpage' => '',
|
||||
//'date_created' => $faker->dateTime()->getTimestamp(),
|
||||
// 'date_modified' => $faker->dateTime()->getTimestamp(),
|
||||
'created_by' => 1,
|
||||
];
|
||||
$url = sprintf('%s', self::ENDPOINT);
|
||||
$this->post(
|
||||
$url,
|
||||
$org_data
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordExists(
|
||||
'Organisations',
|
||||
[
|
||||
'uuid' => $org_data['uuid'],
|
||||
'created_by' => AuthKeysFixture::ADMIN_API_ID,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Organisations;
|
||||
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Fixture\OrganisationsFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use Cake\TestSuite\TestCase;
|
||||
|
||||
class DeleteOrganisationsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/organisations/delete';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
];
|
||||
|
||||
public function testDeleteOrganisation(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordNotExists('Organisations', ['id' => OrganisationsFixture::ORGANISATION_A_ID]);
|
||||
}
|
||||
|
||||
public function testDeleteOrganisationNotAllowedAsRegularUser(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordExists('Organisations', ['id' => OrganisationsFixture::ORGANISATION_A_ID]);
|
||||
}
|
||||
|
||||
public function testDeleteOrganisationNotAllowedAsOrgAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ORG_ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordExists('Organisations', ['id' => OrganisationsFixture::ORGANISATION_A_ID]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Organisations;
|
||||
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Fixture\OrganisationsFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use Cake\TestSuite\TestCase;
|
||||
|
||||
class EditOrganisationsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/organisations/edit';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
];
|
||||
|
||||
private function editOrganisation(int $org_id): void
|
||||
{
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, $org_id);
|
||||
$this->put(
|
||||
$url,
|
||||
[
|
||||
'id' => $org_id,
|
||||
'description' => 'new description',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordExists(
|
||||
'Organisations',
|
||||
[
|
||||
'id' => $org_id,
|
||||
'description' => 'new description',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function editNotAllowed(int $org_id): void
|
||||
{
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, $org_id);
|
||||
$this->put(
|
||||
$url,
|
||||
[
|
||||
'id' => $org_id,
|
||||
'description' => 'new description',
|
||||
]
|
||||
);
|
||||
$this->assertResponseCode(405);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'id' => $org_id,
|
||||
'description' => 'new description',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testEditOrganisationAsAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$this->editOrganisation(OrganisationsFixture::ORGANISATION_A_ID);
|
||||
}
|
||||
|
||||
public function testEditOrganisationAsOrgAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ORG_ADMIN_API_KEY); // user from org A
|
||||
$this->editOrganisation(OrganisationsFixture::ORGANISATION_A_ID);
|
||||
}
|
||||
|
||||
public function testEditNotAllowedAsRegularUser(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||
$this->editNotAllowed(OrganisationsFixture::ORGANISATION_A_ID);
|
||||
}
|
||||
|
||||
public function testEditNotAllowedAsWrongOrgAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ORG_ADMIN_API_KEY); // user from org A
|
||||
$this->editNotAllowed(OrganisationsFixture::ORGANISATION_B_ID); // edit org B not allowed
|
||||
}
|
||||
|
||||
public function testEditNameAlreadyExists(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID);
|
||||
$this->put(
|
||||
$url,
|
||||
[
|
||||
'id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'name' => 'Organisation B',
|
||||
]
|
||||
);
|
||||
$this->assertResponseCode(200);
|
||||
$this->assertDbRecordNotExists(
|
||||
'Organisations',
|
||||
[
|
||||
'id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||
'description' => 'Organisation B',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Organisations;
|
||||
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Fixture\OrganisationsFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use Cake\TestSuite\TestCase;
|
||||
|
||||
class IndexOrganisationsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/organisations/index';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
];
|
||||
|
||||
public function testIndexOrganisationsAsUser(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||
$this->get(self::ENDPOINT);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertResponseContains(sprintf('"uuid": "%s"', OrganisationsFixture::ORGANISATION_A_UUID));
|
||||
$this->assertResponseContains(sprintf('"uuid": "%s"', OrganisationsFixture::ORGANISATION_B_UUID));
|
||||
}
|
||||
|
||||
public function testIndexOrganisationsAsAdmin(): void
|
||||
{
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$this->get(self::ENDPOINT);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertResponseContains(sprintf('"uuid": "%s"', OrganisationsFixture::ORGANISATION_A_UUID));
|
||||
$this->assertResponseContains(sprintf('"uuid": "%s"', OrganisationsFixture::ORGANISATION_B_UUID));
|
||||
}
|
||||
|
||||
public function testIndexOrganisationsWithInvalidAuthToken(): void
|
||||
{
|
||||
$this->setAuthToken('invalid_token');
|
||||
$this->get(self::ENDPOINT);
|
||||
$this->assertResponseCode(405);
|
||||
}
|
||||
|
||||
public function testIndexOrganisationsWithNoAuthToken(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
$this->get(self::ENDPOINT);
|
||||
$this->assertResponseCode(405);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue