django-authority/authority/decorators.py
greg 91929a76c9 Features removed in 1.9 :
1. All models need to be defined inside an installed application or declare an explicit app_label. Furthermore, it isn’t possible to import them before their application is loaded. In particular, it isn’t possible to import models inside the root package of an application

2. The django.contrib.contenttypes.generic module is removed

3. django.db.models.loading is removed.
2016-07-27 18:41:25 +02:00

73 lines
3.2 KiB
Python

import inspect
from django.http import HttpResponseRedirect
from django.utils.http import urlquote
from django.utils.functional import wraps
from django.db.models import Model
from django.apps import apps
from django.shortcuts import get_object_or_404
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from authority.utils import get_check
from authority.views import permission_denied
def permission_required(perm, *lookup_variables, **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', settings.LOGIN_URL)
redirect_field_name = kwargs.pop('redirect_field_name', REDIRECT_FIELD_NAME)
redirect_to_login = kwargs.pop('redirect_to_login', True)
def decorate(view_func):
def decorated(request, *args, **kwargs):
if request.user.is_authenticated():
params = []
for lookup_variable in lookup_variables:
if isinstance(lookup_variable, basestring):
value = kwargs.get(lookup_variable, None)
if value is None:
continue
params.append(value)
elif isinstance(lookup_variable, (tuple, list)):
model, lookup, varname = lookup_variable
value = kwargs.get(varname, None)
if value is None:
continue
if isinstance(model, basestring):
model_class = apps.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)
obj = get_object_or_404(model_class, **{lookup: value})
params.append(obj)
check = get_check(request.user, perm)
granted = False
if check is not None:
granted = check(*params)
if granted or request.user.has_perm(perm):
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 wraps(view_func)(decorated)
return decorate
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)