mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-29 17:39:48 +03:00
Remove DjangoObjectPermissionsFilter
This commit is contained in:
parent
1b8141a4aa
commit
e0882a52e4
|
@ -131,13 +131,6 @@ except ImportError:
|
||||||
requests = None
|
requests = None
|
||||||
|
|
||||||
|
|
||||||
def is_guardian_installed():
|
|
||||||
"""
|
|
||||||
django-guardian is optional and only imported if in INSTALLED_APPS.
|
|
||||||
"""
|
|
||||||
return 'guardian' in settings.INSTALLED_APPS
|
|
||||||
|
|
||||||
|
|
||||||
# PATCH method is not implemented by Django
|
# PATCH method is not implemented by Django
|
||||||
if 'patch' not in View.http_method_names:
|
if 'patch' not in View.http_method_names:
|
||||||
View.http_method_names = View.http_method_names + ['patch']
|
View.http_method_names = View.http_method_names + ['patch']
|
||||||
|
|
|
@ -3,7 +3,6 @@ Provides generic filtering backends that can be used to filter the results
|
||||||
returned by list views.
|
returned by list views.
|
||||||
"""
|
"""
|
||||||
import operator
|
import operator
|
||||||
import warnings
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
@ -14,10 +13,7 @@ from django.template import loader
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from rest_framework import RemovedInDRF310Warning
|
from rest_framework.compat import coreapi, coreschema, distinct
|
||||||
from rest_framework.compat import (
|
|
||||||
coreapi, coreschema, distinct, is_guardian_installed
|
|
||||||
)
|
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
|
|
||||||
|
|
||||||
|
@ -315,41 +311,3 @@ class OrderingFilter(BaseFilterBackend):
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class DjangoObjectPermissionsFilter(BaseFilterBackend):
|
|
||||||
"""
|
|
||||||
A filter backend that limits results to those where the requesting user
|
|
||||||
has read object level permissions.
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
warnings.warn(
|
|
||||||
"`DjangoObjectPermissionsFilter` has been deprecated and moved to "
|
|
||||||
"the 3rd-party django-rest-framework-guardian package.",
|
|
||||||
RemovedInDRF310Warning, stacklevel=2
|
|
||||||
)
|
|
||||||
assert is_guardian_installed(), 'Using DjangoObjectPermissionsFilter, but django-guardian is not installed'
|
|
||||||
|
|
||||||
perm_format = '%(app_label)s.view_%(model_name)s'
|
|
||||||
|
|
||||||
def filter_queryset(self, request, queryset, view):
|
|
||||||
# We want to defer this import until run-time, rather than import-time.
|
|
||||||
# See https://github.com/encode/django-rest-framework/issues/4608
|
|
||||||
# (Also see #1624 for why we need to make this import explicitly)
|
|
||||||
from guardian import VERSION as guardian_version
|
|
||||||
from guardian.shortcuts import get_objects_for_user
|
|
||||||
|
|
||||||
extra = {}
|
|
||||||
user = request.user
|
|
||||||
model_cls = queryset.model
|
|
||||||
kwargs = {
|
|
||||||
'app_label': model_cls._meta.app_label,
|
|
||||||
'model_name': model_cls._meta.model_name
|
|
||||||
}
|
|
||||||
permission = self.perm_format % kwargs
|
|
||||||
if tuple(guardian_version) >= (1, 3):
|
|
||||||
# Maintain behavior compatibility with versions prior to 1.3
|
|
||||||
extra = {'accept_global_perms': False}
|
|
||||||
else:
|
|
||||||
extra = {}
|
|
||||||
return get_objects_for_user(user, permission, queryset, **extra)
|
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
import base64
|
import base64
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import django
|
import django
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AnonymousUser, Group, Permission, User
|
from django.contrib.auth.models import AnonymousUser, Group, Permission, User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import ResolverMatch
|
from django.urls import ResolverMatch
|
||||||
|
|
||||||
from rest_framework import (
|
from rest_framework import (
|
||||||
HTTP_HEADER_ENCODING, RemovedInDRF310Warning, authentication, generics,
|
HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers,
|
||||||
permissions, serializers, status, views
|
status, views
|
||||||
)
|
)
|
||||||
from rest_framework.compat import PY36, is_guardian_installed
|
from rest_framework.compat import PY36
|
||||||
from rest_framework.filters import DjangoObjectPermissionsFilter
|
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from rest_framework.test import APIRequestFactory
|
from rest_framework.test import APIRequestFactory
|
||||||
from tests.models import BasicModel
|
from tests.models import BasicModel
|
||||||
|
@ -309,7 +308,7 @@ class GetQuerysetObjectPermissionInstanceView(generics.RetrieveUpdateDestroyAPIV
|
||||||
get_queryset_object_permissions_view = GetQuerysetObjectPermissionInstanceView.as_view()
|
get_queryset_object_permissions_view = GetQuerysetObjectPermissionInstanceView.as_view()
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(is_guardian_installed(), 'django-guardian not installed')
|
@unittest.skipUnless('guardian' in settings.INSTALLED_APPS, 'django-guardian not installed')
|
||||||
class ObjectPermissionsIntegrationTests(TestCase):
|
class ObjectPermissionsIntegrationTests(TestCase):
|
||||||
"""
|
"""
|
||||||
Integration tests for the object level permissions API.
|
Integration tests for the object level permissions API.
|
||||||
|
@ -418,37 +417,14 @@ class ObjectPermissionsIntegrationTests(TestCase):
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
# Read list
|
# Read list
|
||||||
def test_django_object_permissions_filter_deprecated(self):
|
# Note: this previously tested `DjangoObjectPermissionsFilter`, which has
|
||||||
with warnings.catch_warnings(record=True) as w:
|
# since been moved to a separate package. These now act as sanity checks.
|
||||||
warnings.simplefilter("always")
|
|
||||||
DjangoObjectPermissionsFilter()
|
|
||||||
|
|
||||||
message = ("`DjangoObjectPermissionsFilter` has been deprecated and moved "
|
|
||||||
"to the 3rd-party django-rest-framework-guardian package.")
|
|
||||||
self.assertEqual(len(w), 1)
|
|
||||||
self.assertIs(w[-1].category, RemovedInDRF310Warning)
|
|
||||||
self.assertEqual(str(w[-1].message), message)
|
|
||||||
|
|
||||||
def test_can_read_list_permissions(self):
|
def test_can_read_list_permissions(self):
|
||||||
request = factory.get('/', HTTP_AUTHORIZATION=self.credentials['readonly'])
|
request = factory.get('/', HTTP_AUTHORIZATION=self.credentials['readonly'])
|
||||||
object_permissions_list_view.cls.filter_backends = (DjangoObjectPermissionsFilter,)
|
response = object_permissions_list_view(request)
|
||||||
# TODO: remove in version 3.10
|
|
||||||
with warnings.catch_warnings(record=True):
|
|
||||||
warnings.simplefilter("always")
|
|
||||||
response = object_permissions_list_view(request)
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(response.data[0].get('id'), 1)
|
self.assertEqual(response.data[0].get('id'), 1)
|
||||||
|
|
||||||
def test_cannot_read_list_permissions(self):
|
|
||||||
request = factory.get('/', HTTP_AUTHORIZATION=self.credentials['writeonly'])
|
|
||||||
object_permissions_list_view.cls.filter_backends = (DjangoObjectPermissionsFilter,)
|
|
||||||
# TODO: remove in version 3.10
|
|
||||||
with warnings.catch_warnings(record=True):
|
|
||||||
warnings.simplefilter("always")
|
|
||||||
response = object_permissions_list_view(request)
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
||||||
self.assertListEqual(response.data, [])
|
|
||||||
|
|
||||||
def test_cannot_method_not_allowed(self):
|
def test_cannot_method_not_allowed(self):
|
||||||
request = factory.generic('METHOD_NOT_ALLOWED', '/', HTTP_AUTHORIZATION=self.credentials['readonly'])
|
request = factory.generic('METHOD_NOT_ALLOWED', '/', HTTP_AUTHORIZATION=self.credentials['readonly'])
|
||||||
response = object_permissions_list_view(request)
|
response = object_permissions_list_view(request)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user