From b4d67a0221cc74dbbbfe9da4d00fef35c62f9ff3 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 16:53:57 +0100 Subject: [PATCH 01/15] Write EbiosRMStudy ViewSet and Serializer classes Co-authored-by: Mohamed-Hacene --- backend/ebios_rm/serializers.py | 47 +++++++++++++++++++++++++++++++++ backend/ebios_rm/views.py | 26 ++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 backend/ebios_rm/serializers.py diff --git a/backend/ebios_rm/serializers.py b/backend/ebios_rm/serializers.py new file mode 100644 index 000000000..2c95f71eb --- /dev/null +++ b/backend/ebios_rm/serializers.py @@ -0,0 +1,47 @@ +from core.serializers import ( + BaseModelSerializer, + FieldsRelatedField, + AssessmentReadSerializer, +) +from core.models import StoredLibrary, RiskMatrix +from .models import EbiosRMStudy +from rest_framework import serializers +import logging + + +class EbiosRMStudyWriteSerializer(BaseModelSerializer): + def create(self, validated_data): + if not validated_data.get("risk_matrix"): + try: + ebios_matrix_library = StoredLibrary.objects.get( + urn="urn:intuitem:risk:library:risk-matrix-4x4-ebios-rm" + ) + ebios_matrix_library.load() + + validated_data["risk_matrix"] = RiskMatrix.objects.get( + urn="urn:intuitem:risk:matrix:risk-matrix-4x4-ebios-rm" + ) + except (StoredLibrary.DoesNotExist, RiskMatrix.DoesNotExist) as e: + logging.error(f"Error loading risk matrix: {str(e)}") + raise serializers.ValidationError( + "An error occurred while loading the risk matrix." + ) + return super().create(validated_data) + + class Meta: + model = EbiosRMStudy + exclude = ["created_at", "updated_at"] + + +class EbiosRMStudyReadSerializer(AssessmentReadSerializer): + str = serializers.CharField(source="__str__") + project = FieldsRelatedField(["id", "folder"]) + folder = FieldsRelatedField() + risk_matrix = FieldsRelatedField() + assets = FieldsRelatedField(many=True) + compliance_assessments = FieldsRelatedField(many=True) + risk_assessments = FieldsRelatedField(many=True) + + class Meta: + model = EbiosRMStudy + fields = "__all__" diff --git a/backend/ebios_rm/views.py b/backend/ebios_rm/views.py index 91ea44a21..50a2f2d10 100644 --- a/backend/ebios_rm/views.py +++ b/backend/ebios_rm/views.py @@ -1,3 +1,25 @@ -from django.shortcuts import render +from core.views import BaseModelViewSet as AbstractBaseModelViewSet +from .models import EbiosRMStudy +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_page +from rest_framework.decorators import action +from rest_framework.response import Response -# Create your views here. +LONG_CACHE_TTL = 60 # mn + + +class BaseModelViewSet(AbstractBaseModelViewSet): + serializers_module = "ebios_rm.serializers" + + +class EbiosRMStudyViewSet(BaseModelViewSet): + """ + API endpoint that allows ebios rm studies to be viewed or edited. + """ + + model = EbiosRMStudy + + @method_decorator(cache_page(60 * LONG_CACHE_TTL)) + @action(detail=False, name="Get status choices") + def status(self, request): + return Response(dict(EbiosRMStudy.Status.choices)) From 28882ebe64baf7150fadaddb61d6a0a26eb0b5f7 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 16:58:18 +0100 Subject: [PATCH 02/15] Create ebios-rm-studies routes --- backend/ebios_rm/urls.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 backend/ebios_rm/urls.py diff --git a/backend/ebios_rm/urls.py b/backend/ebios_rm/urls.py new file mode 100644 index 000000000..0e81b0fe6 --- /dev/null +++ b/backend/ebios_rm/urls.py @@ -0,0 +1,12 @@ +from django.urls import include, path +from rest_framework import routers + +from ebios_rm.views import EbiosRMStudyViewSet + +router = routers.DefaultRouter() + +router.register(r"ebios-rm-studies", EbiosRMStudyViewSet, basename="ebios-rm-studies") + +urlpatterns = [ + path("", include(router.urls)), +] From 266567fbb89a5fcf9bdb9aea4b76536dc68161b1 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 16:58:40 +0100 Subject: [PATCH 03/15] Include ebios-rm routes to core urls --- backend/core/urls.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/core/urls.py b/backend/core/urls.py index 5c5c5ddec..d0aa4054d 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -83,6 +83,7 @@ path("iam/", include("iam.urls")), path("serdes/", include("serdes.urls")), path("settings/", include("global_settings.urls")), + path("ebios-rm/", include("ebios_rm.urls")), path("csrf/", get_csrf_token, name="get_csrf_token"), path("build/", get_build, name="get_build"), path("evidences//upload/", UploadAttachmentView.as_view(), name="upload"), From 68e30138121f20f82f8cb98b9c51403464f2d954 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 16:59:51 +0100 Subject: [PATCH 04/15] Rename ebios-rm-studies route to studies So that the URL is /api/ebios-rm/studies --- backend/ebios_rm/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/ebios_rm/urls.py b/backend/ebios_rm/urls.py index 0e81b0fe6..264a41f2a 100644 --- a/backend/ebios_rm/urls.py +++ b/backend/ebios_rm/urls.py @@ -5,7 +5,7 @@ router = routers.DefaultRouter() -router.register(r"ebios-rm-studies", EbiosRMStudyViewSet, basename="ebios-rm-studies") +router.register(r"studies", EbiosRMStudyViewSet, basename="studies") urlpatterns = [ path("", include(router.urls)), From ffee2195ceacf9abe3dcaa72f95b5a3c5eb7c08f Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 17:22:55 +0100 Subject: [PATCH 05/15] Make ref_id optional --- ...rmstudy_ref_id_alter_fearedevent_ref_id.py | 22 +++++++++++++++++++ backend/ebios_rm/models.py | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py diff --git a/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py b/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py new file mode 100644 index 000000000..9559d23f0 --- /dev/null +++ b/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.1 on 2024-12-03 16:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("ebios_rm", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="ebiosrmstudy", + name="ref_id", + field=models.CharField(blank=True, max_length=100), + ), + migrations.AlterField( + model_name="fearedevent", + name="ref_id", + field=models.CharField(blank=True, max_length=100), + ), + ] diff --git a/backend/ebios_rm/models.py b/backend/ebios_rm/models.py index c800aa705..60a535154 100644 --- a/backend/ebios_rm/models.py +++ b/backend/ebios_rm/models.py @@ -64,7 +64,7 @@ class Status(models.TextChoices): default=Entity.get_main_entity, ) - ref_id = models.CharField(max_length=100) + ref_id = models.CharField(max_length=100, blank=True) version = models.CharField( max_length=100, blank=True, @@ -122,7 +122,7 @@ class FearedEvent(NameDescriptionMixin): help_text=_("Qualifications carried by the feared event"), ) - ref_id = models.CharField(max_length=100) + ref_id = models.CharField(max_length=100, blank=True) gravity = models.SmallIntegerField(default=-1, verbose_name=_("Gravity")) is_selected = models.BooleanField(verbose_name=_("Is selected"), default=False) justification = models.TextField(verbose_name=_("Justification"), blank=True) From b9ad9da8be87f1dace94499fdb436c3d06b96ffc Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 17:29:12 +0100 Subject: [PATCH 06/15] Set default matrix for studies on create at the serializer level --- backend/ebios_rm/serializers.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/ebios_rm/serializers.py b/backend/ebios_rm/serializers.py index 2c95f71eb..9b3a71cb6 100644 --- a/backend/ebios_rm/serializers.py +++ b/backend/ebios_rm/serializers.py @@ -10,6 +10,10 @@ class EbiosRMStudyWriteSerializer(BaseModelSerializer): + risk_matrix = serializers.PrimaryKeyRelatedField( + queryset=RiskMatrix.objects.all(), required=False + ) + def create(self, validated_data): if not validated_data.get("risk_matrix"): try: From 9845f188d2617fd635e0fdf963c330e48966e97b Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 17:29:37 +0100 Subject: [PATCH 07/15] Add ebios-rm permissions to administrator role --- backend/core/startup.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/backend/core/startup.py b/backend/core/startup.py index d74419221..833cff177 100644 --- a/backend/core/startup.py +++ b/backend/core/startup.py @@ -339,6 +339,30 @@ "view_filteringlabel", "change_filteringlabel", "delete_filteringlabel", + "add_ebiosrmstudy", + "view_ebiosrmstudy", + "change_ebiosrmstudy", + "delete_ebiosrmstudy", + "add_fearedevent", + "view_fearedevent", + "change_fearedevent", + "delete_fearedevent", + "add_roto", + "view_roto", + "change_roto", + "delete_roto", + "add_stakeholder", + "view_stakeholder", + "change_stakeholder", + "delete_stakeholder", + "add_attackpath", + "view_attackpath", + "change_attackpath", + "delete_attackpath", + "add_operationalscenario", + "view_operationalscenario", + "change_operationalscenario", + "delete_operationalscenario", ] THIRD_PARTY_RESPONDENT_PERMISSIONS_LIST = [ From 7fd435344c6ce49353632451c60a8f68325b7262 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 17:32:25 +0100 Subject: [PATCH 08/15] Try to get EBIOS RM matrix before loading the library --- backend/ebios_rm/serializers.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/backend/ebios_rm/serializers.py b/backend/ebios_rm/serializers.py index 9b3a71cb6..4dd2f6ccc 100644 --- a/backend/ebios_rm/serializers.py +++ b/backend/ebios_rm/serializers.py @@ -17,14 +17,18 @@ class EbiosRMStudyWriteSerializer(BaseModelSerializer): def create(self, validated_data): if not validated_data.get("risk_matrix"): try: - ebios_matrix_library = StoredLibrary.objects.get( - urn="urn:intuitem:risk:library:risk-matrix-4x4-ebios-rm" - ) - ebios_matrix_library.load() - - validated_data["risk_matrix"] = RiskMatrix.objects.get( + ebios_matrix = RiskMatrix.objects.filter( urn="urn:intuitem:risk:matrix:risk-matrix-4x4-ebios-rm" - ) + ).first() + if not ebios_matrix: + ebios_matrix_library = StoredLibrary.objects.get( + urn="urn:intuitem:risk:library:risk-matrix-4x4-ebios-rm" + ) + ebios_matrix_library.load() + ebios_matrix = RiskMatrix.objects.get( + urn="urn:intuitem:risk:matrix:risk-matrix-4x4-ebios-rm" + ) + validated_data["risk_matrix"] = ebios_matrix except (StoredLibrary.DoesNotExist, RiskMatrix.DoesNotExist) as e: logging.error(f"Error loading risk matrix: {str(e)}") raise serializers.ValidationError( From 479eacd57e789966cc2ccba830c9f4b98c6e06b8 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 17:38:00 +0100 Subject: [PATCH 09/15] Improve EbiosRMStudyReadSerializer --- backend/ebios_rm/serializers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/ebios_rm/serializers.py b/backend/ebios_rm/serializers.py index 4dd2f6ccc..918c36f64 100644 --- a/backend/ebios_rm/serializers.py +++ b/backend/ebios_rm/serializers.py @@ -41,14 +41,17 @@ class Meta: exclude = ["created_at", "updated_at"] -class EbiosRMStudyReadSerializer(AssessmentReadSerializer): +class EbiosRMStudyReadSerializer(BaseModelSerializer): str = serializers.CharField(source="__str__") project = FieldsRelatedField(["id", "folder"]) folder = FieldsRelatedField() risk_matrix = FieldsRelatedField() + reference_entity = FieldsRelatedField() assets = FieldsRelatedField(many=True) compliance_assessments = FieldsRelatedField(many=True) risk_assessments = FieldsRelatedField(many=True) + authors = FieldsRelatedField(many=True) + reviewers = FieldsRelatedField(many=True) class Meta: model = EbiosRMStudy From 60ed0751206624527e81e8df6f9d8873dc90e16a Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 19:45:27 +0100 Subject: [PATCH 10/15] Add FolderMixin to all EBIOS RM models --- ...path_folder_fearedevent_folder_and_more.py | 41 +++++++++++++++++++ backend/ebios_rm/models.py | 30 +++++++++++--- 2 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py diff --git a/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py b/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py new file mode 100644 index 000000000..96645fd64 --- /dev/null +++ b/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 5.1.1 on 2024-12-03 18:38 + +import django.db.models.deletion +import iam.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ebios_rm', '0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id'), + ('iam', '0009_create_allauth_emailaddress_objects'), + ] + + operations = [ + migrations.AddField( + model_name='attackpath', + name='folder', + field=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'), + ), + migrations.AddField( + model_name='fearedevent', + name='folder', + field=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'), + ), + migrations.AddField( + model_name='operationalscenario', + name='folder', + field=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'), + ), + migrations.AddField( + model_name='roto', + name='folder', + field=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'), + ), + migrations.AddField( + model_name='stakeholder', + name='folder', + field=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'), + ), + ] diff --git a/backend/ebios_rm/models.py b/backend/ebios_rm/models.py index 60a535154..99104508d 100644 --- a/backend/ebios_rm/models.py +++ b/backend/ebios_rm/models.py @@ -101,7 +101,7 @@ class Meta: ordering = ["created_at"] -class FearedEvent(NameDescriptionMixin): +class FearedEvent(NameDescriptionMixin, FolderMixin): ebios_rm_study = models.ForeignKey( EbiosRMStudy, verbose_name=_("EBIOS RM study"), @@ -132,8 +132,12 @@ class Meta: verbose_name_plural = _("Feared events") ordering = ["created_at"] + def save(self, *args, **kwargs): + self.folder = self.ebios_rm_study.folder + super().save(*args, **kwargs) -class RoTo(AbstractBaseModel): + +class RoTo(AbstractBaseModel, FolderMixin): class RiskOrigin(models.TextChoices): STATE = "state", _("State") ORGANIZED_CRIME = "organized_crime", _("Organized crime") @@ -206,8 +210,12 @@ class Meta: verbose_name_plural = _("RO/TO couples") ordering = ["created_at"] + def save(self, *args, **kwargs): + self.folder = self.ebios_rm_study.folder + super().save(*args, **kwargs) + -class Stakeholder(AbstractBaseModel): +class Stakeholder(AbstractBaseModel, FolderMixin): class Category(models.TextChoices): CLIENT = "client", _("Client") PARTNER = "partner", _("Partner") @@ -289,6 +297,10 @@ class Meta: verbose_name_plural = _("Stakeholders") ordering = ["created_at"] + def save(self, *args, **kwargs): + self.folder = self.ebios_rm_study.folder + super().save(*args, **kwargs) + @staticmethod def _compute_criticality( dependency: int, penetration: int, maturity: int, trust: int @@ -316,7 +328,7 @@ def residual_criticality(self): ) -class AttackPath(AbstractBaseModel): +class AttackPath(AbstractBaseModel, FolderMixin): ebios_rm_study = models.ForeignKey( EbiosRMStudy, verbose_name=_("EBIOS RM study"), @@ -344,8 +356,12 @@ class Meta: verbose_name_plural = _("Attack paths") ordering = ["created_at"] + def save(self, *args, **kwargs): + self.folder = self.ebios_rm_study.folder + super().save(*args, **kwargs) -class OperationalScenario(AbstractBaseModel): + +class OperationalScenario(AbstractBaseModel, FolderMixin): ebios_rm_study = models.ForeignKey( EbiosRMStudy, verbose_name=_("EBIOS RM study"), @@ -375,3 +391,7 @@ class Meta: verbose_name = _("Operational scenario") verbose_name_plural = _("Operational scenarios") ordering = ["created_at"] + + def save(self, *args, **kwargs): + self.folder = self.ebios_rm_study.folder + super().save(*args, **kwargs) From 9cedce48ec079fe145e96b4f82678f2706020f7f Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 19:45:34 +0100 Subject: [PATCH 11/15] Serialize FearedEvent --- backend/ebios_rm/serializers.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/ebios_rm/serializers.py b/backend/ebios_rm/serializers.py index 918c36f64..3507bf69f 100644 --- a/backend/ebios_rm/serializers.py +++ b/backend/ebios_rm/serializers.py @@ -4,7 +4,7 @@ AssessmentReadSerializer, ) from core.models import StoredLibrary, RiskMatrix -from .models import EbiosRMStudy +from .models import EbiosRMStudy, FearedEvent from rest_framework import serializers import logging @@ -56,3 +56,19 @@ class EbiosRMStudyReadSerializer(BaseModelSerializer): class Meta: model = EbiosRMStudy fields = "__all__" + + +class FearedEventWriteSerializer(BaseModelSerializer): + class Meta: + model = FearedEvent + exclude = ["created_at", "updated_at", "folder"] + + +class FearedEventReadSerializer(BaseModelSerializer): + str = serializers.CharField(source="__str__") + ebios_rm_study = FieldsRelatedField() + folder = FieldsRelatedField() + + class Meta: + model = FearedEvent + fields = "__all__" From 1805f11f1809f4db9b93311fc83ba86c6e6f126c Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 19:45:46 +0100 Subject: [PATCH 12/15] Add feared-events routes --- backend/ebios_rm/urls.py | 3 ++- backend/ebios_rm/views.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/backend/ebios_rm/urls.py b/backend/ebios_rm/urls.py index 264a41f2a..47ab37bcf 100644 --- a/backend/ebios_rm/urls.py +++ b/backend/ebios_rm/urls.py @@ -1,11 +1,12 @@ from django.urls import include, path from rest_framework import routers -from ebios_rm.views import EbiosRMStudyViewSet +from ebios_rm.views import EbiosRMStudyViewSet, FearedEventViewSet router = routers.DefaultRouter() router.register(r"studies", EbiosRMStudyViewSet, basename="studies") +router.register(r"feared-events", FearedEventViewSet, basename="feared-events") urlpatterns = [ path("", include(router.urls)), diff --git a/backend/ebios_rm/views.py b/backend/ebios_rm/views.py index 50a2f2d10..69676bf77 100644 --- a/backend/ebios_rm/views.py +++ b/backend/ebios_rm/views.py @@ -1,5 +1,5 @@ from core.views import BaseModelViewSet as AbstractBaseModelViewSet -from .models import EbiosRMStudy +from .models import EbiosRMStudy, FearedEvent from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from rest_framework.decorators import action @@ -23,3 +23,7 @@ class EbiosRMStudyViewSet(BaseModelViewSet): @action(detail=False, name="Get status choices") def status(self, request): return Response(dict(EbiosRMStudy.Status.choices)) + + +class FearedEventViewSet(BaseModelViewSet): + model = FearedEvent From 365b6c63975d289bb00f3bbc14968bd2375e32eb Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 19:46:10 +0100 Subject: [PATCH 13/15] Fit queryset regex to ebios-rm routes --- backend/core/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/core/views.py b/backend/core/views.py index ba3aadc7f..be431f545 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -102,7 +102,10 @@ def get_queryset(self): return None object_ids_view = None if self.request.method == "GET": - if q := re.match("/api/[\w-]+/([0-9a-f-]+)", self.request.path): + if q := re.match( + "/api/[\w-]+/([\w-]+/)?([0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}(,[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})+)", + self.request.path, + ): """"get_queryset is called by Django even for an individual object via get_object https://stackoverflow.com/questions/74048193/why-does-a-retrieve-request-end-up-calling-get-queryset""" id = UUID(q.group(1)) From 11dfb1f0f466218ab47dcfc6879f7541fadc38b2 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Tue, 3 Dec 2024 19:46:20 +0100 Subject: [PATCH 14/15] chore: ruff format --- ...path_folder_fearedevent_folder_and_more.py | 60 +++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py b/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py index 96645fd64..088a7c77b 100644 --- a/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py +++ b/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py @@ -6,36 +6,60 @@ class Migration(migrations.Migration): - dependencies = [ - ('ebios_rm', '0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id'), - ('iam', '0009_create_allauth_emailaddress_objects'), + ("ebios_rm", "0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id"), + ("iam", "0009_create_allauth_emailaddress_objects"), ] operations = [ migrations.AddField( - model_name='attackpath', - name='folder', - field=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'), + model_name="attackpath", + name="folder", + field=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", + ), ), migrations.AddField( - model_name='fearedevent', - name='folder', - field=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'), + model_name="fearedevent", + name="folder", + field=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", + ), ), migrations.AddField( - model_name='operationalscenario', - name='folder', - field=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'), + model_name="operationalscenario", + name="folder", + field=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", + ), ), migrations.AddField( - model_name='roto', - name='folder', - field=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'), + model_name="roto", + name="folder", + field=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", + ), ), migrations.AddField( - model_name='stakeholder', - name='folder', - field=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'), + model_name="stakeholder", + name="folder", + field=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", + ), ), ] From bc11fb0a335fd360ab578350d5c11ecacd4f0f12 Mon Sep 17 00:00:00 2001 From: Nassim Tabchiche Date: Wed, 4 Dec 2024 14:03:25 +0100 Subject: [PATCH 15/15] chore: Squash migrations --- backend/ebios_rm/migrations/0001_initial.py | 51 ++++++++++++++- ...rmstudy_ref_id_alter_fearedevent_ref_id.py | 22 ------- ...path_folder_fearedevent_folder_and_more.py | 65 ------------------- 3 files changed, 48 insertions(+), 90 deletions(-) delete mode 100644 backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py delete mode 100644 backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py diff --git a/backend/ebios_rm/migrations/0001_initial.py b/backend/ebios_rm/migrations/0001_initial.py index b0fb9dc58..66af48c5f 100644 --- a/backend/ebios_rm/migrations/0001_initial.py +++ b/backend/ebios_rm/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.1 on 2024-12-03 12:57 +# Generated by Django 5.1.1 on 2024-12-04 13:02 import django.core.validators import django.db.models.deletion @@ -54,7 +54,7 @@ class Migration(migrations.Migration): "due_date", models.DateField(blank=True, null=True, verbose_name="Due date"), ), - ("ref_id", models.CharField(max_length=100)), + ("ref_id", models.CharField(blank=True, max_length=100)), ( "version", models.CharField( @@ -205,6 +205,15 @@ class Migration(migrations.Migration): "justification", models.TextField(blank=True, verbose_name="Justification"), ), + ( + "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", + ), + ), ( "ebios_rm_study", models.ForeignKey( @@ -249,7 +258,7 @@ class Migration(migrations.Migration): "description", models.TextField(blank=True, null=True, verbose_name="Description"), ), - ("ref_id", models.CharField(max_length=100)), + ("ref_id", models.CharField(blank=True, max_length=100)), ( "gravity", models.SmallIntegerField(default=-1, verbose_name="Gravity"), @@ -280,6 +289,15 @@ class Migration(migrations.Migration): 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", + ), + ), ( "qualifications", models.ManyToManyField( @@ -352,6 +370,15 @@ class Migration(migrations.Migration): 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", + ), + ), ( "threats", models.ManyToManyField( @@ -488,6 +515,15 @@ class Migration(migrations.Migration): verbose_name="Feared events", ), ), + ( + "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", + ), + ), ], options={ "verbose_name": "RO/TO couple", @@ -655,6 +691,15 @@ class Migration(migrations.Migration): verbose_name="Entity", ), ), + ( + "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", + ), + ), ], options={ "verbose_name": "Stakeholder", diff --git a/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py b/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py deleted file mode 100644 index 9559d23f0..000000000 --- a/backend/ebios_rm/migrations/0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 5.1.1 on 2024-12-03 16:22 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("ebios_rm", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="ebiosrmstudy", - name="ref_id", - field=models.CharField(blank=True, max_length=100), - ), - migrations.AlterField( - model_name="fearedevent", - name="ref_id", - field=models.CharField(blank=True, max_length=100), - ), - ] diff --git a/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py b/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py deleted file mode 100644 index 088a7c77b..000000000 --- a/backend/ebios_rm/migrations/0003_attackpath_folder_fearedevent_folder_and_more.py +++ /dev/null @@ -1,65 +0,0 @@ -# Generated by Django 5.1.1 on 2024-12-03 18:38 - -import django.db.models.deletion -import iam.models -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("ebios_rm", "0002_alter_ebiosrmstudy_ref_id_alter_fearedevent_ref_id"), - ("iam", "0009_create_allauth_emailaddress_objects"), - ] - - operations = [ - migrations.AddField( - model_name="attackpath", - name="folder", - field=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", - ), - ), - migrations.AddField( - model_name="fearedevent", - name="folder", - field=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", - ), - ), - migrations.AddField( - model_name="operationalscenario", - name="folder", - field=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", - ), - ), - migrations.AddField( - model_name="roto", - name="folder", - field=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", - ), - ), - migrations.AddField( - model_name="stakeholder", - name="folder", - field=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", - ), - ), - ]