Skip to content

Commit

Permalink
Merge pull request #11887 from DefectDojo/release/2.43.4
Browse files Browse the repository at this point in the history
Release: Merge release into master from: release/2.43.4
  • Loading branch information
rossops authored Feb 24, 2025
2 parents 2df98da + a7383ef commit 400437f
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 42 deletions.
2 changes: 1 addition & 1 deletion components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "defectdojo",
"version": "2.43.3",
"version": "2.43.4",
"license" : "BSD-3-Clause",
"private": true,
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion dojo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# Django starts so that shared_task will use this app.
from .celery import app as celery_app # noqa: F401

__version__ = "2.43.3"
__version__ = "2.43.4"
__url__ = "https://github.com/DefectDojo/django-DefectDojo"
__docs__ = "https://documentation.defectdojo.com"
135 changes: 103 additions & 32 deletions dojo/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.apps import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import JSONField, Q
from django.db.models import Count, JSONField, Q
from django.forms import HiddenInput
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -135,6 +135,20 @@ def __init__(self, *args, **kwargs):
super(CharFilter, self).__init__(*args, **kwargs)


class CharFieldFilterANDExpression(CharFieldInFilter):
def filter(self, queryset, value):
# Catch the case where a value if not supplied
if not value:
return queryset
# Do the filtering
objects = set(value.split(","))
return (
queryset.filter(**{f"{self.field_name}__in": objects})
.annotate(object_count=Count(self.field_name))
.filter(object_count=len(objects))
)


class FindingStatusFilter(ChoiceFilter):
def any(self, qs, name):
return qs
Expand Down Expand Up @@ -1204,11 +1218,20 @@ class ProductEngagementFilterWithoutObjectLookups(ProductEngagementFilterHelper,
class ApiEngagementFilter(DojoFilter):
product__prod_type = NumberInFilter(field_name="product__prod_type", lookup_expr="in")
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")
product__tags = CharFieldInFilter(field_name="product__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on product")
tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
product__tags = CharFieldInFilter(
field_name="product__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on product (uses OR for multiple values)")
product__tags__and = CharFieldFilterANDExpression(
field_name="product__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on product")

not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
Expand Down Expand Up @@ -1365,9 +1388,13 @@ class ApiProductFilter(DojoFilter):
regulations = NumberInFilter(field_name="regulations", lookup_expr="in")

tag = CharFilter(field_name="tags__name", lookup_expr="icontains", label="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")

tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags not present on product", exclude="True")
Expand Down Expand Up @@ -1511,16 +1538,34 @@ class ApiFindingFilter(DojoFilter):
risk_acceptance = extend_schema_field(OpenApiTypes.NUMBER)(ReportRiskAcceptanceFilter())

tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")
test__tags = CharFieldInFilter(field_name="test__tags__name", lookup_expr="in", help_text="Comma separated list of exact tags present on test")
test__engagement__tags = CharFieldInFilter(field_name="test__engagement__tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags present on engagement")
tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
test__tags = CharFieldInFilter(
field_name="test__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on test (uses OR for multiple values)")
test__tags__and = CharFieldFilterANDExpression(
field_name="test__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on test")
test__engagement__tags = CharFieldInFilter(
field_name="test__engagement__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on engagement (uses OR for multiple values)")
test__engagement__tags__and = CharFieldFilterANDExpression(
field_name="test__engagement__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on engagement")
test__engagement__product__tags = CharFieldInFilter(
field_name="test__engagement__product__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on product")

help_text="Comma separated list of exact tags present on product (uses OR for multiple values)")
test__engagement__product__tags__and = CharFieldFilterANDExpression(
field_name="test__engagement__product__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on product")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags not present on model", exclude="True")
Expand Down Expand Up @@ -2118,9 +2163,13 @@ def __init__(self, *args, **kwargs):

class ApiTemplateFindingFilter(DojoFilter):
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")

tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags not present on model", exclude="True")
Expand Down Expand Up @@ -2695,9 +2744,13 @@ class Meta:

class ApiEndpointFilter(DojoFilter):
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")

tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags not present on model", exclude="True")
Expand Down Expand Up @@ -2851,13 +2904,27 @@ def __init__(self, *args, **kwargs):

class ApiTestFilter(DojoFilter):
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")
engagement__tags = CharFieldInFilter(field_name="engagement__tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags present on engagement")
engagement__product__tags = CharFieldInFilter(field_name="engagement__product__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on product")
tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
engagement__tags = CharFieldInFilter(
field_name="engagement__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on engagement (uses OR for multiple values)")
engagement__tags__and = CharFieldFilterANDExpression(
field_name="engagement__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on engagement")
engagement__product__tags = CharFieldInFilter(
field_name="engagement__product__tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags present on product (uses OR for multiple values)")
engagement__product__tags__and = CharFieldFilterANDExpression(
field_name="engagement__product__tags__name",
help_text="Comma separated list of exact tags to match with an AND expression present on product")

not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
Expand Down Expand Up @@ -2905,9 +2972,13 @@ class Meta:

class ApiAppAnalysisFilter(DojoFilter):
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Tag name contains")
tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags")

tags = CharFieldInFilter(
field_name="tags__name",
lookup_expr="in",
help_text="Comma separated list of exact tags (uses OR for multiple values)")
tags__and = CharFieldFilterANDExpression(
field_name="tags__name",
help_text="Comma separated list of exact tags to match with an AND expression")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", help_text="Not Tag name contains", exclude="True")
not_tags = CharFieldInFilter(field_name="tags__name", lookup_expr="in",
help_text="Comma separated list of exact tags not present on model", exclude="True")
Expand Down
8 changes: 4 additions & 4 deletions dojo/survey/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,17 +539,17 @@ def edit_question(request, qid):
extra_tags="alert-info")
type = str(ContentType.objects.get_for_model(question))

if type == "dojo | text question":
if type in {"dojo | text question", "Defect Dojo | text question"}:
form = EditTextQuestionForm(instance=question)
elif type == "dojo | choice question":
elif type in {"dojo | choice question", "Defect Dojo | choice question"}:
form = EditChoiceQuestionForm(instance=question)
else:
raise Http404

if request.method == "POST":
if type == "dojo | text question":
if type in {"dojo | text question", "Defect Dojo | text question"}:
form = EditTextQuestionForm(request.POST, instance=question)
elif type == "dojo | choice question":
elif type in {"dojo | choice question", "Defect Dojo | choice question"}:
form = EditChoiceQuestionForm(request.POST, instance=question)
else:
raise Http404
Expand Down
3 changes: 3 additions & 0 deletions dojo/tools/zap/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def get_description_for_scan_types(self, scan_type):
return "ZAP XML report format."

def get_findings(self, file, test):
if not file.name.endswith(".xml"):
msg = "Internal error: Wrong file format, please use xml."
raise ValueError(msg)
tree = ET.parse(file)
items = []
for node in tree.findall("site"):
Expand Down
4 changes: 2 additions & 2 deletions helm/defectdojo/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
apiVersion: v2
appVersion: "2.43.3"
appVersion: "2.43.4"
description: A Helm chart for Kubernetes to install DefectDojo
name: defectdojo
version: 1.6.174
version: 1.6.175
icon: https://www.defectdojo.org/img/favicon.ico
maintainers:
- name: madchap
Expand Down
4 changes: 2 additions & 2 deletions unittests/dojo_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -716,8 +716,8 @@ def get_finding_tags_api(self, finding_id):
response = self.do_finding_tags_api(self.client.get, finding_id)
return response.data

def get_finding_api_filter_tags(self, tags):
response = self.client.get(reverse("finding-list") + f"?tags={tags}", format="json")
def get_finding_api_filter_tags(self, tags, parameter="tags"):
response = self.client.get(reverse("finding-list") + f"?{parameter}={tags}", format="json")
self.assertEqual(200, response.status_code, response.content[:1000])
return response.data

Expand Down
6 changes: 6 additions & 0 deletions unittests/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ def test_finding_filter_tags(self):

response = self.get_finding_api_filter_tags("tag4")
self.assertEqual(response["count"], 0)
# Test the tags__and filter for a case with no matches
response = self.get_finding_api_filter_tags("tag2,tag3", parameter="tags__and")
self.assertEqual(response["count"], 0)
# Test the tags__and filter for a case with one exact match
response = self.get_finding_api_filter_tags("tag1,tag2", parameter="tags__and")
self.assertEqual(response["count"], 1)

def test_finding_post_tags(self):
# create finding
Expand Down

0 comments on commit 400437f

Please sign in to comment.