mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 08:29:59 +03:00
Remove test dependency on django guardian
An ObjectPermissionBackend is added which is similar to the one in guardian.backends.ObjectPermissionBackend for test support. The differences are that: - Permissions can only be assigned to groups - The object permissions are stored in a defaultdict - Permissions can only be assigned using app_label.codename This allows DRF to be released without waiting for django-guardian to update.
This commit is contained in:
parent
3875d3284e
commit
dc35f9e408
|
@ -2,7 +2,6 @@
|
|||
coreapi==2.3.1
|
||||
coreschema==0.0.4
|
||||
django-filter>=2.4.0,<3.0
|
||||
django-guardian>=2.3.0,<2.4
|
||||
markdown==3.3;python_version>="3.6"
|
||||
markdown==3.2.2;python_version=="3.5"
|
||||
psycopg2-binary>=2.8.5,<2.9
|
||||
|
|
35
tests/authentication/backends.py
Normal file
35
tests/authentication/backends.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from collections import defaultdict
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
|
||||
def assign_perm(perm, group, obj=None):
|
||||
if "." not in perm:
|
||||
raise ValueError("perm must be in the format 'app_label.codename'")
|
||||
|
||||
if obj:
|
||||
ObjectPermissionBackend.assign_perm(perm, group, obj)
|
||||
else:
|
||||
# Assign global permissions if there is no object
|
||||
app_label, codename = perm.split(".", 1)
|
||||
perm = Permission.objects.get(
|
||||
content_type__app_label=app_label, codename=codename
|
||||
)
|
||||
group.permissions.add(perm)
|
||||
|
||||
|
||||
class ObjectPermissionBackend:
|
||||
# Stores the set of groups that have the given permission for the given object
|
||||
object_perms = defaultdict(lambda: defaultdict(set))
|
||||
|
||||
def authenticate(self, *_, **__):
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def assign_perm(cls, perm, group, obj):
|
||||
cls.object_perms[obj][perm].add(group)
|
||||
|
||||
def has_perm(self, user_obj, perm, obj=None):
|
||||
groups_with_obj_perm = self.object_perms[obj][perm]
|
||||
users_groups = {*user_obj.groups.all()}
|
||||
return bool(groups_with_obj_perm.intersection(users_groups))
|
|
@ -19,6 +19,10 @@ def pytest_configure(config):
|
|||
from django.conf import settings
|
||||
|
||||
settings.configure(
|
||||
AUTHENTICATION_BACKENDS=(
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'tests.authentication.backends.ObjectPermissionBackend',
|
||||
),
|
||||
DEBUG_PROPAGATE_EXCEPTIONS=True,
|
||||
DATABASES={
|
||||
'default': {
|
||||
|
@ -70,21 +74,6 @@ def pytest_configure(config):
|
|||
),
|
||||
)
|
||||
|
||||
# guardian is optional
|
||||
try:
|
||||
import guardian # NOQA
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
settings.ANONYMOUS_USER_ID = -1
|
||||
settings.AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'guardian.backends.ObjectPermissionBackend',
|
||||
)
|
||||
settings.INSTALLED_APPS += (
|
||||
'guardian',
|
||||
)
|
||||
|
||||
if config.getoption('--no-pkgroot'):
|
||||
sys.path.pop(0)
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import base64
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AnonymousUser, Group, Permission, User
|
||||
from django.db import models
|
||||
from django.test import TestCase
|
||||
|
@ -14,6 +12,7 @@ from rest_framework import (
|
|||
)
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework.test import APIRequestFactory
|
||||
from tests.authentication.backends import assign_perm
|
||||
from tests.models import BasicModel
|
||||
|
||||
factory = APIRequestFactory()
|
||||
|
@ -299,14 +298,11 @@ class GetQuerysetObjectPermissionInstanceView(generics.RetrieveUpdateDestroyAPIV
|
|||
get_queryset_object_permissions_view = GetQuerysetObjectPermissionInstanceView.as_view()
|
||||
|
||||
|
||||
@unittest.skipUnless('guardian' in settings.INSTALLED_APPS, 'django-guardian not installed')
|
||||
class ObjectPermissionsIntegrationTests(TestCase):
|
||||
"""
|
||||
Integration tests for the object level permissions API.
|
||||
"""
|
||||
def setUp(self):
|
||||
from guardian.shortcuts import assign_perm
|
||||
|
||||
# create users
|
||||
create = User.objects.create_user
|
||||
users = {
|
||||
|
@ -320,14 +316,13 @@ class ObjectPermissionsIntegrationTests(TestCase):
|
|||
everyone = Group.objects.create(name='everyone')
|
||||
model_name = BasicPermModel._meta.model_name
|
||||
app_label = BasicPermModel._meta.app_label
|
||||
f = '{}_{}'.format
|
||||
f = '{}.{}_{}'.format
|
||||
perms = {
|
||||
'view': f('view', model_name),
|
||||
'change': f('change', model_name),
|
||||
'delete': f('delete', model_name)
|
||||
'view': f(app_label, 'view', model_name),
|
||||
'change': f(app_label, 'change', model_name),
|
||||
'delete': f(app_label, 'delete', model_name)
|
||||
}
|
||||
for perm in perms.values():
|
||||
perm = '{}.{}'.format(app_label, perm)
|
||||
assign_perm(perm, everyone)
|
||||
everyone.user_set.add(*users.values())
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user