Skip to content

Commit 0df3a0c

Browse files
authored
Finding notes cascading deletes (#10636)
* finding-notes-cascading-deletes first pass at cascading deletes for notes/notehistory * finding-notes-cascading-deletes remove unused code * finding-notes-cascading-deletes linter cleanup * finding-notes-cascading-deletes retrigger actions
1 parent 4e29d72 commit 0df3a0c

11 files changed

Lines changed: 106 additions & 6 deletions

File tree

dojo/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,19 @@ def ready(self):
7272
# Load any signals here that will be ready for runtime
7373
# Importing the signals file is good enough if using the reciever decorator
7474
import dojo.announcement.signals # noqa: F401
75+
import dojo.benchmark.signals # noqa: F401
76+
import dojo.cred.signals # noqa: F401
7577
import dojo.endpoint.signals # noqa: F401
7678
import dojo.engagement.signals # noqa: F401
7779
import dojo.finding_group.signals # noqa: F401
80+
import dojo.notes.signals # noqa: F401
7881
import dojo.product.signals # noqa: F401
7982
import dojo.product_type.signals # noqa: F401
83+
import dojo.risk_acceptance.signals # noqa: F401
8084
import dojo.sla_config.helpers # noqa: F401
8185
import dojo.tags_signals # noqa: F401
8286
import dojo.test.signals # noqa: F401
87+
import dojo.tool_product.signals # noqa: F401
8388

8489

8590
def get_model_fields_with_extra(model, extra_fields=()):

dojo/benchmark/signals.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import logging
2+
3+
from django.db.models.signals import pre_delete
4+
from django.dispatch import receiver
5+
6+
from dojo.models import Benchmark_Product
7+
from dojo.notes.helper import delete_related_notes
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
@receiver(pre_delete, sender=Benchmark_Product)
13+
def benchmark_product_pre_delete(sender, instance, **kwargs):
14+
delete_related_notes(instance)

dojo/cred/signals.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import logging
2+
3+
from django.db.models.signals import pre_delete
4+
from django.dispatch import receiver
5+
6+
from dojo.models import Cred_User
7+
from dojo.notes.helper import delete_related_notes
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
@receiver(pre_delete, sender=Cred_User)
13+
def cred_user_pre_delete(sender, instance, **kwargs):
14+
delete_related_notes(instance)

dojo/engagement/signals.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from auditlog.models import LogEntry
22
from django.conf import settings
33
from django.contrib.contenttypes.models import ContentType
4-
from django.db.models.signals import post_delete, post_save, pre_save
4+
from django.db.models.signals import post_delete, post_save, pre_delete, pre_save
55
from django.dispatch import receiver
66
from django.urls import reverse
77
from django.utils.translation import gettext as _
88

99
from dojo.models import Engagement
10+
from dojo.notes.helper import delete_related_notes
1011
from dojo.notifications.helper import create_notification
1112

1213

@@ -55,3 +56,8 @@ def engagement_post_delete(sender, instance, using, origin, **kwargs):
5556
url=reverse('view_product', args=(instance.product.id, )),
5657
recipients=[instance.lead],
5758
icon="exclamation-triangle")
59+
60+
61+
@receiver(pre_delete, sender=Engagement)
62+
def engagement_pre_delete(sender, instance, **kwargs):
63+
delete_related_notes(instance)

dojo/finding/helper.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
Vulnerability_Id,
2424
Vulnerability_Id_Template,
2525
)
26+
from dojo.notes.helper import delete_related_notes
2627
from dojo.utils import get_current_user, mass_model_updater, to_str_typed
2728

2829
logger = logging.getLogger(__name__)
@@ -402,8 +403,8 @@ def finding_pre_delete(sender, instance, **kwargs):
402403
logger.debug('finding pre_delete: %d', instance.id)
403404
# this shouldn't be necessary as Django should remove any Many-To-Many entries automatically, might be a bug in Django?
404405
# https://code.djangoproject.com/ticket/154
405-
406406
instance.found_by.clear()
407+
delete_related_notes(instance)
407408

408409

409410
def finding_delete(instance, **kwargs):

dojo/notes/helper.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import logging
2+
3+
logger = logging.getLogger(__name__)
4+
5+
6+
def delete_related_notes(obj):
7+
if not hasattr(obj, 'notes'):
8+
logger.warning(f"Attempted to delete notes from object type {type(obj)} without 'notes' attribute.")
9+
return
10+
logging.debug(f"Deleting {obj.notes.count()} notes for {type(obj).__name__} {obj.id}")
11+
obj.notes.all().delete()

dojo/notes/signals.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import logging
2+
3+
from django.db.models.signals import pre_delete
4+
from django.dispatch import receiver
5+
6+
from dojo.models import Notes
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
def delete_note_history(note):
12+
logging.debug(f"Deleting history for note {note.id}")
13+
note.history.all().delete()
14+
15+
16+
@receiver(pre_delete, sender=Notes)
17+
def note_pre_delete(sender, instance, **kwargs):
18+
delete_note_history(instance)

dojo/risk_acceptance/helper.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ def delete(eng, risk_acceptance):
9898
eng.risk_acceptance.remove(risk_acceptance)
9999
eng.save()
100100

101-
for note in risk_acceptance.notes.all():
102-
note.delete()
103-
104101
risk_acceptance.path.delete()
105102
risk_acceptance.delete()
106103

dojo/risk_acceptance/signals.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import logging
2+
3+
from django.db.models.signals import pre_delete
4+
from django.dispatch import receiver
5+
6+
from dojo.models import Risk_Acceptance
7+
from dojo.notes.helper import delete_related_notes
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
@receiver(pre_delete, sender=Risk_Acceptance)
13+
def risk_acceptance_pre_delete(sender, instance, **kwargs):
14+
delete_related_notes(instance)

dojo/test/signals.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
from auditlog.models import LogEntry
44
from django.conf import settings
55
from django.contrib.contenttypes.models import ContentType
6-
from django.db.models.signals import post_delete, pre_save
6+
from django.db.models.signals import post_delete, pre_delete, pre_save
77
from django.dispatch import receiver
88
from django.urls import reverse
99
from django.utils.translation import gettext as _
1010

1111
from dojo.models import Finding, Test
12+
from dojo.notes.helper import delete_related_notes
1213
from dojo.notifications.helper import create_notification
1314

1415

@@ -49,3 +50,8 @@ def update_found_by_for_findings(sender, instance, **kwargs):
4950
for find in findings:
5051
find.found_by.remove(old_test_type)
5152
find.found_by.add(new_test_type)
53+
54+
55+
@receiver(pre_delete, sender=Test)
56+
def test_pre_delete(sender, instance, **kwargs):
57+
delete_related_notes(instance)

0 commit comments

Comments
 (0)