Skip to content

Commit 3fc9553

Browse files
committed
Moved the anr status and access validation to the middleware, refactored the anr related functionality and cleaned up the entities.
1 parent 8b63132 commit 3fc9553

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2079
-2383
lines changed

Module.php

Lines changed: 4 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
1-
<?php
1+
<?php declare(strict_types=1);
22
/**
33
* @link https://github.com/monarc-project for the canonical source repository
4-
* @copyright Copyright (c) 2016-2022 SMILE GIE Securitymadein.lu - Licensed under GNU Affero GPL v3
4+
* @copyright Copyright (c) 2016-2024 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
55
* @license MONARC is licensed under GNU Affero General Public License version 3
66
*/
77

88
namespace Monarc\FrontOffice;
99

10-
use DateTime;
1110
use Laminas\Stdlib\ResponseInterface;
12-
use Monarc\Core\Model\Entity\AnrSuperClass;
1311
use Monarc\Core\Service\ConnectedUserService;
14-
use Monarc\FrontOffice\CronTask\Service\CronTaskService;
15-
use Monarc\FrontOffice\Model\Entity\Anr;
16-
use Monarc\FrontOffice\Model\Entity\CronTask;
17-
use Monarc\FrontOffice\Model\Entity\Snapshot;
18-
use Monarc\FrontOffice\Model\Table\InstanceTable;
19-
use Monarc\FrontOffice\Model\Table\SnapshotTable;
20-
use Monarc\FrontOffice\Table\AnrTable;
21-
use Monarc\FrontOffice\Table\UserAnrTable;
2212
use Laminas\Http\Request;
2313
use Laminas\Mvc\ModuleRouteListener;
2414
use Laminas\Mvc\MvcEvent;
@@ -166,164 +156,14 @@ public function checkRbac(MvcEvent $mvcEvent)
166156
$roles = $connectedUser->getRoles();
167157
}
168158

