Skip to content

Commit

Permalink
Merge branch 'main' into CA-615-refactor-breadcrumbs
Browse files Browse the repository at this point in the history
  • Loading branch information
nas-tabchiche committed Dec 20, 2024
2 parents 5847038 + 182615d commit d796a00
Show file tree
Hide file tree
Showing 57 changed files with 1,913 additions and 232 deletions.
20 changes: 13 additions & 7 deletions backend/core/base_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,19 @@ def is_unique_in_scope(self, scope: models.QuerySet, fields_to_check: list) -> b
# to avoid false positives as a result of the object being compared to itself
if self.pk:
scope = scope.exclude(pk=self.pk)
return not scope.filter(
**{
f"{field}__iexact": getattr(self, field)
for field in fields_to_check
if hasattr(self, field)
}
).exists()
filters = {}
for field in fields_to_check:
if hasattr(self, field):
field_value = getattr(self, field)
model_field = self._meta.get_field(field)

# Use the appropriate lookup based on the field type
if isinstance(model_field, models.ForeignKey):
filters[f"{field}__exact"] = field_value
else:
filters[f"{field}__iexact"] = field_value

return not scope.filter(**filters).exists()

def display_path(self):
pass
Expand Down
11 changes: 11 additions & 0 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,17 @@ def ancestors_plus_self(self) -> set[Self]:
result.update(x.ancestors_plus_self())
return set(result)

def get_children(self):
return Asset.objects.filter(parent_assets=self)

def get_descendants(self) -> set[Self]:
children = self.get_children()
sub_children = set()
for child in children:
sub_children.append(child)
sub_children.update(child.get_descendants())
return sub_children

def get_security_objectives(self) -> dict[str, dict[str, dict[str, int | bool]]]:
"""
Gets the security objectives of a given asset.
Expand Down
1 change: 1 addition & 0 deletions backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class AssessmentReadSerializer(BaseModelSerializer):
class RiskMatrixReadSerializer(ReferentialSerializer):
folder = FieldsRelatedField()
json_definition = serializers.JSONField(source="get_json_translated")
library = FieldsRelatedField(["name", "id"])

class Meta:
model = RiskMatrix
Expand Down
4 changes: 4 additions & 0 deletions backend/core/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@
"view_stakeholder",
"change_stakeholder",
"delete_stakeholder",
"add_strategicscenario",
"view_strategicscenario",
"change_strategicscenario",
"delete_strategicscenario",
"add_attackpath",
"view_attackpath",
"change_attackpath",
Expand Down
35 changes: 35 additions & 0 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@
AppliedControl,
ComplianceAssessment,
RequirementMappingSet,
RiskAssessment,
)
from core.serializers import ComplianceAssessmentReadSerializer
from core.utils import RoleCodename, UserGroupCodename

from ebios_rm.models import (
EbiosRMStudy,
OperationalScenario,
)

from .models import *
from .serializers import *

Expand Down Expand Up @@ -578,6 +584,35 @@ class RiskAssessmentViewSet(BaseModelViewSet):
"ebios_rm_study",
]

def perform_create(self, serializer):
instance: RiskAssessment = serializer.save()
if instance.ebios_rm_study:
instance.risk_matrix = instance.ebios_rm_study.risk_matrix
ebios_rm_study = EbiosRMStudy.objects.get(id=instance.ebios_rm_study.id)
for operational_scenario in [
operational_scenario
for operational_scenario in ebios_rm_study.operational_scenarios.all()
if operational_scenario.is_selected
]:
risk_scenario = RiskScenario.objects.create(
risk_assessment=instance,
name=operational_scenario.name,
ref_id=operational_scenario.ref_id
if operational_scenario.ref_id
else RiskScenario.get_default_ref_id(instance),
description=operational_scenario.operating_modes_description,
current_proba=operational_scenario.likelihood,
current_impact=operational_scenario.gravity,
)
risk_scenario.assets.set(operational_scenario.get_assets())
risk_scenario.threats.set(operational_scenario.threats.all())
risk_scenario.existing_applied_controls.set(
operational_scenario.get_applied_controls()
)
risk_scenario.save()
instance.save()
return super().perform_create(serializer)

@action(detail=False, name="Risk assessments per status")
def per_status(self, request):
data = assessment_per_status(request.user, RiskAssessment)
Expand Down
66 changes: 66 additions & 0 deletions backend/ebios_rm/migrations/0007_ebiosrmstudy_meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generated by Django 5.1.4 on 2024-12-18 01:25

import core.validators
import ebios_rm.models
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("ebios_rm", "0006_alter_attackpath_stakeholders"),
]

operations = [
migrations.AddField(
model_name="ebiosrmstudy",
name="meta",
field=models.JSONField(
default=ebios_rm.models.get_initial_meta,
validators=[
core.validators.JSONSchemaInstanceValidator(
{
"$id": "https://ciso-assistant.com/schemas/ebiosrmstudy/meta.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Metadata of the EBIOS RM Study",
"properties": {
"workshops": {
"description": "A list of workshops, each containing steps",
"items": {
"additionalProperties": False,
"properties": {
"steps": {
"description": "The list of steps in the workshop",
"items": {
"additionalProperties": False,
"properties": {
"status": {
"description": "The current status of the step",
"enum": [
"to_do",
"in_progress",
"done",
],
"type": "string",
}
},
"required": ["status"],
"type": "object",
},
"type": "array",
}
},
"required": ["steps"],
"type": "object",
},
"type": "array",
}
},
"title": "Metadata",
"type": "object",
}
)
],
verbose_name="Metadata",
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Generated by Django 5.1.4 on 2024-12-20 08:56

import django.db.models.deletion
import iam.models
import uuid
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("ebios_rm", "0007_ebiosrmstudy_meta"),
("iam", "0010_user_preferences"),
]

operations = [
migrations.RemoveField(
model_name="attackpath",
name="ro_to_couple",
),
migrations.CreateModel(
name="StrategicScenario",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="Created at"),
),
(
"updated_at",
models.DateTimeField(auto_now=True, verbose_name="Updated at"),
),
(
"is_published",
models.BooleanField(default=False, verbose_name="published"),
),
("name", models.CharField(max_length=200, verbose_name="Name")),
(
"description",
models.TextField(blank=True, null=True, verbose_name="Description"),
),
("ref_id", models.CharField(blank=True, max_length=100)),
(
"ebios_rm_study",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="strategic_scenarios",
to="ebios_rm.ebiosrmstudy",
verbose_name="EBIOS RM study",
),
),
(
"folder",
models.ForeignKey(
default=iam.models.Folder.get_root_folder_id,
on_delete=django.db.models.deletion.CASCADE,
related_name="%(class)s_folder",
to="iam.folder",
),
),
(
"ro_to_couple",
models.ForeignKey(
help_text="RO/TO couple from which the attach path is derived",
on_delete=django.db.models.deletion.CASCADE,
to="ebios_rm.roto",
verbose_name="RO/TO couple",
),
),
],
options={
"verbose_name": "Strategic Scenario",
"verbose_name_plural": "Strategic Scenarios",
"ordering": ["created_at"],
},
),
migrations.AddField(
model_name="attackpath",
name="strategic_scenario",
field=models.ForeignKey(
default="",
help_text="Strategic scenario from which the attack path is derived",
on_delete=django.db.models.deletion.CASCADE,
related_name="attack_paths",
to="ebios_rm.strategicscenario",
verbose_name="Strategic scenario",
),
preserve_default=False,
),
]
Loading

0 comments on commit d796a00

Please sign in to comment.