Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add applied control duplication #940

Merged
merged 30 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6c96748
Add applied control duplication
monsieurswag Oct 15, 2024
aefec25
fix: add missing import
Mohamed-Hacene Oct 15, 2024
fc7135b
Formatter
monsieurswag Oct 15, 2024
8d22523
Fix missing fetch for model foreign keys
monsieurswag Oct 16, 2024
af3e7c9
Add an option to bring the evidences with the duplicated applied control
monsieurswag Oct 16, 2024
526d867
Merge branch 'main' into CA-503-Duplicate-applied-controls
monsieurswag Oct 16, 2024
a3df53d
Merge branch 'main' into CA-503-Duplicate-applied-controls
monsieurswag Oct 17, 2024
da4e076
Fix conflicts
monsieurswag Oct 21, 2024
edecfa0
Fix missing edit button
monsieurswag Oct 21, 2024
60c091d
Codefactor fix 1
monsieurswag Oct 21, 2024
6a78979
Codefactor fix 2
monsieurswag Oct 21, 2024
dc80e5b
Formatter
monsieurswag Oct 21, 2024
b6cf0f9
Remove dead code
monsieurswag Oct 21, 2024
6ccdfbe
Remove useless comments
monsieurswag Oct 23, 2024
e9ce72e
Merge branch 'main' into CA-503-Duplicate-applied-controls
monsieurswag Nov 12, 2024
e391800
Attempt to fix startup tests
monsieurswag Nov 12, 2024
f765433
Fix conflicts
monsieurswag Nov 26, 2024
4cf0ec0
Fix conflicts
monsieurswag Nov 26, 2024
07d09e2
Light optimization
monsieurswag Nov 26, 2024
2cd22e5
Fix non-working duplicate modal and remove 2 useless values from the …
monsieurswag Nov 27, 2024
4904783
Set the default translations
monsieurswag Nov 27, 2024
3e72c9e
chore: update translations with Fink 🐦
monsieurswag Nov 27, 2024
0756134
Fix conflicts
monsieurswag Dec 3, 2024
2d6595d
Merge branch 'main' into CA-503-Duplicate-applied-controls
monsieurswag Dec 4, 2024
40cd65a
Also copy ref_id when duplicating an AppliedControl
monsieurswag Dec 4, 2024
b413b5f
Fix conflicts
monsieurswag Dec 4, 2024
841e781
Formatter
monsieurswag Dec 4, 2024
0acd167
Copy owner when duplicating AppliedControl
monsieurswag Dec 4, 2024
9a555ff
Fix wrong assignment to AppliedControl.owner ManyToManyField
monsieurswag Dec 4, 2024
a9fc211
Merge branch 'main' into CA-503-Duplicate-applied-controls
monsieurswag Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ def duplicate_and_link_object(new_obj, duplicate_object, target_folder, field_na

# Get parent and sub-folders of the target folder
target_parent_folders = target_folder.get_parent_folders()
sub_folders = target_folder.sub_folders()
sub_folders = target_folder.get_sub_folders()

# Get all related objects for the specified field
related_objects = getattr(source_object, field_name).all()
Expand Down
3 changes: 0 additions & 3 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1787,9 +1787,6 @@ def risk_assessments(self):
def projects(self):
return {risk_assessment.project for risk_assessment in self.risk_assessments}

def parent_project(self):
pass

def __str__(self):
return self.name

Expand Down
11 changes: 9 additions & 2 deletions backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,15 @@ class AppliedControlReadSerializer(AppliedControlWriteSerializer):

ranking_score = serializers.IntegerField(source="get_ranking_score")
owner = FieldsRelatedField(many=True)
has_evidences = serializers.BooleanField()
eta_missed = serializers.BooleanField()
# These properties shouldn't be displayed in the frontend detail view as they are simple derivations from fields already displayed in the detail view.
# has_evidences = serializers.BooleanField()
# eta_missed = serializers.BooleanField()


class AppliedControlDuplicateSerializer(BaseModelSerializer):
class Meta:
model = AppliedControl
fields = ["name", "description", "folder"]


class PolicyWriteSerializer(AppliedControlWriteSerializer):
Expand Down
47 changes: 47 additions & 0 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,53 @@ def get_timeline_info(self, request):
colorMap[domain.name] = next(color_cycle)
return Response({"entries": entries, "colorMap": colorMap})

@action(
detail=True,
name="Duplicate applied control",
methods=["post"],
serializer_class=AppliedControlDuplicateSerializer,
)
def duplicate(self, request, pk):
(object_ids_view, _, _) = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, AppliedControl
)
if UUID(pk) not in object_ids_view:
return Response(
{"results": "applied control duplicated"},
status=status.HTTP_404_NOT_FOUND,
)

