|
6 | 6 | Notes, DojoMeta, FindingImage
|
7 | 7 | from dojo.forms import ImportScanForm, SEVERITY_CHOICES
|
8 | 8 | from dojo.tools.factory import import_parser_factory
|
| 9 | +from dojo.utils import create_notification |
| 10 | +from django.urls import reverse |
| 11 | +from tagging.models import Tag |
9 | 12 | from django.core.validators import URLValidator, validate_ipv46_address
|
10 | 13 | from django.conf import settings
|
11 | 14 | from rest_framework import serializers
|
@@ -516,12 +519,10 @@ class ImportScanSerializer(TaggitSerializer, serializers.Serializer):
|
516 | 519 | default=None,
|
517 | 520 | queryset=User.objects.all())
|
518 | 521 | tags = TagListSerializerField(required=False)
|
519 |
| - skip_duplicates = serializers.BooleanField(required=False, default=False) |
520 | 522 | close_old_findings = serializers.BooleanField(required=False, default=False)
|
521 | 523 |
|
522 | 524 | def save(self):
|
523 | 525 | data = self.validated_data
|
524 |
| - skip_duplicates = data['skip_duplicates'] |
525 | 526 | close_old_findings = data['close_old_findings']
|
526 | 527 | active = data['active']
|
527 | 528 | verified = data['verified']
|
@@ -614,6 +615,52 @@ def save(self):
|
614 | 615 | except SyntaxError:
|
615 | 616 | raise Exception('Parser SyntaxError')
|
616 | 617 |
|
| 618 | + if close_old_findings: |
| 619 | + # Close old active findings that are not reported by this scan. |
| 620 | + new_hash_codes = test.finding_set.values('hash_code') |
| 621 | + |
| 622 | + old_findings = None |
| 623 | + if test.engagement.deduplication_on_engagement: |
| 624 | + old_findings = Finding.objects.exclude(test=test) \ |
| 625 | + .exclude(hash_code__in=new_hash_codes) \ |
| 626 | + .exclude(hash_code__in=skipped_hashcodes) \ |
| 627 | + .filter(test__engagement=test.engagement, |
| 628 | + test__test_type=test_type, |
| 629 | + active=True) |
| 630 | + else: |
| 631 | + old_findings = Finding.objects.exclude(test=test) \ |
| 632 | + .exclude(hash_code__in=new_hash_codes) \ |
| 633 | + .exclude(hash_code__in=skipped_hashcodes) \ |
| 634 | + .filter(test__engagement__product=test.engagement.product, |
| 635 | + test__test_type=test_type, |
| 636 | + active=True) |
| 637 | + |
| 638 | + for old_finding in old_findings: |
| 639 | + old_finding.active = False |
| 640 | + old_finding.mitigated = datetime.datetime.combine( |
| 641 | + test.target_start, |
| 642 | + timezone.now().time()) |
| 643 | + if settings.USE_TZ: |
| 644 | + old_finding.mitigated = timezone.make_aware( |
| 645 | + old_finding.mitigated, |
| 646 | + timezone.get_default_timezone()) |
| 647 | + old_finding.mitigated_by = self.context['request'].user |
| 648 | + old_finding.notes.create(author=self.context['request'].user, |
| 649 | + entry="This finding has been automatically closed" |
| 650 | + " as it is not present anymore in recent scans.") |
| 651 | + Tag.objects.add_tag(old_finding, 'stale') |
| 652 | + old_finding.save() |
| 653 | + title = 'An old finding has been closed for "{}".' \ |
| 654 | + .format(test.engagement.product.name) |
| 655 | + description = 'See <a href="{}">{}</a>' \ |
| 656 | + .format(reverse('view_finding', args=(old_finding.id, )), |
| 657 | + old_finding.title) |
| 658 | + create_notification(event='other', |
| 659 | + title=title, |
| 660 | + description=description, |
| 661 | + icon='bullseye', |
| 662 | + objowner=self.context['request'].user) |
| 663 | + |
617 | 664 | return test
|
618 | 665 |
|
619 | 666 | def validate_scan_data(self, value):
|
|
0 commit comments