summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Bengfort <tobias.bengfort@posteo.de>2019-03-24 00:40:44 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-06-05 13:56:37 +0200
commit581a0f45453f178b8abc0d09bd16ce06309ed33a (patch)
treeb9ac48689168b46346dbb6aabe726f3285f67531
parent75337a60509fdfdd321a5caf8e30d57fff6b9518 (diff)
Refs #30226 -- Added User.get_user_permissions() method.
Added to mirror the existing User.get_group_permissions().
-rw-r--r--django/contrib/auth/backends.py13
-rw-r--r--django/contrib/auth/models.py28
-rw-r--r--docs/ref/contrib/auth.txt17
-rw-r--r--docs/releases/3.0.txt4
-rw-r--r--docs/topics/auth/customizing.txt12
-rw-r--r--tests/auth_tests/test_auth_backends.py17
-rw-r--r--tests/auth_tests/test_models.py1
7 files changed, 70 insertions, 22 deletions
diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
index d20987f8e1..f4b1722757 100644
--- a/django/contrib/auth/backends.py
+++ b/django/contrib/auth/backends.py
@@ -15,11 +15,17 @@ class BaseBackend:
def get_user(self, user_id):
return None
+ def get_user_permissions(self, user_obj, obj=None):
+ return set()
+
def get_group_permissions(self, user_obj, obj=None):
return set()
def get_all_permissions(self, user_obj, obj=None):
- return self.get_group_permissions(user_obj, obj=obj)
+ return {
+ *self.get_user_permissions(user_obj, obj=obj),
+ *self.get_group_permissions(user_obj, obj=obj),
+ }
def has_perm(self, user_obj, perm, obj=None):
return perm in self.get_all_permissions(user_obj, obj=obj)
@@ -96,10 +102,7 @@ class ModelBackend(BaseBackend):
if not user_obj.is_active or user_obj.is_anonymous or obj is not None:
return set()
if not hasattr(user_obj, '_perm_cache'):
- user_obj._perm_cache = {
- *self.get_user_permissions(user_obj),
- *self.get_group_permissions(user_obj),
- }
+ user_obj._perm_cache = super().get_all_permissions(user_obj)
return user_obj._perm_cache
def has_perm(self, user_obj, perm, obj=None):
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 324faa6f3e..78fd7fbb5c 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -159,11 +159,12 @@ class UserManager(BaseUserManager):
# A few helper functions for common logic between User and AnonymousUser.
-def _user_get_all_permissions(user, obj):
+def _user_get_permissions(user, obj, from_name):
permissions = set()
+ name = 'get_%s_permissions' % from_name
for backend in auth.get_backends():
- if hasattr(backend, "get_all_permissions"):
- permissions.update(backend.get_all_permissions(user, obj))
+ if hasattr(backend, name):
+ permissions.update(getattr(backend, name)(user, obj))
return permissions
@@ -233,20 +234,24 @@ class PermissionsMixin(models.Model):
class Meta:
abstract = True
+ def get_user_permissions(self, obj=None):
+ """
+ Return a list of permission strings that this user has directly.
+ Query all available auth backends. If an object is passed in,
+ return only permissions matching this object.
+ """
+ return _user_get_permissions(self, obj, 'user')
+
def get_group_permissions(self, obj=None):
"""
Return a list of permission strings that this user has through their
groups. Query all available auth backends. If an object is passed in,
return only permissions matching this object.
"""
- permissions = set()
- for backend in auth.get_backends():
- if hasattr(backend, "get_group_permissions"):
- permissions.update(backend.get_group_permissions(self, obj))
- return permissions
+ return _user_get_permissions(self, obj, 'group')
def get_all_permissions(self, obj=None):
- return _user_get_all_permissions(self, obj)
+ return _user_get_permissions(self, obj, 'all')
def has_perm(self, perm, obj=None):
"""
@@ -403,11 +408,14 @@ class AnonymousUser:
def user_permissions(self):
return self._user_permissions
+ def get_user_permissions(self, obj=None):
+ return _user_get_permissions(self, obj, 'user')
+
def get_group_permissions(self, obj=None):
return set()
def get_all_permissions(self, obj=None):
- return _user_get_all_permissions(self, obj=obj)
+ return _user_get_permissions(self, obj, 'all')
def has_perm(self, perm, obj=None):
return _user_has_perm(self, perm, obj=obj)
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index 17197e9fc7..877ec168e5 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -191,6 +191,15 @@ Methods
:meth:`~django.contrib.auth.models.User.set_unusable_password()` has
been called for this user.
+ .. method:: get_user_permissions(obj=None)
+
+ .. versionadded:: 3.0
+
+ Returns a set of permission strings that the user has directly.
+
+ If ``obj`` is passed in, only returns the user permissions for this
+ specific object.
+
.. method:: get_group_permissions(obj=None)
Returns a set of permission strings that the user has, through their
@@ -467,14 +476,18 @@ The following backends are available in :mod:`django.contrib.auth.backends`:
A base class that provides default implementations for all required
methods. By default, it will reject any user and provide no permissions.
+ .. method:: get_user_permissions(user_obj, obj=None)
+
+ Returns an empty set.
+
.. method:: get_group_permissions(user_obj, obj=None)
Returns an empty set.
.. method:: get_all_permissions(user_obj, obj=None)
- Uses :meth:`get_group_permissions` to get the set of permission strings
- the ``user_obj`` has.
+ Uses :meth:`get_user_permissions` and :meth:`get_group_permissions` to
+ get the set of permission strings the ``user_obj`` has.
.. method:: has_perm(user_obj, perm, obj=None)
diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt
index 43eb07c78c..1ba81c5643 100644
--- a/docs/releases/3.0.txt
+++ b/docs/releases/3.0.txt
@@ -72,6 +72,10 @@ Minor features
* Added :class:`~django.contrib.auth.backends.BaseBackend` class to ease
customization of authentication backends.
+* Added :meth:`~django.contrib.auth.models.User.get_user_permissions()` method
+ to mirror the existing
+ :meth:`~django.contrib.auth.models.User.get_group_permissions()` method.
+
:mod:`django.contrib.contenttypes`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt
index becf30e7e6..282eb8ca91 100644
--- a/docs/topics/auth/customizing.txt
+++ b/docs/topics/auth/customizing.txt
@@ -180,7 +180,8 @@ Handling authorization in custom backends
Custom auth backends can provide their own permissions.
The user model will delegate permission lookup functions
-(:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
+(:meth:`~django.contrib.auth.models.User.get_user_permissions()`,
+:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
:meth:`~django.contrib.auth.models.User.get_all_permissions()`,
:meth:`~django.contrib.auth.models.User.has_perm()`, and
:meth:`~django.contrib.auth.models.User.has_module_perms()`) to any
@@ -898,6 +899,15 @@ methods and attributes:
Boolean. Designates that this user has all permissions without
explicitly assigning them.
+ .. method:: models.PermissionsMixin.get_user_permissions(obj=None)
+
+ .. versionadded:: 3.0
+
+ Returns a set of permission strings that the user has directly.
+
+ If ``obj`` is passed in, only returns the user permissions for this
+ specific object.
+
.. method:: models.PermissionsMixin.get_group_permissions(obj=None)
Returns a set of permission strings that the user has, through their
diff --git a/tests/auth_tests/test_auth_backends.py b/tests/auth_tests/test_auth_backends.py
index 84facd6c3a..6447edefc9 100644
--- a/tests/auth_tests/test_auth_backends.py
+++ b/tests/auth_tests/test_auth_backends.py
@@ -21,6 +21,9 @@ from .models import (
class SimpleBackend(BaseBackend):
+ def get_user_permissions(self, user_obj, obj=None):
+ return ['user_perm']
+
def get_group_permissions(self, user_obj, obj=None):
return ['group_perm']
@@ -31,13 +34,17 @@ class BaseBackendTest(TestCase):
def setUpTestData(cls):
cls.user = User.objects.create_user('test', 'test@example.com', 'test')
+ def test_get_user_permissions(self):
+ self.assertEqual(self.user.get_user_permissions(), {'user_perm'})
+
def test_get_group_permissions(self):
self.assertEqual(self.user.get_group_permissions(), {'group_perm'})
def test_get_all_permissions(self):
- self.assertEqual(self.user.get_all_permissions(), {'group_perm'})
+ self.assertEqual(self.user.get_all_permissions(), {'user_perm', 'group_perm'})
def test_has_perm(self):
+ self.assertIs(self.user.has_perm('user_perm'), True)
self.assertIs(self.user.has_perm('group_perm'), True)
self.assertIs(self.user.has_perm('other_perm', TestObj()), False)
@@ -102,6 +109,7 @@ class BaseModelBackendTest:
# reloading user to purge the _perm_cache
user = self.UserModel._default_manager.get(pk=self.user.pk)
self.assertEqual(user.get_all_permissions(), {'auth.test'})
+ self.assertEqual(user.get_user_permissions(), {'auth.test'})
self.assertEqual(user.get_group_permissions(), set())
self.assertIs(user.has_module_perms('Group'), False)
self.assertIs(user.has_module_perms('auth'), True)
@@ -111,7 +119,8 @@ class BaseModelBackendTest:
perm = Permission.objects.create(name='test3', content_type=content_type, codename='test3')
user.user_permissions.add(perm)
user = self.UserModel._default_manager.get(pk=self.user.pk)
- self.assertEqual(user.get_all_permissions(), {'auth.test2', 'auth.test', 'auth.test3'})
+ expected_user_perms = {'auth.test2', 'auth.test', 'auth.test3'}
+ self.assertEqual(user.get_all_permissions(), expected_user_perms)
self.assertIs(user.has_perm('test'), False)
self.assertIs(user.has_perm('auth.test'), True)
self.assertIs(user.has_perms(['auth.test2', 'auth.test3']), True)
@@ -121,8 +130,8 @@ class BaseModelBackendTest:
group.permissions.add(perm)
user.groups.add(group)
user = self.UserModel._default_manager.get(pk=self.user.pk)
- exp = {'auth.test2', 'auth.test', 'auth.test3', 'auth.test_group'}
- self.assertEqual(user.get_all_permissions(), exp)
+ self.assertEqual(user.get_all_permissions(), {*expected_user_perms, 'auth.test_group'})
+ self.assertEqual(user.get_user_permissions(), expected_user_perms)
self.assertEqual(user.get_group_permissions(), {'auth.test_group'})
self.assertIs(user.has_perms(['auth.test3', 'auth.test_group']), True)
diff --git a/tests/auth_tests/test_models.py b/tests/auth_tests/test_models.py
index dd3377d7a6..a3502a224f 100644
--- a/tests/auth_tests/test_models.py
+++ b/tests/auth_tests/test_models.py
@@ -333,6 +333,7 @@ class AnonymousUserTests(SimpleTestCase):
self.assertIs(self.user.is_superuser, False)
self.assertEqual(self.user.groups.all().count(), 0)
self.assertEqual(self.user.user_permissions.all().count(), 0)
+ self.assertEqual(self.user.get_user_permissions(), set())
self.assertEqual(self.user.get_group_permissions(), set())
def test_str(self):