diff --git a/apps/acls/api/command_acl.py b/apps/acls/api/command_acl.py index e78b18572..349190d00 100644 --- a/apps/acls/api/command_acl.py +++ b/apps/acls/api/command_acl.py @@ -1,6 +1,9 @@ from rest_framework.decorators import action from rest_framework.response import Response + +from common.drf.filters import BaseFilterSet from orgs.mixins.api import OrgBulkModelViewSet +from .common import ACLFiltersetMixin from .. import models, serializers __all__ = ['CommandFilterACLViewSet', 'CommandGroupViewSet'] @@ -13,10 +16,16 @@ class CommandGroupViewSet(OrgBulkModelViewSet): serializer_class = serializers.CommandGroupSerializer +class CommandACLFilter(ACLFiltersetMixin, BaseFilterSet): + class Meta: + model = models.CommandFilterACL + fields = ['name', 'users', 'assets'] + + class CommandFilterACLViewSet(OrgBulkModelViewSet): model = models.CommandFilterACL - filterset_fields = ('name',) - search_fields = filterset_fields + filterset_class = CommandACLFilter + search_fields = ['name'] serializer_class = serializers.CommandFilterACLSerializer rbac_perms = { 'command_review': 'tickets.add_superticket' diff --git a/apps/acls/api/common.py b/apps/acls/api/common.py new file mode 100644 index 000000000..621901471 --- /dev/null +++ b/apps/acls/api/common.py @@ -0,0 +1,39 @@ +from django_filters import rest_framework as drf_filters + +from common.drf.filters import BaseFilterSet +from common.utils import is_uuid + + +class ACLFiltersetMixin(BaseFilterSet): + users = drf_filters.CharFilter(method='filter_user') + assets = drf_filters.CharFilter(method='filter_asset') + + @staticmethod + def filter_user(queryset, name, value): + from users.models import User + if not value: + return queryset + if is_uuid(value): + user = User.objects.filter(id=value).first() + else: + user = User.objects.filter(name=value).first() + if not user: + return queryset.none() + q = queryset.model.users.get_filter_q(user) + return queryset.filter(q).distinct() + + @staticmethod + def filter_asset(queryset, name, value): + from assets.models import Asset + if not value: + return queryset + + if is_uuid(value): + asset = Asset.objects.filter(id=value).first() + else: + asset = Asset.objects.filter(name=value).first() + if not asset: + return queryset.none() + + q = queryset.model.assets.get_filter_q(asset) + return queryset.filter(q).distinct() diff --git a/apps/acls/api/login_asset_acl.py b/apps/acls/api/login_asset_acl.py index 1447c16d5..a2a662bfa 100644 --- a/apps/acls/api/login_asset_acl.py +++ b/apps/acls/api/login_asset_acl.py @@ -1,12 +1,19 @@ +from common.drf.filters import BaseFilterSet from orgs.mixins.api import OrgBulkModelViewSet +from .common import ACLFiltersetMixin from .. import models, serializers - __all__ = ['LoginAssetACLViewSet'] +class CommandACLFilter(ACLFiltersetMixin, BaseFilterSet): + class Meta: + model = models.LoginAssetACL + fields = ['name', 'users', 'assets'] + + class LoginAssetACLViewSet(OrgBulkModelViewSet): model = models.LoginAssetACL - filterset_fields = ('name', ) - search_fields = filterset_fields + filterset_class = CommandACLFilter + search_fields = ['name'] serializer_class = serializers.LoginAssetACLSerializer diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py index adfe94769..bc0795eab 100644 --- a/apps/common/db/fields.py +++ b/apps/common/db/fields.py @@ -502,7 +502,8 @@ class JSONManyToManyDescriptor: def get_filter_q(self, instance): model_cls = self.field.model field_name = self.field.column - q = Q(users__type='all') | Q(users__type='ids', users__ids__contains=[str(instance.id)]) + q = Q(**{f'{field_name}__type': 'all'}) | \ + Q(**{f'{field_name}__type': 'ids', f'{field_name}__ids__contains': [str(instance.id)]}) queryset_id_attrs = model_cls.objects \ .filter(**{'{}__type'.format(field_name): 'attrs'}) \ .values_list('id', '{}__attrs'.format(field_name))