applied_control = self.get_object()
data = request.data
new_folder = Folder.objects.get(id=data["folder"])
duplicate_applied_control = AppliedControl.objects.create(
reference_control=applied_control.reference_control,
name=data["name"],
description=data["description"],
folder=new_folder,
ref_id=applied_control.ref_id,
category=applied_control.category,
csf_function=applied_control.csf_function,
priority=applied_control.priority,
status=applied_control.status,
start_date=applied_control.start_date,
eta=applied_control.eta,
expiry_date=applied_control.expiry_date,
link=applied_control.link,
effort=applied_control.effort,
cost=applied_control.cost,
)
duplicate_applied_control.owner.set(applied_control.owner.all())
if data["duplicate_evidences"]:
duplicate_related_objects(
applied_control, duplicate_applied_control, new_folder, "evidences"
)
duplicate_applied_control.save()

return Response(
{"results": AppliedControlReadSerializer(duplicate_applied_control).data}
)

@action(detail=False, methods=["get"])
def ids(self, request):
my_map = dict()
Expand Down
34 changes: 16 additions & 18 deletions backend/iam/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Inspired from Azure IAM model"""

from collections import defaultdict
from typing import Any, List, Self, Tuple
from typing import Any, List, Self, Tuple, Generator
import uuid
from allauth.account.models import EmailAddress
from django.utils import timezone
Expand Down Expand Up @@ -101,24 +101,22 @@ class Meta:
def __str__(self) -> str:
return self.name.__str__()

def sub_folders(self) -> List[Self]:
def get_sub_folders(self) -> Generator[Self, None, None]:
"""Return the list of subfolders"""

def sub_folders_in(f, sub_folder_list):
for sub_folder in f.folder_set.all():
sub_folder_list.append(sub_folder)
sub_folders_in(sub_folder, sub_folder_list)
return sub_folder_list
def sub_folders_in(folder):
for sub_folder in folder.folder_set.all():
yield sub_folder
yield from sub_folders_in(sub_folder)

return sub_folders_in(self, [])
yield from sub_folders_in(self)

def get_parent_folders(self) -> List[Self]:
# Should we update data-model.md now that this method is a generator ?
def get_parent_folders(self) -> Generator[Self, None, None]:
"""Return the list of parent folders"""
return (
[self.parent_folder] + Folder.get_parent_folders(self.parent_folder)
if self.parent_folder
else []
)
current_folder = self
while (current_folder := current_folder.parent_folder) is not None:
yield current_folder

@staticmethod
def _navigate_structure(start, path):
Expand Down Expand Up @@ -657,11 +655,11 @@ def get_accessible_folders(
]:
for f in ra.perimeter_folders.all():
folders_set.add(f)
folders_set.update(f.sub_folders())
folders_set.update(f.get_sub_folders())
# calculate perimeter
perimeter = set()
perimeter.add(folder)
perimeter.update(folder.sub_folders())
perimeter.update(folder.get_sub_folders())
# return filtered result
return [
x.id
Expand Down Expand Up @@ -698,7 +696,7 @@ def get_accessible_object_ids(
folder_for_object = {x: Folder.get_folder(x) for x in all_objects}
perimeter = set()
perimeter.add(folder)
perimeter.update(folder.sub_folders())
perimeter.update(folder.get_sub_folders())
for ra in [
x
for x in RoleAssignment.get_role_assignments(user)
Expand All @@ -707,7 +705,7 @@ def get_accessible_object_ids(
ra_permissions = ra.role.permissions.all()
for my_folder in perimeter & set(ra.perimeter_folders.all()):
target_folders = (
[my_folder] + my_folder.sub_folders()
[my_folder, *my_folder.get_sub_folders()]
if ra.is_recursive
else [my_folder]
)
Expand Down
5 changes: 4 additions & 1 deletion frontend/messages/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@
"back": "خلف",
"duplicate": "ينسخ",
"duplicateRiskAssessment": "تكرار تقييم المخاطر",
"duplicateAppliedControl": "تكرار عنصر التحكم المطبق",
"size": "الحجم",
"favicon": "الرمز المفضل",
"logo": "الشعار",
Expand Down Expand Up @@ -862,5 +863,7 @@
"tagsHelpText": "تُستخدم العلامات لتصنيف العناصر وتصفيتها. يمكنك إضافة علامات في قسم \"إضافي\"",
"forgotPassword": "هل نسيت كلمة السر",
"scoreSemiColon": "نتيجة:",
"mappingInferenceHelpText": "هذه المتغيرات ثابتة ولن تتغير اعتمادًا على المصدر."
"mappingInferenceHelpText": "هذه المتغيرات ثابتة ولن تتغير اعتمادًا على المصدر.",
"bringTheEvidences": "أحضر الأدلة",
"bringTheEvidencesHelpText": "في حالة التعطيل، سيتم تكرار الكائن بدون أدلته"
}
4 changes: 3 additions & 1 deletion frontend/messages/cz.json
Original file line number Diff line number Diff line change
Expand Up @@ -852,5 +852,7 @@
"exploreButton": "Prozkoumat",
"tags": "Štítky",
"addTag": "Přidat štítek",
"tagsHelpText": "Štítky pomáhají kategorizovat a filtrovat více objektů. Můžete je spravovat v menu Extra."
"tagsHelpText": "Štítky pomáhají kategorizovat a filtrovat více objektů. Můžete je spravovat v menu Extra.",
"bringTheEvidences": "Přineste důkazy",
"bringTheEvidencesHelpText": "Pokud je zakázáno, objekt bude duplikován bez jeho důkazů"
}
5 changes: 4 additions & 1 deletion frontend/messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Zurückkehren",
"duplicate": "Duplikat",
"duplicateRiskAssessment": "Duplizieren Sie die Risikobewertung",
"duplicateAppliedControl": "Duplizieren Sie das angewendete kontrolle",
"size": "Größe",
"favicon": "Favicon",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "Tags werden zum Kategorisieren und Filtern der Elemente verwendet. Sie können Tags im Abschnitt Extra hinzufügen",
"forgotPassword": "Passwort vergessen",
"scoreSemiColon": "Punktzahl:",
"mappingInferenceHelpText": "Diese Variablen sind fest und ändern sich je nach Quelle nicht."
"mappingInferenceHelpText": "Diese Variablen sind fest und ändern sich je nach Quelle nicht.",
"bringTheEvidences": "Bringen Sie die Beweise",
"bringTheEvidencesHelpText": "Wenn deaktiviert, wird das Objekt ohne seine Beweise dupliziert"
}
5 changes: 4 additions & 1 deletion frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@
"back": "Back",
"duplicate": "Duplicate",
"duplicateRiskAssessment": "Duplicate the risk assessment",
"duplicateAppliedControl": "Duplicate the applied control",
"size": "Size",
"favicon": "Favicon",
"logo": "Logo",
Expand Down Expand Up @@ -919,5 +920,7 @@
"ebiosWs5_3": "Define security measures",
"ebiosWs5_4": "Assess and document residual risks",
"ebiosWs5_5": "Establish risk monitoring framework",
"activity": "Activity"
"activity": "Activity",
"bringTheEvidences": "Bring the evidences",
"bringTheEvidencesHelpText": "If disabled, the object will be duplicated without its evidences"
}
5 changes: 4 additions & 1 deletion frontend/messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Devolver",
"duplicate": "Duplicar",
"duplicateRiskAssessment": "Duplicar la evaluación de riesgo",
"duplicateAppliedControl": "Duplicar el control aplicado",
"size": "Tamaño",
"favicon": "Favicon",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "Las etiquetas se utilizan para categorizar y filtrar los elementos. Puedes agregar etiquetas en la sección Extra",
"forgotPassword": "Has olvidado tu contraseña",
"scoreSemiColon": "Puntaje:",
"mappingInferenceHelpText": "Estas variables son fijas y no cambiarán dependiendo de la fuente."
"mappingInferenceHelpText": "Estas variables son fijas y no cambiarán dependiendo de la fuente.",
"bringTheEvidences": "Traer las evidencias",
"bringTheEvidencesHelpText": "Si está deshabilitado, el objeto se duplicará sin sus evidencias."
}
5 changes: 4 additions & 1 deletion frontend/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@
"back": "Retour",
"duplicate": "Dupliquer",
"duplicateRiskAssessment": "Dupliquer l’évaluation de risque",
"duplicateAppliedControl": "Dupliquer la mesure appliquée",
"size": "Taille",
"favicon": "Icône de favori",
"logo": "Logo",
Expand Down Expand Up @@ -895,5 +896,7 @@
"ebiosWs5_3": "Définir les mesures de sécurité",
"ebiosWs5_4": "Évaluer et documenter les risques résiduels",
"ebiosWs5_5": "Mettre en place le cadre de suivi des risques",
"activity": "Activité"
"activity": "Activité",
"bringTheEvidences": "Apportez les preuves",
"bringTheEvidencesHelpText": "Si désactivé, l'objet sera dupliqué sans ses preuves"
}
5 changes: 4 additions & 1 deletion frontend/messages/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "वापस",
"duplicate": "प्रतिलिपि",
"duplicateRiskAssessment": "जोखिम आकलन की प्रतिलिपि बनाएँ",
"duplicateAppliedControl": "लागू नियंत्रण की प्रतिलिपि बनाएँ",
"size": "आकार",
"favicon": "फ़ेविकॉन",
"logo": "प्रतीक चिन्ह",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "टैग का उपयोग आइटम को वर्गीकृत और फ़िल्टर करने के लिए किया जाता है। आप अतिरिक्त अनुभाग में टैग जोड़ सकते हैं",
"forgotPassword": "पासवर्ड भूल गए",
"scoreSemiColon": "अंक:",
"mappingInferenceHelpText": "ये चर निश्चित हैं और स्रोत के आधार पर परिवर्तित नहीं होंगे।"
"mappingInferenceHelpText": "ये चर निश्चित हैं और स्रोत के आधार पर परिवर्तित नहीं होंगे।",
"bringTheEvidences": "सबूत लाओ",
"bringTheEvidencesHelpText": "यदि अक्षम किया गया है, तो ऑब्जेक्ट को उसके साक्ष्य के बिना डुप्लिकेट किया जाएगा"
}
5 changes: 4 additions & 1 deletion frontend/messages/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Ripetere",
"duplicate": "Duplicare",
"duplicateRiskAssessment": "Duplicare la valutazione del rischio",
"duplicateAppliedControl": "Duplica il controllo applicato",
"size": "Dimensione",
"favicon": "Icona preferita",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "I tag vengono utilizzati per categorizzare e filtrare gli elementi. Puoi aggiungere tag nella sezione Extra",
"forgotPassword": "Ha dimenticato la password",
"scoreSemiColon": "Punto:",
"mappingInferenceHelpText": "Queste variabili sono fisse e non cambiano a seconda della fonte."
"mappingInferenceHelpText": "Queste variabili sono fisse e non cambiano a seconda della fonte.",
"bringTheEvidences": "Portare le prove",
"bringTheEvidencesHelpText": "Se disabilitato, l'oggetto verrà duplicato senza le sue prove"
}
5 changes: 4 additions & 1 deletion frontend/messages/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Opbrengst",
"duplicate": "Duplicaat",
"duplicateRiskAssessment": "Dupliceer de risicobeoordeling",
"duplicateAppliedControl": "Dupliceer de toegepaste controle",
"size": "Grootte",
"favicon": "Favorieten",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "Tags worden gebruikt om de items te categoriseren en te filteren. U kunt tags toevoegen in de sectie Extra",
"forgotPassword": "Wachtwoord vergeten",
"scoreSemiColon": "Punt:",
"mappingInferenceHelpText": "Deze variabelen zijn vast en veranderen niet, afhankelijk van de bron."
"mappingInferenceHelpText": "Deze variabelen zijn vast en veranderen niet, afhankelijk van de bron.",
"bringTheEvidences": "Breng de bewijzen",
"bringTheEvidencesHelpText": "Als dit is uitgeschakeld, wordt het object gedupliceerd zonder de bijbehorende bewijzen"
}
5 changes: 4 additions & 1 deletion frontend/messages/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Powrót",
"duplicate": "Duplikować",
"duplicateRiskAssessment": "Powielić ocenę ryzyka",
"duplicateAppliedControl": "Duplikuj zastosowaną kontrolę",
"size": "Rozmiar",
"favicon": "Favicon",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "Tagi służą do kategoryzowania i filtrowania elementów. Możesz dodać tagi w sekcji Extra",
"forgotPassword": "Zapomniałem hasła",
"scoreSemiColon": "Wynik:",
"mappingInferenceHelpText": "Te zmienne są stałe i nie zmieniają się w zależności od źródła."
"mappingInferenceHelpText": "Te zmienne są stałe i nie zmieniają się w zależności od źródła.",
"bringTheEvidences": "Przynieś dowody",
"bringTheEvidencesHelpText": "Jeśli wyłączone, obiekt zostanie zduplikowany bez dowodów"
}
5 changes: 4 additions & 1 deletion frontend/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Retornar",
"duplicate": "Duplicado",
"duplicateRiskAssessment": "Duplicar a avaliação de risco",
"duplicateAppliedControl": "Duplicar o controle aplicado",
"size": "Tamanho",
"favicon": "Favicon",
"logo": "Logotipo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "As tags são usadas para categorizar e filtrar os itens. Você pode adicionar tags na seção Extra",
"forgotPassword": "Esqueceu sua senha",
"scoreSemiColon": "Pontuação:",
"mappingInferenceHelpText": "Essas variáveis são fixas e não mudarão dependendo da fonte."
"mappingInferenceHelpText": "Essas variáveis são fixas e não mudarão dependendo da fonte.",
"bringTheEvidences": "Traga as evidências",
"bringTheEvidencesHelpText": "Se desabilitado, o objeto será duplicado sem suas evidências"
}
5 changes: 4 additions & 1 deletion frontend/messages/ro.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "Înapoi",
"duplicate": "Dublică",
"duplicateRiskAssessment": "Dublarea evaluării riscului",
"duplicateAppliedControl": "Duplicați control aplicat",
"size": "Mărime",
"favicon": "Favicon",
"logo": "Logo",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "Etichetele sunt folosite pentru a clasifica și filtra articolele. Puteți adăuga etichete în secțiunea Extra",
"forgotPassword": "Aţi uitat parola",
"scoreSemiColon": "Scor:",
"mappingInferenceHelpText": "Aceste variabile sunt fixe și nu se vor modifica în funcție de sursă."
"mappingInferenceHelpText": "Aceste variabile sunt fixe și nu se vor modifica în funcție de sursă.",
"bringTheEvidences": "Aduceți dovezile",
"bringTheEvidencesHelpText": "Dacă este dezactivat, obiectul va fi duplicat fără dovezile sale"
}
4 changes: 3 additions & 1 deletion frontend/messages/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -862,5 +862,7 @@
"forgotPassword": "Glömt lösenord",
"ssoSettingsUpdated": "SSO-inställningar uppdaterade",
"scoreSemiColon": "Göra:",
"mappingInferenceHelpText": "Dessa variabler är fasta och kommer inte att ändras beroende på källan."
"mappingInferenceHelpText": "Dessa variabler är fasta och kommer inte att ändras beroende på källan.",
"bringTheEvidences": "Kom med bevisen",
"bringTheEvidencesHelpText": "Om det är inaktiverat kommer objektet att dupliceras utan dess bevis"
}
5 changes: 4 additions & 1 deletion frontend/messages/ur.json
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@
"back": "واپس",
"duplicate": "نقل کریں",
"duplicateRiskAssessment": "خطرے کی تشخیص کو نقل کریں",
"duplicateAppliedControl": "لاگو کنٹرول کی نقل تیار کریں۔",
"size": "سائز",
"favicon": "فیویکان",
"logo": "لوگو",
Expand Down Expand Up @@ -861,5 +862,7 @@
"tagsHelpText": "ٹیگز اشیاء کی درجہ بندی اور فلٹر کرنے کے لیے استعمال ہوتے ہیں۔ آپ اضافی سیکشن میں ٹیگ شامل کر سکتے ہیں۔",
"forgotPassword": "پاس ورڈ بھول گئے۔",
"scoreSemiColon": "سکور:",
"mappingInferenceHelpText": "یہ متغیرات طے شدہ ہیں اور ماخذ کے لحاظ سے تبدیل نہیں ہوں گے۔"
"mappingInferenceHelpText": "یہ متغیرات طے شدہ ہیں اور ماخذ کے لحاظ سے تبدیل نہیں ہوں گے۔",
"bringTheEvidences": "ثبوت لے کر آئیں",
"bringTheEvidencesHelpText": "اگر غیر فعال ہو تو، اعتراض کو اس کے ثبوت کے بغیر نقل کر دیا جائے گا۔"
}
Loading
Loading