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
|
coreapi==2.3.1
|
||||||
coreschema==0.0.4
|
coreschema==0.0.4
|
||||||
django-filter>=2.4.0,<3.0
|
django-filter>=2.4.0,<3.0
|
||||||
django-guardian>=2.3.0,<2.4
|
|
||||||
markdown==3.3;python_version>="3.6"
|
markdown==3.3;python_version>="3.6"
|
||||||
markdown==3.2.2;python_version=="3.5"
|
markdown==3.2.2;python_version=="3.5"
|
||||||
psycopg2-binary>=2.8.5,<2.9
|
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
|
from django.conf import settings
|
||||||
|
|
||||||
settings.configure(
|
settings.configure(
|
||||||
|
AUTHENTICATION_BACKENDS=(
|
||||||
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
|
'tests.authentication.backends.ObjectPermissionBackend',
|
||||||
|
),
|
||||||
DEBUG_PROPAGATE_EXCEPTIONS=True,
|
DEBUG_PROPAGATE_EXCEPTIONS=True,
|
||||||
DATABASES={
|
DATABASES={
|
||||||
'default': {
|
'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'):
|
if config.getoption('--no-pkgroot'):
|
||||||
sys.path.pop(0)
|
sys.path.pop(0)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import base64
|
import base64
|
||||||
import unittest
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
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
|
||||||
|
@ -14,6 +12,7 @@ from rest_framework import (
|
||||||
)
|
)
|
||||||
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.authentication.backends import assign_perm
|
||||||
from tests.models import BasicModel
|
from tests.models import BasicModel
|
||||||
|
|
||||||
factory = APIRequestFactory()
|
factory = APIRequestFactory()
|
||||||
|
@ -299,14 +298,11 @@ class GetQuerysetObjectPermissionInstanceView(generics.RetrieveUpdateDestroyAPIV
|
||||||
get_queryset_object_permissions_view = GetQuerysetObjectPermissionInstanceView.as_view()
|
get_queryset_object_permissions_view = GetQuerysetObjectPermissionInstanceView.as_view()
|
||||||
|
|
||||||
|
|
||||||
@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.
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
from guardian.shortcuts import assign_perm
|
|
||||||
|
|
||||||
# create users
|
# create users
|
||||||
create = User.objects.create_user
|
create = User.objects.create_user
|
||||||
users = {
|
users = {
|
||||||
|
@ -320,14 +316,13 @@ class ObjectPermissionsIntegrationTests(TestCase):
|
||||||
everyone = Group.objects.create(name='everyone')
|
everyone = Group.objects.create(name='everyone')
|
||||||
model_name = BasicPermModel._meta.model_name
|
model_name = BasicPermModel._meta.model_name
|
||||||
app_label = BasicPermModel._meta.app_label
|
app_label = BasicPermModel._meta.app_label
|
||||||
f = '{}_{}'.format
|
f = '{}.{}_{}'.format
|
||||||
perms = {
|
perms = {
|
||||||
'view': f('view', model_name),
|
'view': f(app_label, 'view', model_name),
|
||||||
'change': f('change', model_name),
|
'change': f(app_label, 'change', model_name),
|
||||||
'delete': f('delete', model_name)
|
'delete': f(app_label, 'delete', model_name)
|
||||||
}
|
}
|
||||||
for perm in perms.values():
|
for perm in perms.values():
|
||||||
perm = '{}.{}'.format(app_label, perm)
|
|
||||||
assign_perm(perm, everyone)
|
assign_perm(perm, everyone)
|
||||||
everyone.user_set.add(*users.values())
|
everyone.user_set.add(*users.values())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user