Add support for proxy model permission inheritance
Proxy models now get the permission inheritance from their base model. Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -124,7 +124,8 @@
|
|||||||
characters.
|
characters.
|
||||||
- Improve TestModelTestMixin. Allow specifying a base model.
|
- Improve TestModelTestMixin. Allow specifying a base model.
|
||||||
Fix passing the dynamic Meta class to the test model.
|
Fix passing the dynamic Meta class to the test model.
|
||||||
|
- Support for proxy model permission inheritance. Proxy models
|
||||||
|
now get the permission inheritance from their base models.
|
||||||
|
|
||||||
3.2.9 (2019-11-03)
|
3.2.9 (2019-11-03)
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ class ModelPermission(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_inheritance(cls, model):
|
def get_inheritance(cls, model):
|
||||||
|
# Proxy models get the inheritance from their base model
|
||||||
|
if model._meta.proxy:
|
||||||
|
model = model._meta.proxy_for_model
|
||||||
|
|
||||||
return cls._inheritances[model]
|
return cls._inheritances[model]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -49,9 +49,8 @@ class ACLTestMixin(PermissionTestMixin, RoleTestMixin, TestModelTestMixin):
|
|||||||
# this avoids their Content Type from being looked up
|
# this avoids their Content Type from being looked up
|
||||||
# in subsequent tests where they don't exists due to the database
|
# in subsequent tests where they don't exists due to the database
|
||||||
# transaction rollback.
|
# transaction rollback.
|
||||||
for model in self._test_models:
|
#for model in self._test_models:
|
||||||
ModelPermission.deregister(model=model)
|
# ModelPermission.deregister(model=model)
|
||||||
self._test_models.remove(model)
|
|
||||||
|
|
||||||
super(ACLTestMixin, self).tearDown()
|
super(ACLTestMixin, self).tearDown()
|
||||||
|
|
||||||
@@ -71,12 +70,12 @@ class ACLTestMixin(PermissionTestMixin, RoleTestMixin, TestModelTestMixin):
|
|||||||
'object_id': self.test_object.pk
|
'object_id': self.test_object.pk
|
||||||
}
|
}
|
||||||
|
|
||||||
def _setup_test_object(self, register_model_permissions=True):
|
def _setup_test_object(self, model_name=None, register_model_permissions=True):
|
||||||
self._create_test_model()
|
self.TestModel = self._create_test_model(model_name=model_name)
|
||||||
self._create_test_object()
|
self.test_object = self.TestModel.objects.create()
|
||||||
if register_model_permissions:
|
if register_model_permissions:
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=self.test_object._meta.model, permissions=(
|
model=self.TestModel, permissions=(
|
||||||
permission_acl_edit, permission_acl_view,
|
permission_acl_edit, permission_acl_view,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -85,9 +84,23 @@ class ACLTestMixin(PermissionTestMixin, RoleTestMixin, TestModelTestMixin):
|
|||||||
|
|
||||||
if register_model_permissions:
|
if register_model_permissions:
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=self.test_object._meta.model, permissions=(
|
model=self.TestModel, permissions=(
|
||||||
self.test_permission,
|
self.test_permission,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self._inject_test_object_content_type()
|
self._inject_test_object_content_type()
|
||||||
|
|
||||||
|
def _setup_test_object_base(self):
|
||||||
|
self.test_object_base = self._setup_test_object(
|
||||||
|
model_name='TestModelBase'
|
||||||
|
)
|
||||||
|
|
||||||
|
def _setup_test_object_proxy(self):
|
||||||
|
self.TestModelProxy = self._create_test_model(
|
||||||
|
base_class=self.TestModel, model_name='TestModelProxy',
|
||||||
|
options={
|
||||||
|
'proxy': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.test_object_proxy = self.TestModelProxy.objects.create()
|
||||||
|
|||||||
@@ -67,8 +67,10 @@ class PermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
|
|
||||||
def _setup_child_parent_test_objects(self):
|
def _setup_child_parent_test_objects(self):
|
||||||
self._create_test_permission()
|
self._create_test_permission()
|
||||||
self._create_test_model(model_name='TestModelParent')
|
self.TestModelParent = self._create_test_model(
|
||||||
self._create_test_model(
|
model_name='TestModelParent'
|
||||||
|
)
|
||||||
|
self.TestModelChild = self._create_test_model(
|
||||||
fields={
|
fields={
|
||||||
'parent': models.ForeignKey(
|
'parent': models.ForeignKey(
|
||||||
on_delete=models.CASCADE, related_name='children',
|
on_delete=models.CASCADE, related_name='children',
|
||||||
@@ -166,7 +168,7 @@ class PermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
|
|
||||||
class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
||||||
def test_retrieve_inherited_role_permission_not_model_applicable(self):
|
def test_retrieve_inherited_role_permission_not_model_applicable(self):
|
||||||
self._create_test_model()
|
self.TestModel = self._create_test_model()
|
||||||
self.test_object = self.TestModel.objects.create()
|
self.test_object = self.TestModel.objects.create()
|
||||||
self._create_test_acl()
|
self._create_test_acl()
|
||||||
self._create_test_permission()
|
self._create_test_permission()
|
||||||
@@ -179,7 +181,7 @@ class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
self.assertTrue(self.test_permission.stored_permission not in queryset)
|
self.assertTrue(self.test_permission.stored_permission not in queryset)
|
||||||
|
|
||||||
def test_retrieve_inherited_role_permission_model_applicable(self):
|
def test_retrieve_inherited_role_permission_model_applicable(self):
|
||||||
self._create_test_model()
|
self.TestModel = self._create_test_model()
|
||||||
self.test_object = self.TestModel.objects.create()
|
self.test_object = self.TestModel.objects.create()
|
||||||
self._create_test_acl()
|
self._create_test_acl()
|
||||||
self._create_test_permission()
|
self._create_test_permission()
|
||||||
@@ -199,8 +201,10 @@ class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
def test_retrieve_inherited_related_parent_child_permission(self):
|
def test_retrieve_inherited_related_parent_child_permission(self):
|
||||||
self._create_test_permission()
|
self._create_test_permission()
|
||||||
|
|
||||||
self._create_test_model(model_name='TestModelParent')
|
self.TestModelParent = self._create_test_model(
|
||||||
self._create_test_model(
|
model_name='TestModelParent'
|
||||||
|
)
|
||||||
|
self.TestModelChild = self._create_test_model(
|
||||||
fields={
|
fields={
|
||||||
'parent': models.ForeignKey(
|
'parent': models.ForeignKey(
|
||||||
on_delete=models.CASCADE, related_name='children',
|
on_delete=models.CASCADE, related_name='children',
|
||||||
@@ -240,8 +244,10 @@ class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
):
|
):
|
||||||
self._create_test_permission()
|
self._create_test_permission()
|
||||||
|
|
||||||
self._create_test_model(model_name='TestModelGrandParent')
|
self.TestModelGrandParent = self._create_test_model(
|
||||||
self._create_test_model(
|
model_name='TestModelGrandParent'
|
||||||
|
)
|
||||||
|
self.TestModelParent = self._create_test_model(
|
||||||
fields={
|
fields={
|
||||||
'parent': models.ForeignKey(
|
'parent': models.ForeignKey(
|
||||||
on_delete=models.CASCADE, related_name='children',
|
on_delete=models.CASCADE, related_name='children',
|
||||||
@@ -249,7 +255,7 @@ class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
)
|
)
|
||||||
}, model_name='TestModelParent'
|
}, model_name='TestModelParent'
|
||||||
)
|
)
|
||||||
self._create_test_model(
|
self.TestModelChild = self._create_test_model(
|
||||||
fields={
|
fields={
|
||||||
'parent': models.ForeignKey(
|
'parent': models.ForeignKey(
|
||||||
on_delete=models.CASCADE, related_name='children',
|
on_delete=models.CASCADE, related_name='children',
|
||||||
@@ -294,3 +300,84 @@ class InheritedPermissionTestCase(ACLTestMixin, BaseTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(self.test_permission.stored_permission in queryset)
|
self.assertTrue(self.test_permission.stored_permission in queryset)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyModelPermissionTestCase(ACLTestMixin, BaseTestCase):
|
||||||
|
def test_proxy_model_filtering_no_permission(self):
|
||||||
|
self._setup_test_object_base()
|
||||||
|
self._setup_test_object_proxy()
|
||||||
|
|
||||||
|
proxy_object = self.TestModelProxy.objects.get(pk=self.test_object.pk)
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
proxy_object in AccessControlList.objects.restrict_queryset(
|
||||||
|
permission=self.test_permission,
|
||||||
|
queryset=self.TestModelProxy.objects.all(),
|
||||||
|
user=self._test_case_user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_proxy_model_filtering_with_access(self):
|
||||||
|
self._setup_test_object_base()
|
||||||
|
self._setup_test_object_proxy()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_object, permission=self.test_permission
|
||||||
|
)
|
||||||
|
|
||||||
|
proxy_object = self.TestModelProxy.objects.get(pk=self.test_object.pk)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
proxy_object in AccessControlList.objects.restrict_queryset(
|
||||||
|
permission=self.test_permission,
|
||||||
|
queryset=self.TestModelProxy.objects.all(),
|
||||||
|
user=self._test_case_user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_proxy_model_inheritance_with_access(self):
|
||||||
|
self._create_test_permission()
|
||||||
|
|
||||||
|
self.TestModelParent = self._create_test_model(
|
||||||
|
model_name='TestModelParent'
|
||||||
|
)
|
||||||
|
self.TestModelChild = self._create_test_model(
|
||||||
|
fields={
|
||||||
|
'parent': models.ForeignKey(
|
||||||
|
on_delete=models.CASCADE, related_name='children',
|
||||||
|
to='TestModelParent',
|
||||||
|
)
|
||||||
|
}, model_name='TestModelChild'
|
||||||
|
)
|
||||||
|
self.TestModelProxy = self._create_test_model(
|
||||||
|
base_class=self.TestModelChild, model_name='TestModelProxy',
|
||||||
|
options={
|
||||||
|
'proxy': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
ModelPermission.register(
|
||||||
|
model=self.TestModelParent, permissions=(
|
||||||
|
self.test_permission,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=self.TestModelChild, related='parent',
|
||||||
|
)
|
||||||
|
|
||||||
|
parent = self.TestModelParent.objects.create()
|
||||||
|
child = self.TestModelChild.objects.create(parent=parent)
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=parent, permission=self.test_permission
|
||||||
|
)
|
||||||
|
|
||||||
|
proxy_object = self.TestModelProxy.objects.get(pk=child.pk)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
proxy_object in AccessControlList.objects.restrict_queryset(
|
||||||
|
permission=self.test_permission,
|
||||||
|
queryset=self.TestModelProxy.objects.all(),
|
||||||
|
user=self._test_case_user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user