169-
$isGranted = false;
170-
/** @var SnapshotTable $snapshotTable */
171-
$snapshotTable = $serviceManager->get(SnapshotTable::class);
172-
/** @var UserAnrTable $userAnrTable */
173-
$userAnrTable = $serviceManager->get(UserAnrTable::class);
174159
foreach ($roles as $role) {
175160
if ($mvcEvent->getViewModel()->rbac->isGranted($role, $route)) {
176-
$anrId = (int)$mvcEvent->getRouteMatch()->getParam('id');
177-
if (($route === 'monarc_api_client_anr' && $anrId !== 0)
178-
|| strncmp($route, 'monarc_api_global_client_anr/', 29) === 0
179-
) {
180-
if ($route !== 'monarc_api_client_anr') {
181-
$anrId = (int)$mvcEvent->getRouteMatch()->getParam('anrid');
182-
}
183-
if ($anrId === 0) {
184-
break;
185-
}
186-
187-
$result = $this->validateAnrStatusAndGetResponseIfInvalid($anrId, $mvcEvent, $route);
188-
if ($result !== null) {
189-
return $result;
190-
}
191-
192-
$userAnr = $userAnrTable->findByAnrIdAndUser($anrId, $connectedUser);
193-
if ($userAnr === null) {
194-
// We authorise the access for snapshot, but for read only (GET).
195-
if ($mvcEvent->getRequest()->getMethod() !== 'GET'
196-
&& !$this->authorizedPost($route, $mvcEvent->getRequest()->getMethod())
197-
) {
198-
break;
199-
}
200-
/** @var Snapshot|false $snapshot */
201-
$snapshot = current($snapshotTable->getEntityByFields(['anr' => $anrId]));
202-
if ($snapshot === false) {
203-
break;
204-
}
205-
$userAnr = $userAnrTable->findByAnrAndUser($snapshot->getAnrReference(), $connectedUser);
206-
if ($userAnr === null) {
207-
// the user did not have access to the anr, from which this snapshot was created.
208-
break;
209-
}
210-
$isGranted = true;
211-
break;
212-
}
213-
214-
if (!$userAnr->hasWriteAccess() && $mvcEvent->getRequest()->getMethod() !== 'GET') {
215-
// We authorize POST for the specific actions.
216-
if ($this->authorizedPost($route, $mvcEvent->getRequest()->getMethod())) {
217-
$isGranted = true;
218-
}
219-
break;
220-
}
221-
}
222-
223-
$isGranted = true;
224-
break;
225-
}
226-
}
227-
228-
if (!$isGranted) {
229-
$response = $mvcEvent->getResponse();
230-
$response->setStatusCode($connectedUser === null ? 401 : 403);
231-
232-
return $response;
233-
}
234-
}
235-
236-
private function authorizedPost($route, $method)
237-
{
238-
return $method === 'POST'
239-
&& ($route === 'monarc_api_global_client_anr/export' // export ANR
240-
|| $route === 'monarc_api_global_client_anr/instance_export' // export Instance
241-
|| $route === 'monarc_api_global_client_anr/objects_export' // export Object
242-
|| $route === 'monarc_api_global_client_anr/deliverable' // generate a report
243-
);
244-
}
245-
246-
/**
247-
* Validates the anr status for NON GET method requests exclude DELETE (cancellation of background import).
248-
*/
249-
private function validateAnrStatusAndGetResponseIfInvalid(
250-
int $anrId,
251-
MvcEvent $mvcEvent,
252-
string $route
253-
): ?ResponseInterface {
254-
/* GET requests are always allowed and cancellation of import (delete import process -> PID). */
255-
if ($mvcEvent->getRequest()->getMethod() === Request::METHOD_GET
256-
|| (
257-
$mvcEvent->getRequest()->getMethod() === Request::METHOD_DELETE
258-
&& $route === 'monarc_api_global_client_anr/instance_import'
259-
)
260-
) {
261-
return null;
262-
}
263-
264-
$serviceManager = $mvcEvent->getApplication()->getServiceManager();
265-
266-
/** @var Anr $anr */
267-
$anr = $serviceManager->get(AnrTable::class)->findById($anrId);
268-
if ($anr->isActive()) {
269-
return null;
270-
}
271-
272-
/* Allow deleting anr if the status is waiting for import or there is an import error. */
273-
if ($route === 'monarc_api_client_anr'
274-
&& $mvcEvent->getRequest()->getMethod() === Request::METHOD_DELETE
275-
&& ($anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR
276-
|| $anr->getStatus() === AnrSuperClass::STATUS_AWAITING_OF_IMPORT
277-
)
278-
) {
279-
return null;
280-
}
281-
282-
/* Allow to restore a snapshot if there is an import error. */
283-
if ($route === 'monarc_api_global_client_anr/snapshot_restore'
284-
&& $anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR
285-
&& $mvcEvent->getRequest()->getMethod() === Request::METHOD_POST
286-
) {
287-
return null;
288-
}
289-
290-
$result = [
291-
'status' => $anr->getStatusName(),
292-
'importStatus' => [],
293-
];
294-
/** @var CronTaskService $cronTaskService */
295-
$cronTaskService = $serviceManager->get(CronTaskService::class);
296-
297-
if ($anr->getStatus() === AnrSuperClass::STATUS_UNDER_IMPORT) {
298-
$importCronTask = $cronTaskService->getLatestTaskByNameWithParam(
299-
CronTask::NAME_INSTANCE_IMPORT,
300-
['anrId' => $anrId]
301-
);
302-
if ($importCronTask !== null && $importCronTask->getStatus() === CronTask::STATUS_IN_PROGRESS) {
303-
/** @var InstanceTable $instanceTable */
304-
$instanceTable = $serviceManager->get(InstanceTable::class);
305-
$timeDiff = $importCronTask->getUpdatedAt()->diff(new DateTime());
306-
$instancesNumber = $instanceTable->countByAnrIdFromDate($anrId, $importCronTask->getUpdatedAt());
307-
$result['importStatus'] = [
308-
'executionTime' => $timeDiff->h . ' hours ' . $timeDiff->i . ' min ' . $timeDiff->s . ' sec',
309-
'createdInstances' => $instancesNumber,
310-
];
311-
}
312-
} elseif ($anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR) {
313-
$importCronTask = $cronTaskService->getLatestTaskByNameWithParam(
314-
CronTask::NAME_INSTANCE_IMPORT,
315-
['anrId' => $anrId]
316-
);
317-
if ($importCronTask !== null && $importCronTask->getStatus() === CronTask::STATUS_FAILURE) {
318-
$result['importStatus'] = [
319-
'errorMessage' => $importCronTask->getResultMessage(),
320-
];
161+
return;
321162
}
322163
}
323164

324165
$response = $mvcEvent->getResponse();
325-
$response->setContent(json_encode($result, JSON_THROW_ON_ERROR));
326-
$response->setStatusCode(409);
166+
$response->setStatusCode($connectedUser === null ? 401 : 403);
327167

328168
return $response;
329169
}

config/module.config.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,9 +1248,7 @@
12481248
],
12491249
'defaults' => [
12501250
'controller' => PipeSpec::class,
1251-
'middleware' => new PipeSpec(
1252-
Controller\ApiUserTwoFAController::class,
1253-
),
1251+
'middleware' => new PipeSpec(Controller\ApiUserTwoFAController::class),
12541252
],
12551253
],
12561254
],

migrations/db/20230901112005_fix_positions_cleanup_db.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,23 @@ public function change()
343343

344344
$this->table('recommandations')
345345
->removeColumn('token_import')
346+
->removeColumn('original_code')
346347
->update();
347348

348349
$this->table('deliveries')
349350
->renameColumn('resp_smile', 'responsible_manager')
350351
->update();
351352

352353
$this->table('scales_impact_types')
353-
->removeColumn('position')
354-
->update();
354+
->removeColumn('position')
355+
->update();
356+
357+
$this->table('objects_categories')
358+
->changeColumn('label1', 'string', ['null' => false, 'default' => '', 'limit' => 2048])
359+
->changeColumn('label2', 'string', ['null' => false, 'default' => '', 'limit' => 2048])
360+
->changeColumn('label3', 'string', ['null' => false, 'default' => '', 'limit' => 2048])
361+
->changeColumn('label4', 'string', ['null' => false, 'default' => '', 'limit' => 2048])
362+
->save();
355363

356364
/* TODO: Should be added to the next release migration, to perform this release in a safe mode.
357365
$this->table('anr_instance_metadata_fields')->removeColumn('label_translation_key')->update();
Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php declare(strict_types=1);
22
/**
33
* @link https://github.com/monarc-project for the canonical source repository
4-
* @copyright Copyright (c) 2016-2023 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
4+
* @copyright Copyright (c) 2016-2024 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
55
* @license MONARC is licensed under GNU Affero General Public License version 3
66
*/
77

@@ -17,45 +17,38 @@ class ApiAnrController extends AbstractRestfulControllerRequestHandler
1717
{
1818
use ControllerRequestResponseHandlerTrait;
1919

20-
private CreateAnrDataInputValidator $createAnrDataInputValidator;
21-
22-
private AnrService $anrService;
23-
24-
public function __construct(CreateAnrDataInputValidator $createAnrDataInputValidator, AnrService $anrService)
25-
{
26-
$this->createAnrDataInputValidator = $createAnrDataInputValidator;
27-
$this->anrService = $anrService;
20+
public function __construct(
21+
private CreateAnrDataInputValidator $createAnrDataInputValidator,
22+
private AnrService $anrService
23+
) {
2824
}
2925

3026
public function getList()
3127
{
32-
$page = $this->params()->fromQuery('page');
33-
$limit = $this->params()->fromQuery('limit');
34-
$order = $this->params()->fromQuery('order');
35-
$filter = $this->params()->fromQuery('filter');
36-
37-
$result = $this->anrService->getList($page, $limit, $order, $filter);
38-
// protected $dependencies = ['referentials'];
39-
if (count($this->dependencies)) {
40-
foreach ($result as $key => $entity) {
41-
$this->formatDependencies($result[$key], $this->dependencies);
42-
}
43-
}
28+
$result = $this->anrService->getList();
4429

4530
return $this->getPreparedJsonResponse([
4631
'count' => \count($result),
4732
'anrs' => $result,
4833
]);
4934
}
5035

36+
public function get($id)
37+
{
38+
/** @var Anr $anr */
39+
$anr = $this->getRequest()->getAttribute('anr');
40+
41+
return $this->getSuccessfulJsonResponse($this->anrService->getAnrData($anr));
42+
}
43+
5144
/**
5245
* @param array $data
5346
*/
5447
public function create($data)
5548
{
5649
$this->validatePostParams($this->createAnrDataInputValidator, $data);
5750

58-
$anr = $this->anrService->createFromModelToClient($this->createAnrDataInputValidator->getValidData());
51+
$anr = $this->anrService->createBasedOnModel($this->createAnrDataInputValidator->getValidData());
5952

6053
return $this->getSuccessfulJsonResponse(['id' => $anr->getId()]);
6154
}
@@ -73,4 +66,14 @@ public function patch($id, $data)
7366

7467
return $this->getSuccessfulJsonResponse(['id' => $id]);
7568
}
69+
70+
public function delete(mixed $id)
71+
{
72+
/** @var Anr $anr */
73+
$anr = $this->getRequest()->getAttribute('anr');
74+
75+
$this->anrService->delete($anr);
76+
77+
return $this->getSuccessfulJsonResponse();
78+
}
7679
}

src/Controller/ApiModelVerifyLanguageController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99

1010
use Laminas\Mvc\Controller\AbstractRestfulController;
1111
use Laminas\View\Model\JsonModel;
12-
use Monarc\FrontOffice\Service\AnrService;
12+
use Monarc\FrontOffice\Service\AnrModelService;
1313

1414
class ApiModelVerifyLanguageController extends AbstractRestfulController
1515
{
16-
public function __construct(private AnrService $anrService)
16+
public function __construct(private AnrModelService $anrModelService)
1717
{
1818
}
1919

2020
public function get($id)
2121
{
22-
return new JsonModel($this->anrService->getModelAvailableLanguages((int)$id));
22+
return new JsonModel($this->anrModelService->getAvailableLanguages((int)$id));
2323
}
2424
}

0 commit comments

Comments
 (0)