Skip to content

Commit

Permalink
Fix engagements filters in 'engagements by product view' (DefectDojo#…
Browse files Browse the repository at this point in the history
…10046)

* fix engagements filters in 'engagements by product view'

* fix linter

* add filtering without object lookups

* fix imports order
  • Loading branch information
davidhernandeze authored Apr 30, 2024
1 parent b007d28 commit 0fa2d45
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
10 changes: 7 additions & 3 deletions dojo/engagement/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
EngagementFilterWithoutObjectLookups,
EngagementTestFilter,
EngagementTestFilterWithoutObjectLookups,
ProductEngagementsFilter,
ProductEngagementsFilterWithoutObjectLookups,
)
from dojo.finding.helper import NOT_ACCEPTED_FINDINGS_QUERY
from dojo.finding.views import find_available_notetypes
Expand Down Expand Up @@ -215,8 +217,11 @@ def engagements_all(request):
products_with_engagements = products_with_engagements.filter(~Q(engagement=None)).distinct()

# count using prefetch instead of just using 'engagement__set_test_test` to avoid loading all test in memory just to count them
filter_string_matching = get_system_setting('filter_string_matching', False)
products_filter_class = ProductEngagementsFilterWithoutObjectLookups if filter_string_matching else ProductEngagementsFilter
engagement_query = Engagement.objects.annotate(test_count=Count('test__id'))
filter_qs = products_with_engagements.prefetch_related(
Prefetch('engagement_set', queryset=Engagement.objects.all().annotate(test_count=Count('test__id')))
Prefetch('engagement_set', queryset=products_filter_class(request.GET, engagement_query).qs)
)

filter_qs = filter_qs.prefetch_related(
Expand All @@ -230,15 +235,14 @@ def engagements_all(request):
'engagement_set__jira_project__jira_instance',
'jira_project_set__jira_instance'
)
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = EngagementFilterWithoutObjectLookups if filter_string_matching else EngagementFilter
filtered = filter_class(
request.GET,
queryset=filter_qs
)

prods = get_page_items(request, filtered.qs, 25)

prods.paginator.count = sum(len(prod.engagement_set.all()) for prod in prods)
name_words = products_with_engagements.values_list('name', flat=True)
eng_words = get_authorized_engagements(Permissions.Engagement_View).values_list('name', flat=True).distinct()

Expand Down
26 changes: 26 additions & 0 deletions dojo/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,32 @@ class Meta:
fields = ['name', 'prod_type']


class ProductEngagementsFilter(DojoFilter):
engagement__name = CharFilter(field_name='name', lookup_expr='icontains', label='Engagement name contains')
engagement__lead = ModelChoiceFilter(field_name='lead', queryset=Dojo_User.objects.none(), label="Lead")
engagement__version = CharFilter(field_name='version', lookup_expr='icontains', label='Engagement version')
engagement__test__version = CharFilter(field_name='test__version', lookup_expr='icontains', label='Test version')
engagement__status = MultipleChoiceFilter(field_name='status', choices=ENGAGEMENT_STATUS_CHOICES,
label="Status")

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form.fields['engagement__lead'].queryset = get_authorized_users(Permissions.Product_Type_View) \
.filter(engagement__lead__isnull=False).distinct()

class Meta:
model = Engagement
fields = []


class ProductEngagementsFilterWithoutObjectLookups(ProductEngagementsFilter):
engagement__lead = CharFilter(
field_name="lead__username",
lookup_expr="iexact",
label="Lead Username",
help_text="Search for Lead username that are an exact match")


class EngagementFilterWithoutObjectLookups(EngagementFilterHelper):
engagement__lead = CharFilter(
field_name="engagement__lead__username",
Expand Down

0 comments on commit 0fa2d45

Please sign in to comment.