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

String Based Filtering: Follow on for #10038 #10050

Merged
merged 4 commits into from
Apr 29, 2024

Update unit tests again

9d12461
Select commit
Loading
Failed to load commit list.
Merged

String Based Filtering: Follow on for #10038 #10050

Update unit tests again
9d12461
Select commit
Loading
Failed to load commit list.
DryRunSecurity / Authn/Authz Analyzer succeeded Apr 29, 2024 in 25s

DryRun Security

Details

Authn/Authz Analyzer Findings: 16 detected

⚠️ Potential Authn/Authz Function Used or Modified dojo/endpoint/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains the function get_authorized_endpoints(), which suggests that it is responsible for determining the list of endpoints that the user is authorized to access. This function is likely part of the authentication or authorization mechanism of the application.
Filename dojo/endpoint/views.py
CodeLink
endpoints = endpoints.prefetch_related('product', 'product__tags', 'tags').distinct()
endpoints = get_authorized_endpoints(Permissions.Endpoint_View, endpoints, request.user)
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = EndpointFilterWithoutObjectLookups if filter_string_matching else EndpointFilter
if host_view:
ids = get_endpoint_ids(filter_class(request.GET, queryset=endpoints, user=request.user).qs)
endpoints = filter_class(request.GET, queryset=endpoints.filter(id__in=ids), user=request.user)
else:
endpoints = filter_class(request.GET, queryset=endpoints, user=request.user)
paged_endpoints = get_page_items(request, endpoints.qs, 25)
⚠️ Potential Authn/Authz Function Used or Modified dojo/endpoint/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code includes the user_is_authorized decorator from the dojo.authorization.authorization_decorators module, which suggests that the code contains functions related to authorization. Additionally, the Permissions class from the dojo.authorization.roles_permissions module is imported, which also indicates the presence of authorization-related functionality.
Filename dojo/endpoint/views.py
CodeLink
from django.db.models import Q, QuerySet, Count
from dojo.endpoint.utils import clean_hosts_run, endpoint_meta_import
from dojo.filters import EndpointFilter, EndpointFilterWithoutObjectLookups
from dojo.forms import EditEndpointForm, \
DeleteEndpointForm, AddEndpointForm, DojoMetaDataForm, ImportEndpointMetaForm
from dojo.models import Product, Endpoint, Finding, DojoMeta, Endpoint_Status
from dojo.utils import get_page_items, add_breadcrumb, get_period_counts, Product_Tab, calculate_grade, redirect, \
add_error_message_to_response, is_scan_file_too_large, get_system_setting
from dojo.notifications.helper import create_notification
from dojo.authorization.authorization_decorators import user_is_authorized
from dojo.authorization.roles_permissions import Permissions
⚠️ Potential Authn/Authz Function Used or Modified dojo/engagement/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code includes the following functions that are commonly associated with authentication or authorization in web applications: PermissionDenied and HttpResponseRedirect. The PermissionDenied exception is typically raised when a user tries to access a resource they are not authorized to access, and HttpResponseRedirect is often used to redirect users to a login page or other authentication-related page.
Filename dojo/engagement/views.py
CodeLink
from django.core.exceptions import ValidationError, PermissionDenied
from django.urls import reverse, Resolver404
from django.db.models import Q, Count
from django.http import HttpResponseRedirect, StreamingHttpResponse, HttpResponse, FileResponse, QueryDict, HttpRequest
from django.shortcuts import render, get_object_or_404
from django.views.decorators.cache import cache_page
from django.utils import timezone
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains functions related to authentication and authorization, such as get_authorized_products() and get_authorized_users(), which are used to filter the queryset based on user permissions. These functions indicate that the code is handling access control and user authorization.
Filename dojo/filters.py
CodeLink
'test__engagement__product'].queryset = get_authorized_products(Permissions.Product_View)
class EngagementDirectFilterHelper(FilterSet):
name = CharFilter(lookup_expr="icontains", label="Engagement name contains")
version = CharFilter(field_name="version", lookup_expr="icontains", label="Engagement version")
test__version = CharFilter(field_name="test__version", lookup_expr="icontains", label="Test version")
product__name = CharFilter(lookup_expr="icontains", label="Product name contains")
status = MultipleChoiceFilter(choices=ENGAGEMENT_STATUS_CHOICES, label="Status")
tag = CharFilter(field_name="tags__name", lookup_expr="icontains", label="Tag name contains")
not_tag = CharFilter(field_name="tags__name", lookup_expr="icontains", label="Not tag name contains", exclude=True)
has_tags = BooleanFilter(field_name="tags", lookup_expr="isnull", exclude=True, label="Has tags")
test__engagement__product__lifecycle = MultipleChoiceFilter(
choices=Product.LIFECYCLE_CHOICES,
label="Product lifecycle",
null_label="Empty")
o = OrderingFilter(
# tuple-mapping retains order
fields=(
("target_start", "target_start"),
("name", "name"),
("product__name", "product__name"),
("product__prod_type__name", "product__prod_type__name"),
("lead__first_name", "lead__first_name"),
),
field_labels={
"target_start": "Start date",
"name": "Engagement",
"product__name": "Product Name",
"product__prod_type__name": "Product Type",
"lead__first_name": "Lead",
}
)
class EngagementDirectFilter(EngagementDirectFilterHelper, DojoFilter):
lead = ModelChoiceFilter(queryset=Dojo_User.objects.none(), label="Lead")
product__prod_type = ModelMultipleChoiceFilter(
queryset=Product_Type.objects.none(),
label="Product Type")
tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
queryset=Engagement.tags.tag_model.objects.all().order_by("name"))
not_tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
exclude=True,
queryset=Engagement.tags.tag_model.objects.all().order_by("name"))
def __init__(self, *args, **kwargs):
super(EngagementDirectFilter, self).__init__(*args, **kwargs)
self.form.fields["product__prod_type"].queryset = get_authorized_product_types(Permissions.Product_Type_View)
self.form.fields["lead"].queryset = get_authorized_users(Permissions.Product_Type_View) \
.filter(engagement__lead__isnull=False).distinct()
class Meta:
model = Engagement
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains two functions that appear to be related to authentication or authorization: get_authorized_users() and Permissions.Product_Type_View. The get_authorized_users() function seems to be used to filter the queryset of users based on their permissions, which suggests that it is related to authorization. The Permissions.Product_Type_View variable also suggests the existence of a permissions system, which is typically used for authorization.
Filename dojo/filters.py
CodeLink
field_labels={
'name': 'Engagement Name',
}
)
class Meta:
model = Product
fields = ['name']
class ProductEngagementFilter(ProductEngagementFilterHelper, DojoFilter):
lead = ModelChoiceFilter(queryset=Dojo_User.objects.none(), label="Lead")
tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
queryset=Engagement.tags.tag_model.objects.all().order_by("name"))
not_tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
exclude=True,
queryset=Engagement.tags.tag_model.objects.all().order_by("name"))
def __init__(self, *args, **kwargs):
super(ProductEngagementFilter, self).__init__(*args, **kwargs)
self.form.fields["lead"].queryset = get_authorized_users(
Permissions.Product_Type_View).filter(engagement__lead__isnull=False).distinct()
class ProductEngagementFilterWithoutObjectLookups(ProductEngagementFilterHelper, DojoFilter):
lead = CharFilter(
field_name="lead__username",
lookup_expr="iexact",
label="Lead Username",
help_text="Search for Lead username that are an exact match")
lead_contains = CharFilter(
field_name="lead__username",
lookup_expr="icontains",
label="Lead Username Contains",
help_text="Search for Lead username that contain a given pattern")
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')
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains a ProductFilter class that has an __init__ method that takes a user parameter. This suggests that the user parameter is used for authentication or authorization purposes, potentially to restrict the available product types that the user can view. Additionally, the get_authorized_product_types function is called in the __init__ method, which further indicates that the code is handling authentication or authorization logic.
Filename dojo/filters.py
CodeLink
'external_audience': 'External Audience ',
'internet_accessible': 'Internet Accessible ',
}
)
class ProductFilter(ProductFilterHelper, DojoFilter):
prod_type = ModelMultipleChoiceFilter(
queryset=Product_Type.objects.none(),
label="Product Type")
tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
queryset=Product.tags.tag_model.objects.all().order_by("name"))
not_tags = ModelMultipleChoiceFilter(
field_name="tags__name",
to_field_name="name",
exclude=True,
queryset=Product.tags.tag_model.objects.all().order_by("name"))
def __init__(self, *args, **kwargs):
self.user = None
if "user" in kwargs:
self.user = kwargs.pop("user")
super(ProductFilter, self).__init__(*args, **kwargs)
self.form.fields["prod_type"].queryset = get_authorized_product_types(Permissions.Product_Type_View)
class Meta:
model = Product
fields = [
"name", "name_exact", "prod_type", "business_criticality",
"platform", "lifecycle", "origin", "external_audience",
"internet_accessible", "tags"
]
class ProductFilterWithoutObjectLookups(ProductFilterHelper):
prod_type__name = CharFilter(
field_name="prod_type__name",
lookup_expr="iexact",
label="Product Type Name",
help_text="Search for Product Type names that are an exact match")
prod_type__name_contains = CharFilter(
field_name="prod_type__name",
lookup_expr="icontains",
label="Product Type Name Contains",
help_text="Search for Product Type names that contain a given pattern")
def __init__(self, *args, **kwargs):
kwargs.pop("user", None)
super(ProductFilterWithoutObjectLookups, self).__init__(*args, **kwargs)
class Meta:
model = Product
fields = [
"name", "name_exact", "business_criticality", "platform",
"lifecycle", "origin", "external_audience", "internet_accessible",
]
class ApiProductFilter(DojoFilter):
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains functions related to authentication and authorization, such as get_authorized_engagements() and get_authorized_product_types(). These functions likely perform checks to ensure the user has the necessary permissions to access the requested resources.
Filename dojo/filters.py
CodeLink
queryset=Product.tags.tag_model.objects.all().order_by('name'))
def __init__(self, *args, **kwargs):
if args[0]:
if args[0].get("start_date", "") != "" or args[0].get("end_date", "") != "":
args[0]._mutable = True
args[0]["date"] = 8
args[0]._mutable = False
self.pid = None
if "pid" in kwargs:
self.pid = kwargs.pop("pid")
super().__init__(*args, **kwargs)
if self.pid:
del self.form.fields["finding__test__engagement__product__prod_type"]
self.form.fields["finding__test__engagement"].queryset = Engagement.objects.filter(
product_id=self.pid
).all()
else:
self.form.fields["finding__test__engagement"].queryset = get_authorized_engagements(Permissions.Engagement_View).order_by("name")
if "finding__test__engagement__product__prod_type" in self.form.fields:
self.form.fields[
"finding__test__engagement__product__prod_type"].queryset = get_authorized_product_types(Permissions.Product_Type_View)
class Meta:
model = Endpoint_Status
exclude = ["last_modified", "endpoint", "finding"]
class MetricsEndpointFilterWithoutObjectLookups(MetricsEndpointFilterHelper, FindingTagStringFilter):
finding__test__engagement__product__prod_type = CharFilter(
field_name="finding__test__engagement__product__prod_type",
lookup_expr="iexact",
label="Product Type Name",
help_text="Search for Product Type names that are an exact match")
finding__test__engagement__product__prod_type_contains = CharFilter(
field_name="finding__test__engagement__product__prod_type",
lookup_expr="icontains",
label="Product Type Name Contains",
help_text="Search for Product Type names that contain a given pattern")
finding__test__engagement = CharFilter(
field_name="finding__test__engagement",
lookup_expr="iexact",
label="Engagement Name",
help_text="Search for Engagement names that are an exact match")
finding__test__engagement_contains = CharFilter(
field_name="finding__test__engagement",
lookup_expr="icontains",
label="Engagement Name Contains",
help_text="Search for Engagement names that contain a given pattern")
endpoint__tags_contains = CharFilter(
label="Endpoint Tag Contains",
field_name="endpoint__tags__name",
lookup_expr="icontains",
help_text="Search for tags on a Endpoint that contain a given pattern")
endpoint__tags = CharFilter(
label="Endpoint Tag",
field_name="endpoint__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Endpoint that are an exact match")
finding__tags_contains = CharFilter(
label="Finding Tag Contains",
field_name="finding__tags__name",
lookup_expr="icontains",
help_text="Search for tags on a Finding that contain a given pattern")
finding__tags = CharFilter(
label="Finding Tag",
field_name="finding__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Finding that are an exact match")
finding__test__tags_contains = CharFilter(
label="Test Tag Contains",
field_name="finding__test__tags__name",
lookup_expr="icontains",
help_text="Search for tags on a Finding that contain a given pattern")
finding__test__tags = CharFilter(
label="Test Tag",
field_name="finding__test__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Finding that are an exact match")
finding__test__engagement__tags_contains = CharFilter(
label="Engagement Tag Contains",
field_name="finding__test__engagement__tags__name",
lookup_expr="icontains",
help_text="Search for tags on a Finding that contain a given pattern")
finding__test__engagement__tags = CharFilter(
label="Engagement Tag",
field_name="finding__test__engagement__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Finding that are an exact match")
finding__test__engagement__product__tags_contains = CharFilter(
label="Product Tag Contains",
field_name="finding__test__engagement__product__tags__name",
lookup_expr="icontains",
help_text="Search for tags on a Finding that contain a given pattern")
finding__test__engagement__product__tags = CharFilter(
label="Product Tag",
field_name="finding__test__engagement__product__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Finding that are an exact match")
not_endpoint__tags_contains = CharFilter(
label="Endpoint Tag Does Not Contain",
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains a reporter and reviewers field in the FindingFilter class, which suggests that these fields are used to filter findings based on the user who reported or reviewed them. This indicates that the code may contain functions related to authentication or authorization, as the Dojo_User model is likely used to represent users who can report or review findings.
Filename dojo/filters.py
CodeLink
del self.form.fields['test__name_contains']
class FindingFilter(FindingFilterHelper, FindingTagFilter):
reporter = ModelMultipleChoiceFilter(queryset=Dojo_User.objects.none())
reviewers = ModelMultipleChoiceFilter(queryset=Dojo_User.objects.none())
test__engagement__product__prod_type = ModelMultipleChoiceFilter(
⚠️ Potential Authn/Authz Function Used or Modified dojo/filters.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains a function called get_authorized_endpoints that appears to be related to authorization. This function is used in the qs property of the EndpointFilterWithoutObjectLookups class, which suggests that it is used to filter the queryset based on the user's permissions. Additionally, the user attribute is set in the __init__ method of the class, which indicates that the user's information is being used in the filtering process.
Filename dojo/filters.py
CodeLink
not_findings__test__engagement__product__tags = CharFilter(
label="Not Product Tag",
field_name="findings__test__engagement__product__tags__name",
lookup_expr="iexact",
help_text="Search for tags on a Product that are an exact match, and exclude them",
exclude=True)
def __init__(self, *args, **kwargs):
self.user = None
if 'user' in kwargs:
self.user = kwargs.pop('user')
super(EndpointFilterWithoutObjectLookups, self).__init__(*args, **kwargs)
@property
def qs(self):
parent = super(EndpointFilterWithoutObjectLookups, self).qs
return get_authorized_endpoints(Permissions.Endpoint_View, parent)
class Meta:
model = Endpoint
exclude = ["findings", "inherited_tags", "product"]
class ApiEndpointFilter(DojoFilter):
⚠️ Potential Authn/Authz Function Used or Modified dojo/metrics/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code includes the import statement for Dojo_User, which suggests the presence of user-related functionality, potentially including authentication and authorization mechanisms.
Filename dojo/metrics/views.py
CodeLink
from django.views.decorators.cache import cache_page
from django.utils import timezone
from dojo.filters import (
MetricsEndpointFilter,
MetricsEndpointFilterWithoutObjectLookups,
MetricsFindingFilter,
MetricsFindingFilterWithoutObjectLookups,
UserFilter,
)
from dojo.forms import SimpleMetricsForm, ProductTypeCountsForm, ProductTagCountsForm
from dojo.models import Product_Type, Finding, Product, Engagement, Test, \
Risk_Acceptance, Dojo_User, Endpoint_Status
⚠️ Potential Authn/Authz Function Used or Modified dojo/metrics/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains the function 'get_authorized_endpoint_status' which is likely related to authorization. This function appears to be checking the permissions of the user to view the endpoints based on the 'Permissions.Endpoint_View' permission. This suggests that the code is handling authentication and authorization mechanisms.
Filename dojo/metrics/views.py
CodeLink
'finding__reporter')
endpoints_query = get_authorized_endpoint_status(Permissions.Endpoint_View, endpoints_query, request.user)
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = MetricsEndpointFilterWithoutObjectLookups if filter_string_matching else MetricsEndpointFilter
endpoints = filter_class(request.GET, queryset=endpoints_query)
form = endpoints.form
endpoints_qs = queryset_check(endpoints)
if not endpoints_qs:
⚠️ Potential Authn/Authz Function Used or Modified dojo/product/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains a reference to request.user, which is likely used for authentication or authorization purposes. The ProductFilterWithoutObjectLookups and ProductFilter classes may also contain functions related to authentication or authorization, as they are used to filter the product queryset based on the current user.
Filename dojo/product/views.py
CodeLink
# otherwise the paginator will perform all the annotations/prefetching already only to count the total number of records
# see https://code.djangoproject.com/ticket/23771 and https://code.djangoproject.com/ticket/25375
name_words = prods.values_list('name', flat=True)
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = ProductFilterWithoutObjectLookups if filter_string_matching else ProductFilter
prod_filter = filter_class(request.GET, queryset=prods, user=request.user)
prod_list = get_page_items(request, prod_filter.qs, 25)
⚠️ Potential Authn/Authz Function Used or Modified dojo/reports/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code imports the Dojo_User model, which is likely related to authentication and authorization functionality in the web application. The Dojo_User model is likely used to represent user accounts and manage user-related operations, such as authentication and authorization.
Filename dojo/reports/views.py
CodeLink
from django.views import View
from dojo.filters import ReportFindingFilter, EndpointReportFilter, \
EndpointFilter, EndpointFilterWithoutObjectLookups
from dojo.forms import ReportOptionsForm
from dojo.models import Product_Type, Finding, Product, Engagement, Test, \
Dojo_User, Endpoint, Risk_Acceptance
⚠️ Potential Authn/Authz Function Used or Modified dojo/product/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains the @user_is_authorized decorator, which is likely used to check if the user is authorized to access the view_engagements function. This function is related to authentication and authorization, as it involves handling user access control for the product engagements view.
Filename dojo/product/views.py
CodeLink
@user_is_authorized(Product, Permissions.Engagement_View, 'pid')
def view_engagements(request, pid):
prod = get_object_or_404(Product, id=pid)
default_page_num = 10
recent_test_day_count = 7
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = ProductEngagementFilterWithoutObjectLookups if filter_string_matching else ProductEngagementFilter
# In Progress Engagements
engs = Engagement.objects.filter(product=prod, active=True, status="In Progress").order_by('-updated')
active_engs_filter = filter_class(request.GET, queryset=engs, prefix='active')
result_active_engs = get_page_items(request, active_engs_filter.qs, default_page_num, prefix="engs")
# prefetch only after creating the filters to avoid https://code.djangoproject.com/ticket/23771
# and https://code.djangoproject.com/ticket/25375
result_active_engs.object_list = prefetch_for_view_engagements(
result_active_engs.object_list,
recent_test_day_count,
)
# Engagements that are queued because they haven't started or paused
engs = Engagement.objects.filter(~Q(status="In Progress"), product=prod, active=True).order_by('-updated')
queued_engs_filter = filter_class(request.GET, queryset=engs, prefix='queued')
result_queued_engs = get_page_items(request, queued_engs_filter.qs, default_page_num, prefix="queued_engs")
result_queued_engs.object_list = prefetch_for_view_engagements(
result_queued_engs.object_list,
recent_test_day_count,
)
# Cancelled or Completed Engagements
engs = Engagement.objects.filter(product=prod, active=False).order_by('-target_end')
inactive_engs_filter = filter_class(request.GET, queryset=engs, prefix='closed')
result_inactive_engs = get_page_items(request, inactive_engs_filter.qs, default_page_num, prefix="inactive_engs")
result_inactive_engs.object_list = prefetch_for_view_engagements(
result_inactive_engs.object_list,
recent_test_day_count,
)
product_tab = Product_Tab(prod, title=_("All Engagements"), tab="engagements")
return render(request, 'dojo/view_engagements.html', {
⚠️ Potential Authn/Authz Function Used or Modified dojo/reports/views.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains a reference to request.user, which suggests that it is handling user-specific information and may involve authentication or authorization functions. The EndpointFilter and EndpointFilterWithoutObjectLookups classes also suggest that the code is dealing with access control and authorization of users to access certain endpoints or resources.
Filename dojo/reports/views.py
CodeLink
finding__duplicate=False,
finding__out_of_scope=False,
).distinct()
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = EndpointFilterWithoutObjectLookups if filter_string_matching else EndpointFilter
endpoints = filter_class(request.GET, queryset=endpoints, user=request.user)
in_use_widgets = [ReportOptions(request=request)]
available_widgets = [CoverPage(request=request),
⚠️ Potential Authn/Authz Function Used or Modified dojo/reports/widgets.py (click for details)
Type Potential Authn/Authz Function Used or Modified
Description The code contains the user parameter and the request.user object, which are typically used for authentication and authorization purposes in web applications. The EndpointFilter and EndpointFilterWithoutObjectLookups classes may also be involved in the authorization process, as they are used to filter the Endpoint objects based on the user's permissions or access control settings.
Filename dojo/reports/widgets.py
CodeLink
d[item['name']] = item['value']
endpoints = Endpoint.objects.filter(id__in=endpoints)
filter_string_matching = get_system_setting("filter_string_matching", False)
filter_class = EndpointFilterWithoutObjectLookups if filter_string_matching else EndpointFilter
endpoints = filter_class(d, queryset=endpoints, user=request.user)
user_id = user.id if user is not None else None
endpoints = EndpointList(request=request, endpoints=endpoints, finding_notes=finding_notes,
finding_images=finding_images, host=host, user_id=user_id)