From 268b6a7ad4067380a93ad5634b1cdeb94e5d3f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 13 Jan 2015 18:37:25 +0100 Subject: [PATCH] Issue #1886: Bad request when use project.slug instead project.id in API calls --- taiga/base/filters.py | 31 ++++++++++++++----- .../test_issues_resources.py | 19 ++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/taiga/base/filters.py b/taiga/base/filters.py index 7be6fcbd..5c73ed95 100644 --- a/taiga/base/filters.py +++ b/taiga/base/filters.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import operator from functools import reduce +import logging from django.db.models import Q from django.db.models.sql.where import ExtraWhere, OR, AND @@ -22,9 +23,12 @@ from django.db.models.sql.where import ExtraWhere, OR, AND from rest_framework import filters from taiga.base import tags +from taiga.base import exceptions as exc from taiga.projects.models import Membership +logger = logging.getLogger(__name__) + class QueryParamsFilterMixin(filters.BaseFilterBackend): _special_values_dict = { @@ -92,8 +96,13 @@ class PermissionBasedFilterBackend(FilterBackend): def filter_queryset(self, request, queryset, view): project_id = None - if hasattr(view, "filter_fields") and "project" in view.filter_fields: - project_id = request.QUERY_PARAMS.get("project", None) + if (hasattr(view, "filter_fields") and "project" in view.filter_fields and + "project" in request.QUERY_PARAMS): + try: + project_id = int(request.QUERY_PARAMS["project"]) + except: + logger.error("Filtering project diferent value than an integer: {}".format(request.QUERY_PARAMS["project"])) + raise exc.BadRequest("'project' must be an integer value.") qs = queryset @@ -103,11 +112,13 @@ class PermissionBasedFilterBackend(FilterBackend): memberships_qs = Membership.objects.filter(user=request.user) if project_id: memberships_qs = memberships_qs.filter(project_id=project_id) - memberships_qs = memberships_qs.filter(Q(role__permissions__contains=[self.permission]) | Q(is_owner=True)) + memberships_qs = memberships_qs.filter(Q(role__permissions__contains=[self.permission]) | + Q(is_owner=True)) projects_list = [membership.project_id for membership in memberships_qs] - qs = qs.filter(Q(project_id__in=projects_list) | Q(project__public_permissions__contains=[self.permission])) + qs = qs.filter(Q(project_id__in=projects_list) | + Q(project__public_permissions__contains=[self.permission])) else: qs = qs.filter(project__anon_permissions__contains=[self.permission]) @@ -171,8 +182,13 @@ class CanViewWikiAttachmentFilterBackend(PermissionBasedAttachmentFilterBackend) class CanViewProjectObjFilterBackend(FilterBackend): def filter_queryset(self, request, queryset, view): project_id = None - if hasattr(view, "filter_fields") and "project" in view.filter_fields: - project_id = request.QUERY_PARAMS.get("project", None) + if (hasattr(view, "filter_fields") and "project" in view.filter_fields and + "project" in request.QUERY_PARAMS): + try: + project_id = int(request.QUERY_PARAMS["project"]) + except: + logger.error("Filtering project diferent value than an integer: {}".format(request.QUERY_PARAMS["project"])) + raise exc.BadRequest("'project' must be an integer value.") qs = queryset @@ -182,7 +198,8 @@ class CanViewProjectObjFilterBackend(FilterBackend): memberships_qs = Membership.objects.filter(user=request.user) if project_id: memberships_qs = memberships_qs.filter(project_id=project_id) - memberships_qs = memberships_qs.filter(Q(role__permissions__contains=['view_project']) | Q(is_owner=True)) + memberships_qs = memberships_qs.filter(Q(role__permissions__contains=['view_project']) | + Q(is_owner=True)) projects_list = [membership.project_id for membership in memberships_qs] diff --git a/tests/integration/resources_permissions/test_issues_resources.py b/tests/integration/resources_permissions/test_issues_resources.py index d4895443..d451b794 100644 --- a/tests/integration/resources_permissions/test_issues_resources.py +++ b/tests/integration/resources_permissions/test_issues_resources.py @@ -205,6 +205,25 @@ def test_issue_list(client, data): assert response.status_code == 200 +def test_issue_list_filter_by_project_ok(client, data): + url = "{}?project={}".format(reverse("issues-list"), data.public_project.pk) + + client.login(data.project_owner) + response = client.get(url) + + assert response.status_code == 200 + assert len(response.data) == 1 + + +def test_issue_list_filter_by_project_error(client, data): + url = "{}?project={}".format(reverse("issues-list"), "-ERROR-") + + client.login(data.project_owner) + response = client.get(url) + + assert response.status_code == 400 + + def test_issue_create(client, data): url = reverse('issues-list')