Kaydet (Commit) d5a4f209 authored tarafından Anssi Kääriäinen's avatar Anssi Kääriäinen

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 %}.
üst c2532825
......@@ -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')
......
{% 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 %}
{% 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
======
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment