Skip to content

Commit 9df966e

Browse files
authored
Further filter fixes. (#547)
* Add query string to logging output. * Type checking fix (type->isinstance) * Fix filters for Mreg (HostPolicy outstanding). * Safer version of JSON filter to avoid SQL injections. * Refactor, cleanup. * Hostpolicy filter "fixes", also bump dependencies. - We are stuck on drf 3.14.0 due to encode/django-rest-framework#9358 until encode/django-rest-framework#9483 goes into prod, hopefully 3.15.3. * Skeleton for testing filters. * Add iexact support, add cases. Fix toml. * Move to ruff formater. * More tests. - Add ip support. - Add reverse lookups. * Hostpolicy filter tests. - Also reformat as per ruff. * Add a test for filtering on ?id= for hosts. - This should catch the generic issue of filtering on IDs. Ideally we'd do this for every model that supports ID... * support `__in`. * Support CIDR matching. - Match exact CIDR or IP within a CIDR.
1 parent 8952b79 commit 9df966e

File tree

8 files changed

+657
-130
lines changed

8 files changed

+657
-130
lines changed

hostpolicy/api/v1/views.py

+48-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
from rest_framework import status
33
from rest_framework.response import Response
44

5-
from django_filters import rest_framework as rest_filters
5+
from django_filters import rest_framework as filters
6+
from rest_framework import filters as rest_filters
67

78
from hostpolicy.api.permissions import IsSuperOrHostPolicyAdminOrReadOnly
89
from hostpolicy.models import HostPolicyAtom, HostPolicyRole
@@ -18,39 +19,71 @@
1819
from mreg.mixins import LowerCaseLookupMixin
1920
from mreg.models.host import Host
2021

21-
from . import serializers
22-
23-
# For some reason the name field for filtersets for HostPolicyAtom and HostPolicyRole does
24-
# not support operators (e.g. __contains, __regex) in the same way as other fields. Yes,
25-
# the name field is a LowerCaseCharField, but the operators work fine in mreg proper.
26-
# To resolve this issue, we create custom fields for the filtersets that use the name field.
22+
from mreg.api.v1.filters import STRING_OPERATORS, INT_OPERATORS
2723

28-
class HostPolicyAtomFilterSet(rest_filters.FilterSet):
29-
name__contains = rest_filters.CharFilter(field_name="name", lookup_expr="contains")
30-
name__regex = rest_filters.CharFilter(field_name="name", lookup_expr="regex")
24+
from . import serializers
3125

26+
# Note that related lookups don't work at the moment, so we need to do them explicitly.
27+
class HostPolicyAtomFilterSet(filters.FilterSet):
3228
class Meta:
3329
model = HostPolicyAtom
34-
fields = "__all__"
30+
fields = {
31+
"name": STRING_OPERATORS,
32+
"create_date": INT_OPERATORS,
33+
"updated_at": INT_OPERATORS,
34+
"description": STRING_OPERATORS,
35+
"roles": INT_OPERATORS,
36+
}
37+
3538

39+
class HostPolicyRoleFilterSet(filters.FilterSet):
40+
# This seems to be required due to the many-to-many relationships?
41+
atoms__name__exact = filters.CharFilter(field_name='atoms__name', lookup_expr='exact')
42+
atoms__name__contains = filters.CharFilter(field_name='atoms__name', lookup_expr='contains')
43+
atoms__name__regex = filters.CharFilter(field_name='atoms__name', lookup_expr='regex')
44+
45+
hosts__name__exact = filters.CharFilter(field_name='hosts__name', lookup_expr='exact')
46+
hosts__name__contains = filters.CharFilter(field_name='hosts__name', lookup_expr='contains')
47+
hosts__name__regex = filters.CharFilter(field_name='hosts__name', lookup_expr='regex')
48+
49+
labels__name__exact = filters.CharFilter(field_name='labels__name', lookup_expr='exact')
50+
labels__name__contains = filters.CharFilter(field_name='labels__name', lookup_expr='contains')
51+
labels__name__regex = filters.CharFilter(field_name='labels__name', lookup_expr='regex')
3652

37-
class HostPolicyRoleFilterSet(rest_filters.FilterSet):
38-
name__contains = rest_filters.CharFilter(field_name="name", lookup_expr="contains")
39-
name__regex = rest_filters.CharFilter(field_name="name", lookup_expr="regex")
4053
class Meta:
4154
model = HostPolicyRole
42-
fields = "__all__"
55+
fields = {
56+
"name": STRING_OPERATORS,
57+
"create_date": INT_OPERATORS,
58+
"updated_at": INT_OPERATORS,
59+
"hosts": INT_OPERATORS,
60+
"atoms": INT_OPERATORS,
61+
"labels": INT_OPERATORS,
62+
}
4363

4464
class HostPolicyAtomLogMixin(HistoryLog):
4565

4666
log_resource = 'hostpolicy_atom'
4767
model = HostPolicyAtom
68+
filter_backends = (
69+
rest_filters.SearchFilter,
70+
filters.DjangoFilterBackend,
71+
rest_filters.OrderingFilter,
72+
)
73+
ordering_fields = "__all__"
74+
4875

4976

5077
class HostPolicyRoleLogMixin(HistoryLog):
5178

5279
log_resource = 'hostpolicy_role'
5380
model = HostPolicyRole
81+
filter_backends = (
82+
rest_filters.SearchFilter,
83+
filters.DjangoFilterBackend,
84+
rest_filters.OrderingFilter,
85+
)
86+
ordering_fields = "__all__"
5487

5588

5689
class HostPolicyPermissionsListCreateAPIView(M2MPermissions,

0 commit comments

Comments
 (0)