mirror of
https://github.com/jazzband/django-authority.git
synced 2026-03-16 22:20:28 +00:00
Overhaul to the templatetags. New templatetag get_permission to perform a specific permission check.
This commit is contained in:
parent
b1356e8761
commit
1cfcf334ce
2 changed files with 124 additions and 47 deletions
|
|
@ -44,24 +44,37 @@
|
|||
</li>
|
||||
|
||||
<li><h2>Detailed tests</h2>
|
||||
|
||||
<h3>Can I change this flatpage?</h3>
|
||||
<p>"can_change" of the custom permission set "flatpage_permission":</p>
|
||||
<p>ifhasperm "flatpage_permission.change_flatpage" request.user:</p>
|
||||
<blockquote>
|
||||
{% 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 %}
|
||||
</blockquote>
|
||||
<h3>Can I access top secret flat pages?</h3>
|
||||
<p>"top_secret" of the custom permission set "flatpage_permission":</p>
|
||||
|
||||
<h3>Can I access this top secret flat page?</h3>
|
||||
<p>ifhasperm "flatpage_permission.top_secret" request.user flatpage:</p>
|
||||
<blockquote>
|
||||
{% 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 %}
|
||||
</blockquote>
|
||||
|
||||
<h3>Again, can I really access this top secret flat page?</h3>
|
||||
<p>get_permission "flatpage_permission.top_secret" for request.user and flatpage as "secret_agent":</p>
|
||||
{% get_permission "flatpage_permission.top_secret" for request.user and flatpage as "secret_agent" %}
|
||||
<blockquote>
|
||||
{% if secret_agent %}
|
||||
Yes {{ request.user }}, you are a secret agent
|
||||
{% else %}
|
||||
Nope, only a programmer, sorry
|
||||
{% endif %}
|
||||
</blockquote>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue