Remove DjangoObjectPermissionsFilter

This commit is contained in:
Ryan P Kilby 2019-05-20 20:10:38 -07:00
parent 1b8141a4aa
commit e0882a52e4
3 changed files with 9 additions and 82 deletions

View File

@ -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']

View File

@ -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)

View File

@ -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)