Fixed #18991 -- Allowed permission lookup by "if in"
When looking permissions from PermWrapper it is now possible to use {% if "someapp.someperm" in perms %} instead of {% if perms.someapp.someperm %}.
This commit is contained in:
parent
c2532825db
commit
d5a4f209c3
|
@ -32,6 +32,17 @@ class PermWrapper(object):
|
|||
# I am large, I contain multitudes.
|
||||
raise TypeError("PermWrapper is not iterable.")
|
||||
|
||||
def __contains__(self, perm_name):
|
||||
"""
|
||||
Lookup by "someapp" or "someapp.someperm" in perms.
|
||||
"""
|
||||
if '.' not in perm_name:
|
||||
# The name refers to module.
|
||||
return bool(self[perm_name])
|
||||
module_name, perm_name = perm_name.split('.', 1)
|
||||
return self[module_name][perm_name]
|
||||
|
||||
|
||||
def auth(request):
|
||||
"""
|
||||
Returns context variables required by apps that use Django's authentication
|
||||
|
|
|
@ -3,6 +3,8 @@ import os
|
|||
from django.conf import global_settings
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth.tests.utils import skipIfCustomUser
|
||||
from django.contrib.auth.models import User, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.auth.context_processors import PermWrapper, PermLookupDict
|
||||
from django.db.models import Q
|
||||
from django.test import TestCase
|
||||
|
@ -10,13 +12,13 @@ from django.test.utils import override_settings
|
|||
|
||||
|
||||
class MockUser(object):
|
||||
def has_module_perm(self, perm):
|
||||
if perm == 'mockapp.someapp':
|
||||
def has_module_perms(self, perm):
|
||||
if perm == 'mockapp':
|
||||
return True
|
||||
return False
|
||||
|
||||
def has_perm(self, perm):
|
||||
if perm == 'someperm':
|
||||
if perm == 'mockapp.someperm':
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -40,13 +42,19 @@ class PermWrapperTests(TestCase):
|
|||
|
||||
def test_permwrapper_in(self):
|
||||
"""
|
||||
Test that 'something' in PermWrapper doesn't end up in endless loop.
|
||||
Test that 'something' in PermWrapper works as expected.
|
||||
"""
|
||||
perms = PermWrapper(MockUser())
|
||||
with self.assertRaises(TypeError):
|
||||
self.EQLimiterObject() in perms
|
||||
# Works for modules and full permissions.
|
||||
self.assertTrue('mockapp' in perms)
|
||||
self.assertFalse('nonexisting' in perms)
|
||||
self.assertTrue('mockapp.someperm' in perms)
|
||||
self.assertFalse('mockapp.nonexisting' in perms)
|
||||
|
||||
def test_permlookupdict_in(self):
|
||||
"""
|
||||
No endless loops if accessed with 'in' - refs #18979.
|
||||
"""
|
||||
pldict = PermLookupDict(MockUser(), 'mockapp')
|
||||
with self.assertRaises(TypeError):
|
||||
self.EQLimiterObject() in pldict
|
||||
|
@ -92,9 +100,28 @@ class AuthContextProcessorTests(TestCase):
|
|||
self.assertContains(response, "Session accessed")
|
||||
|
||||
def test_perms_attrs(self):
|
||||
self.client.login(username='super', password='secret')
|
||||
u = User.objects.create_user(username='normal', password='secret')
|
||||
u.user_permissions.add(
|
||||
Permission.objects.get(
|
||||
content_type=ContentType.objects.get_for_model(Permission),
|
||||
codename='add_permission'))
|
||||
self.client.login(username='normal', password='secret')
|
||||
response = self.client.get('/auth_processor_perms/')
|
||||
self.assertContains(response, "Has auth permissions")
|
||||
self.assertContains(response, "Has auth.add_permission permissions")
|
||||
self.assertNotContains(response, "nonexisting")
|
||||
|
||||
def test_perm_in_perms_attrs(self):
|
||||
u = User.objects.create_user(username='normal', password='secret')
|
||||
u.user_permissions.add(
|
||||
Permission.objects.get(
|
||||
content_type=ContentType.objects.get_for_model(Permission),
|
||||
codename='add_permission'))
|
||||
self.client.login(username='normal', password='secret')
|
||||
response = self.client.get('/auth_processor_perm_in_perms/')
|
||||
self.assertContains(response, "Has auth permissions")
|
||||
self.assertContains(response, "Has auth.add_permission permissions")
|
||||
self.assertNotContains(response, "nonexisting")
|
||||
|
||||
def test_message_attrs(self):
|
||||
self.client.login(username='super', password='secret')
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{% if 'auth' in perms %}Has auth permissions{% endif %}
|
||||
{% if 'auth.add_permission' in perms %}Has auth.add_permission permissions{% endif %}
|
||||
{% if 'nonexisting' in perms %}nonexisting perm found{% endif %}
|
||||
{% if 'auth.nonexisting' in perms %}auth.nonexisting perm found{% endif %}
|
|
@ -1 +1,4 @@
|
|||
{% if perms.auth %}Has auth permissions{% endif %}
|
||||
{% if perms.auth.add_permission %}Has auth.add_permission permissions{% endif %}
|
||||
{% if perms.nonexisting %}nonexisting perm found{% endif %}
|
||||
{% if perms.auth.nonexisting in perms %}auth.nonexisting perm found{% endif %}
|
||||
|
|
|
@ -37,6 +37,10 @@ def auth_processor_perms(request):
|
|||
return render_to_response('context_processors/auth_attrs_perms.html',
|
||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
||||
|
||||
def auth_processor_perm_in_perms(request):
|
||||
return render_to_response('context_processors/auth_attrs_perm_in_perms.html',
|
||||
RequestContext(request, {}, processors=[context_processors.auth]))
|
||||
|
||||
def auth_processor_messages(request):
|
||||
info(request, "Message 1")
|
||||
return render_to_response('context_processors/auth_attrs_messages.html',
|
||||
|
@ -58,6 +62,7 @@ urlpatterns = urlpatterns + patterns('',
|
|||
(r'^auth_processor_attr_access/$', auth_processor_attr_access),
|
||||
(r'^auth_processor_user/$', auth_processor_user),
|
||||
(r'^auth_processor_perms/$', auth_processor_perms),
|
||||
(r'^auth_processor_perm_in_perms/$', auth_processor_perm_in_perms),
|
||||
(r'^auth_processor_messages/$', auth_processor_messages),
|
||||
url(r'^userpage/(.+)/$', userpage, name="userpage"),
|
||||
)
|
||||
|
|
|
@ -180,6 +180,10 @@ Django 1.5 also includes several smaller improvements worth noting:
|
|||
and inversion, expanding the types of expressions that can be passed to the
|
||||
database.
|
||||
|
||||
* When using :class:`~django.template.RequestContext`, it is now possible to
|
||||
look up permissions by using ``{% if 'someapp.someperm' in perms %}``
|
||||
in templates.
|
||||
|
||||
Backwards incompatible changes in 1.5
|
||||
=====================================
|
||||
|
||||
|
|
|
@ -1710,6 +1710,20 @@ Thus, you can check permissions in template ``{% if %}`` statements:
|
|||
<p>You don't have permission to do anything in the foo app.</p>
|
||||
{% endif %}
|
||||
|
||||
.. versionadded:: 1.5
|
||||
Permission lookup by "if in".
|
||||
|
||||
It is possible to also look permissions up by ``{% if in %}`` statements.
|
||||
For example:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
{% if 'foo' in perms %}
|
||||
{% if 'foo.can_vote' in perms %}
|
||||
<p>In lookup works, too.</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
Groups
|
||||
======
|
||||
|
||||
|
|
Loading…
Reference in New Issue