diff --git a/example/templates/flatpages/default.html b/example/templates/flatpages/default.html
index ea22fb5..01a9e16 100644
--- a/example/templates/flatpages/default.html
+++ b/example/templates/flatpages/default.html
@@ -44,24 +44,37 @@
Detailed tests
+
Can I change this flatpage?
- "can_change" of the custom permission set "flatpage_permission":
+ ifhasperm "flatpage_permission.change_flatpage" request.user:
- {% ifhasperm "flatpage_permission.can_change" request.user %}
- Yes, you are allowed.
+ {% ifhasperm "flatpage_permission.change_flatpage" request.user %}
+ Yes, you are allowed.
{% else %}
- Nope, sorry.
+ Nope, sorry.
{% endifhasperm %}
- Can I access top secret flat pages?
- "top_secret" of the custom permission set "flatpage_permission":
+
+ Can I access this top secret flat page?
+ ifhasperm "flatpage_permission.top_secret" request.user flatpage:
{% ifhasperm "flatpage_permission.top_secret" request.user flatpage %}
- Yes, you are of course allowed to view flatpage '{{ flatpage }}', aren't you?
+ Yes, you are of course allowed to view flatpage '{{ flatpage }}', aren't you?
{% else %}
- Nope, sorry. Wait, how can you read this then?
+ Nope, sorry. Wait, how can you read this then?
{% endifhasperm %}
+
+ Again, can I really access this top secret flat page?
+ get_permission "flatpage_permission.top_secret" for request.user and flatpage as "secret_agent":
+ {% get_permission "flatpage_permission.top_secret" for request.user and flatpage as "secret_agent" %}
+
+ {% if secret_agent %}
+ Yes {{ request.user }}, you are a secret agent
+ {% else %}
+ Nope, only a programmer, sorry
+ {% endif %}
+
diff --git a/src/authority/templatetags/permissions.py b/src/authority/templatetags/permissions.py
index d796b37..87802b7 100644
--- a/src/authority/templatetags/permissions.py
+++ b/src/authority/templatetags/permissions.py
@@ -10,29 +10,48 @@ from authority.forms import UserPermissionForm
register = template.Library()
-class ComparisonNode(template.Node):
+def next_bit_for(bits, key, if_none=None):
+ try:
+ return bits[bits.index(key)+1]
+ except ValueError:
+ return if_none
+
+class ResolverNode(template.Node):
+ """
+ A small wrapper that adds a convenient resolve method.
+ """
+ def resolve(self, var, context):
+ """Resolves a variable out of context if it's not in quotes"""
+ if var is None:
+ return var
+ if var[0] in ('"', "'") and var[-1] == var[0]:
+ return var[1:-1]
+ else:
+ return template.Variable(var).resolve(context)
+
+class ComparisonNode(ResolverNode):
"""
Implements a node to provide an "if user/group has permission on object"
"""
- def __init__(self, user, permission, nodelist_true, nodelist_false, *objs):
+ def __init__(self, user, perm, nodelist_true, nodelist_false, *objs):
self.user = user
self.objs = objs
- # poll_permission.can_change
- self.perm = permission.strip('"')
- self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
+ self.perm = perm
+ self.nodelist_true = nodelist_true
+ self.nodelist_false = nodelist_false
def render(self, context):
try:
- user = template.Variable(self.user).resolve(context)
+ user = self.resolve(self.user, context)
+ perm = self.resolve(self.perm, context)
if self.objs:
objs = []
for obj in self.objs:
if obj is not None:
- objs.append(
- template.Variable(obj).resolve(context))
+ objs.append(self.resolve(obj, context))
else:
objs = None
- check = permissions.registry.get_check(user, self.perm)
+ check = permissions.registry.get_check(user, perm)
if check is not None:
if check(*objs):
# return True if check was successful
@@ -53,17 +72,20 @@ def do_if_has_perm(parser, token):
"""
This function provides funcitonality for the 'ifhasperm' template tag
- {% ifhasperm [permission_label].[check_name] [user] [*objs] %}
- lalala
- {% else %}
- meh
- {% endifhasperm %}
+ Syntax::
+
+ {% ifhasperm [permission_label].[check_name] [user] [*objs] %}
+ lalala
+ {% else %}
+ meh
+ {% endifhasperm %}
+
+ {% if hasperm "poll_permission.can_change" request.user %}
+ lalala
+ {% else %}
+ meh
+ {% endifhasperm %}
- {% if hasperm poll_permission.can_change request.user %}
- lalala
- {% else %}
- meh
- {% endifhasperm %}
"""
bits = token.contents.split()
if 5 < len(bits) < 3:
@@ -107,10 +129,14 @@ def permission_delete_link(context, perm):
@register.inclusion_tag('authority/permission_form.html', takes_context=True)
def permission_form(context, obj, perm=None):
"""
- Renders an "add permissions" form
+ Renders an "add permissions" form for the given object. If no object
+ is given it will render a select box to choose from.
+
+ Syntax::
+
+ {% permission_form [obj] [permission_label].[check_name] %}
+ {% permission_form lesson "lesson_permission.add_lesson" %}
- {% permission_form [obj] add_lesson %}
- {% permission_form lesson add_lesson %}
"""
user = context['request'].user
if user.is_authenticated():
@@ -122,21 +148,13 @@ def permission_form(context, obj, perm=None):
}
return {'form': None}
-class PermissionForObjectNode(template.Node):
- def __init__(self, obj, user, var_name):
+class PermissionsForObjectNode(ResolverNode):
+ def __init__(self, obj, user, var_name, perm=None, objs=None):
self.obj = obj
self.user = user
+ self.perm = perm
self.var_name = var_name
- def resolve(self, var, context):
- """Resolves a variable out of context if it's not in quotes"""
- if var is None:
- return var
- if var[0] in ('"', "'") and var[-1] == var[0]:
- return var[1:-1]
- else:
- return template.Variable(var).resolve(context)
-
def render(self, context):
obj = self.resolve(self.obj, context)
var_name = self.resolve(self.var_name, context)
@@ -152,6 +170,9 @@ class PermissionForObjectNode(template.Node):
@register.tag
def get_permissions(parser, token):
"""
+ Retrieves all permissions associated with the given obj and user
+ and assigns the result to a context variable.
+
Syntax::
{% get_permissions obj %}
@@ -163,16 +184,59 @@ def get_permissions(parser, token):
{% get_permissions obj for request.user as "my_permissions" %}
"""
- def next_bit_for(bits, key, if_none=None):
- try:
- return bits[bits.index(key)+1]
- except ValueError:
- return if_none
-
bits = token.contents.split()
kwargs = {
'obj': next_bit_for(bits, 'get_permissions'),
'user': next_bit_for(bits, 'for'),
'var_name': next_bit_for(bits, 'as', '"permissions"'),
}
+ return PermissionsForObjectNode(**kwargs)
+
+class PermissionForObjectNode(ResolverNode):
+ def __init__(self, perm, user, objs, var_name):
+ self.perm = perm
+ self.user = user
+ self.objs = objs
+ self.var_name = var_name
+
+ def render(self, context):
+ objs = [self.resolve(obj, context) for obj in self.objs.split(',')]
+ var_name = self.resolve(self.var_name, context)
+ perm = self.resolve(self.perm, context)
+ user = self.resolve(self.user, context)
+ granted = False
+ if not isinstance(user, AnonymousUser):
+ check = permissions.registry.get_check(user, perm)
+ if check is not None:
+ granted = check(*objs)
+ context[var_name] = granted
+ return ''
+
+@register.tag
+def get_permission(parser, token):
+ """
+ Performs a permission check with the given signature, user and objects
+ and assigns the result to a context variable.
+
+ Syntax::
+
+ {% get_permission [permission_label].[check_name] for [user] and [objs] as [varname] %}
+
+ {% get_permission "poll_permission.can_change" for request.user and poll as "is_allowed" %}
+ {% get_permission "poll_permission.can_change" for request.user and poll,second_poll as "is_allowed" %}
+
+ {% if is_allowed %}
+ I've got ze power to change ze pollllllzzz. Muahahaa.
+ {% else %}
+ Meh. No power for meeeee.
+ {% endif %}
+
+ """
+ bits = token.contents.split()
+ kwargs = {
+ 'perm': next_bit_for(bits, 'get_permission'),
+ 'user': next_bit_for(bits, 'for'),
+ 'objs': next_bit_for(bits, 'and'),
+ 'var_name': next_bit_for(bits, 'as', '"permission"'),
+ }
return PermissionForObjectNode(**kwargs)