Skip to content

Commit 6e28a32

Browse files
authored
Merge pull request #79 from monarc-project/feature/AB-08
Asset-based ISO 27005:2022 alignment
2 parents 4dc0560 + 3b70d1d commit 6e28a32

39 files changed

Lines changed: 3152 additions & 100 deletions

config/module.config.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,57 @@
12311231
],
12321232
],
12331233
],
1234+
1235+
'risk_sources' => [
1236+
'type' => 'segment',
1237+
'options' => [
1238+
'route' => 'risk-sources[/:id]',
1239+
'constraints' => [
1240+
'id' => '[0-9]+',
1241+
],
1242+
'defaults' => [
1243+
'controller' => PipeSpec::class,
1244+
'middleware' => new PipeSpec(
1245+
AnrValidationMiddleware::class,
1246+
Controller\ApiAnrRiskSourcesController::class,
1247+
),
1248+
],
1249+
],
1250+
],
1251+
1252+
'interested_parties' => [
1253+
'type' => 'segment',
1254+
'options' => [
1255+
'route' => 'interested-parties[/:id]',
1256+
'constraints' => [
1257+
'id' => '[0-9]+',
1258+
],
1259+
'defaults' => [
1260+
'controller' => PipeSpec::class,
1261+
'middleware' => new PipeSpec(
1262+
AnrValidationMiddleware::class,
1263+
Controller\ApiAnrInterestedPartiesController::class,
1264+
),
1265+
],
1266+
],
1267+
],
1268+
1269+
'reassessment_triggers' => [
1270+
'type' => 'segment',
1271+
'options' => [
1272+
'route' => 'reassessment-triggers[/:id]',
1273+
'constraints' => [
1274+
'id' => '[0-9]+',
1275+
],
1276+
'defaults' => [
1277+
'controller' => PipeSpec::class,
1278+
'middleware' => new PipeSpec(
1279+
AnrValidationMiddleware::class,
1280+
Controller\ApiAnrReassessmentTriggersController::class,
1281+
),
1282+
],
1283+
],
1284+
],
12341285
],
12351286
],
12361287
'monarc_api_doc_models' => [
@@ -1401,6 +1452,9 @@
14011452
Controller\ApiConfigController::class => AutowireFactory::class,
14021453
Controller\ApiClientsController::class => AutowireFactory::class,
14031454
Controller\ApiCoreReferentialsController::class => AutowireFactory::class,
1455+
Controller\ApiAnrRiskSourcesController::class => AutowireFactory::class,
1456+
Controller\ApiAnrInterestedPartiesController::class => AutowireFactory::class,
1457+
Controller\ApiAnrReassessmentTriggersController::class => AutowireFactory::class,
14041458
Controller\ApiUserPasswordController::class => AutowireFactory::class,
14051459
Controller\ApiUserTwoFAController::class => AutowireFactory::class,
14061460
Controller\ApiUserRecoveryCodesController::class => AutowireFactory::class,
@@ -1509,6 +1563,9 @@
15091563
Table\OperationalRiskScaleTypeTable::class => ClientEntityManagerFactory::class,
15101564
Table\OperationalRiskScaleCommentTable::class => ClientEntityManagerFactory::class,
15111565
Table\OperationalInstanceRiskScaleTable::class => ClientEntityManagerFactory::class,
1566+
Table\RiskSourceTable::class => ClientEntityManagerFactory::class,
1567+
Table\InterestedPartyTable::class => ClientEntityManagerFactory::class,
1568+
Table\ReassessmentTriggerTable::class => ClientEntityManagerFactory::class,
15121569
Table\RecommendationTable::class => ClientEntityManagerFactory::class,
15131570
Table\RecommendationHistoryTable::class => ClientEntityManagerFactory::class,
15141571
Table\RecommendationRiskTable::class => ClientEntityManagerFactory::class,
@@ -1593,6 +1650,9 @@
15931650
Service\SoaService::class => AutowireFactory::class,
15941651
Service\SoaScaleCommentService::class => AutowireFactory::class,
15951652
Service\SystemMessageService::class => AutowireFactory::class,
1653+
Service\RiskSourceService::class => AutowireFactory::class,
1654+
Service\InterestedPartyService::class => AutowireFactory::class,
1655+
Service\ReassessmentTriggerService::class => AutowireFactory::class,
15961656
Stats\Service\StatsAnrService::class => ReflectionBasedAbstractFactory::class,
15971657
Stats\Service\StatsSettingsService::class => AutowireFactory::class,
15981658
CronTask\Service\CronTaskService::class => AutowireFactory::class,
@@ -1603,6 +1663,7 @@
16031663
/* Import services. */
16041664
Import\Service\ObjectImportService::class => AutowireFactory::class,
16051665
Import\Service\InstanceImportService::class => AutowireFactory::class,
1666+
Import\Processor\RiskSourceImportProcessor::class => AutowireFactory::class,
16061667

16071668
// Helpers
16081669
Import\Helper\ImportCacheHelper::class => AutowireFactory::class,
@@ -1844,6 +1905,9 @@
18441905
'monarc_api_guides_items',
18451906
'monarc_api_models',
18461907
'monarc_api_referentials',
1908+
'monarc_api_global_client_anr/risk_sources',
1909+
'monarc_api_global_client_anr/interested_parties',
1910+
'monarc_api_global_client_anr/reassessment_triggers',
18471911
'monarc_api_client',
18481912
'monarc_api_global_client_anr/carto_risks',
18491913
'monarc_api_global_client_anr/risk_owners',
@@ -1858,6 +1922,9 @@
18581922
'monarc_api_doc_models',
18591923
'monarc_api_models',
18601924
'monarc_api_referentials',
1925+
'monarc_api_global_client_anr/risk_sources',
1926+
'monarc_api_global_client_anr/interested_parties',
1927+
'monarc_api_global_client_anr/reassessment_triggers',
18611928
'monarc_api_admin_users_roles',
18621929
'monarc_api_global_client_anr/anr_instance_metadata_field',
18631930
'monarc_api_global_client_anr/instance_metadata',
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @link https://github.com/monarc-project for the canonical source repository
4+
* @copyright Copyright (c) 2016-2026 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
5+
* @license MONARC is licensed under GNU Affero General Public License version 3
6+
*/
7+
8+
use Phinx\Migration\AbstractMigration;
9+
10+
class AddRiskSources extends AbstractMigration
11+
{
12+
public function up(): void
13+
{
14+
$this->execute(
15+
'CREATE TABLE `risk_sources` (
16+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
17+
`anr_id` int(11) unsigned NOT NULL,
18+
`label` varchar(255) NOT NULL,
19+
`is_default` tinyint(1) NOT NULL DEFAULT 0,
20+
`is_active` tinyint(1) NOT NULL DEFAULT 1,
21+
`creator` varchar(255) DEFAULT NULL,
22+
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
23+
`updater` varchar(255) DEFAULT NULL,
24+
`updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
25+
PRIMARY KEY (`id`),
26+
KEY `risk_sources_anr_id_indx` (`anr_id`),
27+
KEY `risk_sources_anr_id_is_active_indx` (`anr_id`, `is_active`),
28+
UNIQUE `risk_sources_anr_id_label_unq` (`anr_id`, `label`),
29+
FOREIGN KEY (`anr_id`) REFERENCES `anrs` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT
30+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'
31+
);
32+
33+
$anrIds = $this->fetchAll('SELECT id FROM anrs');
34+
foreach ($anrIds as $anr) {
35+
$anrId = $anr['id'];
36+
$this->execute(
37+
"INSERT IGNORE INTO `risk_sources` (`anr_id`, `label`, `is_default`, `is_active`, `creator`, `created_at`) VALUES
38+
({$anrId}, 'External attacker', 1, 1, 'System', NOW()),
39+
({$anrId}, 'Internal malicious user', 1, 1, 'System', NOW()),
40+
({$anrId}, 'Internal accidental user', 1, 1, 'System', NOW()),
41+
({$anrId}, 'Supplier / third party', 1, 1, 'System', NOW()),
42+
({$anrId}, 'System failure', 1, 1, 'System', NOW()),
43+
({$anrId}, 'Software defect', 1, 1, 'System', NOW()),
44+
({$anrId}, 'Natural event', 1, 1, 'System', NOW()),
45+
({$anrId}, 'Organizational or process weakness', 1, 1, 'System', NOW()),
46+
({$anrId}, 'Other', 1, 1, 'System', NOW());"
47+
);
48+
}
49+
50+
$this->table('instances_risks')
51+
->addColumn('risk_source_id', 'integer', ['null' => true, 'signed' => false, 'after' => 'asset_id'])
52+
->addIndex(['risk_source_id'], ['name' => 'risk_source_id'])
53+
->addForeignKey('risk_source_id', 'risk_sources', 'id', ['delete' => 'SET_NULL', 'update' => 'RESTRICT'])
54+
->update();
55+
}
56+
57+
public function down(): void
58+
{
59+
$this->table('instances_risks')
60+
->dropForeignKey('risk_source_id')
61+
->removeIndexByName('risk_source_id')
62+
->removeColumn('risk_source_id')
63+
->update();
64+
65+
$this->table('risk_sources')->drop()->save();
66+
}
67+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @link https://github.com/monarc-project for the canonical source repository
4+
* @copyright Copyright (c) 2016-2026 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
5+
* @license MONARC is licensed under GNU Affero General Public License version 3
6+
*/
7+
8+
use Phinx\Migration\AbstractMigration;
9+
10+
class AddAnrReassessmentTriggers extends AbstractMigration
11+
{
12+
public function up(): void
13+
{
14+
$this->execute(
15+
'CREATE TABLE IF NOT EXISTS `anr_reassessment_triggers` (
16+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
17+
`anr_id` int(11) unsigned NOT NULL,
18+
`trigger_type` varchar(255) DEFAULT "",
19+
`description` text NOT NULL,
20+
`is_active` tinyint(1) NOT NULL DEFAULT 1,
21+
`position` int(11) NOT NULL DEFAULT 0,
22+
`creator` varchar(255) DEFAULT NULL,
23+
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
24+
`updater` varchar(255) DEFAULT NULL,
25+
`updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
26+
PRIMARY KEY (`id`),
27+
KEY `anr_reassessment_triggers_anr_id_indx` (`anr_id`),
28+
KEY `anr_reassessment_triggers_anr_id_trigger_type_indx` (`anr_id`, `trigger_type`),
29+
KEY `anr_reassessment_triggers_anr_id_position_indx` (`anr_id`, `position`),
30+
CONSTRAINT `fk_anr_reassessment_triggers_anr`
31+
FOREIGN KEY (`anr_id`) REFERENCES `anrs` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT
32+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'
33+
);
34+
}
35+
36+
public function down(): void
37+
{
38+
$this->table('anr_reassessment_triggers')->drop()->save();
39+
}
40+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @link https://github.com/monarc-project for the canonical source repository
4+
* @copyright Copyright (c) 2016-2026 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
5+
* @license MONARC is licensed under GNU Affero General Public License version 3
6+
*/
7+
8+
use Phinx\Migration\AbstractMigration;
9+
10+
class AddRiskReviewMetadata extends AbstractMigration
11+
{
12+
public function up(): void
13+
{
14+
$this->table('instances_risks')
15+
->addColumn('last_review_date', 'date', ['null' => true, 'after' => 'comment_after'])
16+
->addColumn('review_frequency', 'string', ['limit' => 50, 'null' => true, 'after' => 'last_review_date'])
17+
->update();
18+
19+
$this->table('anr_reassessment_triggers')
20+
->addColumn('monitoring_approach', 'text', ['null' => true, 'after' => 'description'])
21+
->update();
22+
}
23+
24+
public function down(): void
25+
{
26+
$this->table('instances_risks')
27+
->removeColumn('review_frequency')
28+
->removeColumn('last_review_date')
29+
->update();
30+
31+
$this->table('anr_reassessment_triggers')
32+
->removeColumn('monitoring_approach')
33+
->update();
34+
}
35+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @link https://github.com/monarc-project for the canonical source repository
4+
* @copyright Copyright (c) 2016-2026 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
5+
* @license MONARC is licensed under GNU Affero General Public License version 3
6+
*/
7+
8+
use Phinx\Migration\AbstractMigration;
9+
10+
class AddResidualRiskAcceptance extends AbstractMigration
11+
{
12+
public function up(): void
13+
{
14+
$this->table('instances_risks')
15+
->addColumn('residual_risk_decision', 'string', ['limit' => 20, 'null' => true, 'after' => 'review_frequency'])
16+
->addColumn(
17+
'residual_risk_approved_by',
18+
'string',
19+
['limit' => 255, 'null' => true, 'after' => 'residual_risk_decision']
20+
)
21+
->addColumn('residual_risk_approved_at', 'date', ['null' => true, 'after' => 'residual_risk_approved_by'])
22+
->addColumn('residual_risk_justification', 'text', ['null' => true, 'after' => 'residual_risk_approved_at'])
23+
->update();
24+
25+
$this->table('instances_risks_op')
26+
->addColumn('last_review_date', 'date', ['null' => true, 'after' => 'mitigation'])
27+
->addColumn('review_frequency', 'string', ['limit' => 50, 'null' => true, 'after' => 'last_review_date'])
28+
->addColumn('residual_risk_decision', 'string', ['limit' => 20, 'null' => true, 'after' => 'review_frequency'])
29+
->addColumn('residual_risk_approved_by', 'string', ['limit' => 255, 'null' => true, 'after' => 'residual_risk_decision'])
30+
->addColumn('residual_risk_approved_at', 'date', ['null' => true, 'after' => 'residual_risk_approved_by'])
31+
->addColumn('residual_risk_justification', 'text', ['null' => true, 'after' => 'residual_risk_approved_at'])
32+
->addColumn('risk_source_id', 'integer', ['null' => true, 'signed' => false, 'after' => 'object_id'])
33+
->addIndex(['risk_source_id'], ['name' => 'risk_source_id'])
34+
->addForeignKey('risk_source_id', 'risk_sources', 'id', ['delete' => 'SET_NULL', 'update' => 'RESTRICT'])
35+
->update();
36+
}
37+
38+
public function down(): void
39+
{
40+
$this->table('instances_risks')
41+
->removeColumn('residual_risk_justification')
42+
->removeColumn('residual_risk_approved_at')
43+
->removeColumn('residual_risk_approved_by')
44+
->removeColumn('residual_risk_decision')
45+
->update();
46+
47+
$this->table('instances_risks_op')
48+
->removeColumn('residual_risk_justification')
49+
->removeColumn('residual_risk_approved_at')
50+
->removeColumn('residual_risk_approved_by')
51+
->removeColumn('residual_risk_decision')
52+
->removeColumn('review_frequency')
53+
->removeColumn('last_review_date')
54+
->dropForeignKey('risk_source_id')
55+
->removeIndexByName('risk_source_id')
56+
->removeColumn('risk_source_id')
57+
->update();
58+
}
59+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* @link https://github.com/monarc-project for the canonical source repository
4+
* @copyright Copyright (c) 2016-2026 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
5+
* @license MONARC is licensed under GNU Affero General Public License version 3
6+
*/
7+
8+
use Phinx\Migration\AbstractMigration;
9+
10+
class AddInterestedParties extends AbstractMigration
11+
{
12+
public function up(): void
13+
{
14+
$this->table('anr_interested_parties')
15+
->addColumn('anr_id', 'integer', ['null' => false, 'signed' => false])
16+
->addColumn('stakeholder', 'string', ['limit' => 255, 'null' => false])
17+
->addColumn('requirement', 'text', ['null' => false])
18+
->addColumn('position', 'integer', ['default' => 0, 'signed' => false])
19+
->addColumn('creator', 'string', ['limit' => 255, 'null' => true])
20+
->addColumn('created_at', 'datetime', ['null' => true])
21+
->addColumn('updater', 'string', ['limit' => 255, 'null' => true])
22+
->addColumn('updated_at', 'datetime', ['null' => true])
23+
->addIndex(['anr_id'], ['name' => 'idx_anr_id'])
24+
->addIndex(['anr_id', 'position'], ['name' => 'anr_interested_parties_anr_id_position_indx'])
25+
->addForeignKey('anr_id', 'anrs', 'id', ['delete' => 'CASCADE', 'update' => 'RESTRICT'])
26+
->create();
27+
}
28+
29+
public function down(): void
30+
{
31+
$this->table('anr_interested_parties')->drop()->save();
32+
}
33+
}

src/Controller/ApiAnrInstancesRisksController.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ public function update($id, $data)
5858

5959
return $this->getPreparedJsonResponse([
6060
'id' => $instanceRisk->getId(),
61+
'riskSourceId' => $instanceRisk->getRiskSource()?->getId(),
62+
'riskSourceLabel' => $instanceRisk->getRiskSource()?->getLabel() ?? '',
63+
'lastReviewDate' => $instanceRisk->getLastReviewDate()?->format('Y-m-d'),
64+
'reviewFrequency' => $instanceRisk->getReviewFrequency(),
65+
'residualRiskDecision' => $instanceRisk->getResidualRiskDecision(),
66+
'residualRiskApprovedBy' => $instanceRisk->getResidualRiskApprovedBy(),
67+
'residualRiskApprovedAt' => $instanceRisk->getResidualRiskApprovedAt()?->format('Y-m-d'),
68+
'residualRiskJustification' => $instanceRisk->getResidualRiskJustification(),
6169
'threatRate' => $instanceRisk->getThreatRate(),
6270
'vulnerabilityRate' => $instanceRisk->getVulnerabilityRate(),
6371
'reductionAmount' => $instanceRisk->getReductionAmount(),

src/Controller/ApiAnrInstancesRisksOpController.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ public function update($id, $data)
6262
'cacheBrutRisk' => $instanceRiskOp->getCacheBrutRisk(),
6363
'cacheNetRisk' => $instanceRiskOp->getCacheNetRisk(),
6464
'cacheTargetedRisk' => $instanceRiskOp->getCacheTargetedRisk(),
65+
'riskSourceId' => $instanceRiskOp->getRiskSource()?->getId(),
66+
'riskSourceLabel' => $instanceRiskOp->getRiskSource()?->getLabel() ?? '',
67+
'lastReviewDate' => $instanceRiskOp->getLastReviewDate()?->format('Y-m-d'),
68+
'reviewFrequency' => $instanceRiskOp->getReviewFrequency(),
69+
'residualRiskDecision' => $instanceRiskOp->getResidualRiskDecision(),
70+
'residualRiskApprovedBy' => $instanceRiskOp->getResidualRiskApprovedBy(),
71+
'residualRiskApprovedAt' => $instanceRiskOp->getResidualRiskApprovedAt()?->format('Y-m-d'),
72+
'residualRiskJustification' => $instanceRiskOp->getResidualRiskJustification(),
6573
]);
6674
}
6775
/**

0 commit comments

Comments
 (0)