mirror of
https://github.com/jazzband/django-authority.git
synced 2026-05-03 13:14:43 +00:00
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.
73 lines
3.2 KiB
Python
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)
|