Issue #1886: Bad request when use project.slug instead project.id in API calls
parent
c2416dd622
commit
268b6a7ad4
|
@ -15,6 +15,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
import logging
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.db.models.sql.where import ExtraWhere, OR, AND
|
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 rest_framework import filters
|
||||||
|
|
||||||
from taiga.base import tags
|
from taiga.base import tags
|
||||||
|
from taiga.base import exceptions as exc
|
||||||
|
|
||||||
from taiga.projects.models import Membership
|
from taiga.projects.models import Membership
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class QueryParamsFilterMixin(filters.BaseFilterBackend):
|
class QueryParamsFilterMixin(filters.BaseFilterBackend):
|
||||||
_special_values_dict = {
|
_special_values_dict = {
|
||||||
|
@ -92,8 +96,13 @@ class PermissionBasedFilterBackend(FilterBackend):
|
||||||
|
|
||||||
def filter_queryset(self, request, queryset, view):
|
def filter_queryset(self, request, queryset, view):
|
||||||
project_id = None
|
project_id = None
|
||||||
if hasattr(view, "filter_fields") and "project" in view.filter_fields:
|
if (hasattr(view, "filter_fields") and "project" in view.filter_fields and
|
||||||
project_id = request.QUERY_PARAMS.get("project", None)
|
"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
|
qs = queryset
|
||||||
|
|
||||||
|
@ -103,11 +112,13 @@ class PermissionBasedFilterBackend(FilterBackend):
|
||||||
memberships_qs = Membership.objects.filter(user=request.user)
|
memberships_qs = Membership.objects.filter(user=request.user)
|
||||||
if project_id:
|
if project_id:
|
||||||
memberships_qs = memberships_qs.filter(project_id=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]
|
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:
|
else:
|
||||||
qs = qs.filter(project__anon_permissions__contains=[self.permission])
|
qs = qs.filter(project__anon_permissions__contains=[self.permission])
|
||||||
|
|
||||||
|
@ -171,8 +182,13 @@ class CanViewWikiAttachmentFilterBackend(PermissionBasedAttachmentFilterBackend)
|
||||||
class CanViewProjectObjFilterBackend(FilterBackend):
|
class CanViewProjectObjFilterBackend(FilterBackend):
|
||||||
def filter_queryset(self, request, queryset, view):
|
def filter_queryset(self, request, queryset, view):
|
||||||
project_id = None
|
project_id = None
|
||||||
if hasattr(view, "filter_fields") and "project" in view.filter_fields:
|
if (hasattr(view, "filter_fields") and "project" in view.filter_fields and
|
||||||
project_id = request.QUERY_PARAMS.get("project", None)
|
"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
|
qs = queryset
|
||||||
|
|
||||||
|
@ -182,7 +198,8 @@ class CanViewProjectObjFilterBackend(FilterBackend):
|
||||||
memberships_qs = Membership.objects.filter(user=request.user)
|
memberships_qs = Membership.objects.filter(user=request.user)
|
||||||
if project_id:
|
if project_id:
|
||||||
memberships_qs = memberships_qs.filter(project_id=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]
|
projects_list = [membership.project_id for membership in memberships_qs]
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,25 @@ def test_issue_list(client, data):
|
||||||
assert response.status_code == 200
|
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):
|
def test_issue_create(client, data):
|
||||||
url = reverse('issues-list')
|
url = reverse('issues-list')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue