changeset tagging in dvcs,
[redakcja.git] / apps / django_cas / decorators.py
1 """Replacement authentication decorators that work around redirection loops"""
2
3 try:
4     from functools import wraps
5 except ImportError:
6     from django.utils.functional import wraps
7
8 from django.contrib.auth import REDIRECT_FIELD_NAME
9 from django.contrib.auth.decorators import login_required
10 from django.http import HttpResponseForbidden, HttpResponseRedirect
11 from django.utils.http import urlquote
12
13 __all__ = ['login_required', 'permission_required', 'user_passes_test']
14
15
16 def user_passes_test(test_func, login_url=None,
17                      redirect_field_name=REDIRECT_FIELD_NAME):
18     """Replacement for django.contrib.auth.decorators.user_passes_test that
19     returns 403 Forbidden if the user is already logged in.
20     """
21
22     if not login_url:
23         from django.conf import settings
24         login_url = settings.LOGIN_URL
25
26     def decorator(view_func):
27         @wraps(view_func)
28         def wrapper(request, *args, **kwargs):
29             if test_func(request.user):
30                 return view_func(request, *args, **kwargs)
31             elif request.user.is_authenticated():
32                 return HttpResponseForbidden('<h1>Permission denied</h1>')
33             else:
34                 path = '%s?%s=%s' % (login_url, redirect_field_name,
35                                      urlquote(request.get_full_path()))
36                 return HttpResponseRedirect(path)
37         return wrapper
38     return decorator
39
40
41 def permission_required(perm, login_url=None):
42     """Replacement for django.contrib.auth.decorators.permission_required that
43     returns 403 Forbidden if the user is already logged in.
44     """
45
46     return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)