mirror of
https://github.com/jazzband/django-authority.git
synced 2026-03-16 22:20:28 +00:00
Fixed decorator to only check for permissions if user is logged in. Added permission_denied view to be used when permission check unsuccessful, e.g. with the new permission_required_or_403 decorator. The permission_required decorator will redirect to the login form by default.
This commit is contained in:
parent
0f14d735a3
commit
287d2eccd5
3 changed files with 56 additions and 25 deletions
|
|
@ -1,8 +1,9 @@
|
|||
from django.contrib.flatpages.views import flatpage
|
||||
from django.contrib.flatpages.models import FlatPage
|
||||
|
||||
from authority.decorators import permission_required
|
||||
from authority.decorators import permission_required, permission_required_or_403
|
||||
|
||||
#@permission_required_or_403('flatpage_permission.top_secret', (FlatPage, 'url__contains')) # use this to return a 403 page
|
||||
@permission_required('flatpage_permission.top_secret', (FlatPage, 'url__contains'))
|
||||
def top_secret(request, url):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -10,38 +10,49 @@ from django.contrib.auth.decorators import user_passes_test
|
|||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
|
||||
from authority import permissions
|
||||
from authority.views import permission_denied
|
||||
|
||||
def permission_required(perm, *args, **kwargs):
|
||||
"""
|
||||
Decorator for views that checks whether a user has a particular permission
|
||||
enabled, redirecting to the log-in page if necessary.
|
||||
"""
|
||||
login_url = kwargs.pop('login_url', None)
|
||||
if not login_url:
|
||||
login_url = getattr(settings, 'LOGIN_URL', '/')
|
||||
login_url = kwargs.pop('login_url', settings.LOGIN_URL)
|
||||
redirect_field_name = kwargs.pop('redirect_field_name', REDIRECT_FIELD_NAME)
|
||||
redirect_to_login = kwargs.pop('redirect_to_login', True)
|
||||
model_lookups = args
|
||||
def _permission_required(view_func, request, *args, **kwargs):
|
||||
objs = []
|
||||
# model_lookups = [('flatpages.flatpage', 'url__contains')]
|
||||
for i, arguments in enumerate(model_lookups):
|
||||
model, lookup = arguments
|
||||
if isinstance(model, basestring):
|
||||
model_class = get_model(*model.split("."))
|
||||
else:
|
||||
model_class = model
|
||||
if model_class is None:
|
||||
raise ValueError(
|
||||
"The given argument '%s' is not a valid model." % model)
|
||||
if inspect.isclass(model_class) and \
|
||||
not issubclass(model_class, Model):
|
||||
raise ValueError(
|
||||
'The argument %s needs to be a model.' % model)
|
||||
objs.append(get_object_or_404(model_class, **{lookup: args[i]}))
|
||||
check = permissions.registry.get_check(request.user, perm)
|
||||
if check is not None:
|
||||
if check(*objs):
|
||||
return view_func(request, *args, **kwargs)
|
||||
#return HttpResponseForbidden("Permission")
|
||||
raise PermissionDenied()
|
||||
if request.user.is_authenticated():
|
||||
for i, arguments in enumerate(model_lookups):
|
||||
model, lookup = arguments
|
||||
if isinstance(model, basestring):
|
||||
model_class = get_model(*model.split("."))
|
||||
else:
|
||||
model_class = model
|
||||
if model_class is None:
|
||||
raise ValueError(
|
||||
"The given argument '%s' is not a valid model." % model)
|
||||
if inspect.isclass(model_class) and \
|
||||
not issubclass(model_class, Model):
|
||||
raise ValueError(
|
||||
'The argument %s needs to be a model.' % model)
|
||||
objs.append(get_object_or_404(model_class, **{lookup: args[i]}))
|
||||
check = permissions.registry.get_check(request.user, perm)
|
||||
if check is not None:
|
||||
if check(*objs):
|
||||
return view_func(request, *args, **kwargs)
|
||||
if redirect_to_login:
|
||||
path = urlquote(request.get_full_path())
|
||||
tup = login_url, redirect_field_name, path
|
||||
return HttpResponseRedirect('%s?%s=%s' % tup)
|
||||
return permission_denied(request)
|
||||
return decorator(_permission_required)
|
||||
|
||||
def permission_required_or_403(perm, *args, **kwargs):
|
||||
"""
|
||||
Decorator that wraps the permission_required decorator and returns a
|
||||
permission denied (403) page instead of redirecting to the login URL.
|
||||
"""
|
||||
kwargs['redirect_to_login'] = False
|
||||
return permission_required(perm, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from django.db.models.loading import get_model
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
from django.template.context import RequestContext
|
||||
from django.template import loader
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from authority.models import Permission
|
||||
|
|
@ -56,3 +57,21 @@ def delete_permission(request, permission_pk):
|
|||
message=ugettext('You removed the permission.'))
|
||||
next = request.REQUEST.get('next') or '/'
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
def permission_denied(request, template_name=None, extra_context={}):
|
||||
"""
|
||||
Default 403 handler.
|
||||
|
||||
Templates: `403.html`
|
||||
Context:
|
||||
request_path
|
||||
The path of the requested URL (e.g., '/app/pages/bad_page/')
|
||||
"""
|
||||
if template_name is None:
|
||||
template_name = ('authority/403.html', '403.html')
|
||||
context = {
|
||||
'request_path': request.path,
|
||||
}
|
||||
context.update(extra_context)
|
||||
return HttpResponseForbidden(loader.render_to_string(template_name, context,
|
||||
context_instance=RequestContext(request)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue