~canonical-django/canonical-django/project-template

« back to all changes in this revision

Viewing changes to trunk/python-packages/django/contrib/auth/decorators.py

  • Committer: Matthew Nuzum
  • Date: 2008-11-13 05:46:03 UTC
  • Revision ID: matthew.nuzum@canonical.com-20081113054603-v0kvr6z6xyexvqt3
adding to version control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
try:
 
2
    from functools import update_wrapper
 
3
except ImportError:
 
4
    from django.utils.functional import update_wrapper  # Python 2.3, 2.4 fallback.
 
5
 
 
6
from django.contrib.auth import REDIRECT_FIELD_NAME
 
7
from django.http import HttpResponseRedirect
 
8
from django.utils.http import urlquote
 
9
 
 
10
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
 
11
    """
 
12
    Decorator for views that checks that the user passes the given test,
 
13
    redirecting to the log-in page if necessary. The test should be a callable
 
14
    that takes the user object and returns True if the user passes.
 
15
    """
 
16
    def decorate(view_func):
 
17
        return _CheckLogin(view_func, test_func, login_url, redirect_field_name)
 
18
    return decorate
 
19
 
 
20
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
 
21
    """
 
22
    Decorator for views that checks that the user is logged in, redirecting
 
23
    to the log-in page if necessary.
 
24
    """
 
25
    actual_decorator = user_passes_test(
 
26
        lambda u: u.is_authenticated(),
 
27
        redirect_field_name=redirect_field_name
 
28
    )
 
29
    if function:
 
30
        return actual_decorator(function)
 
31
    return actual_decorator
 
32
 
 
33
def permission_required(perm, login_url=None):
 
34
    """
 
35
    Decorator for views that checks whether a user has a particular permission
 
36
    enabled, redirecting to the log-in page if necessary.
 
37
    """
 
38
    return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)
 
39
 
 
40
class _CheckLogin(object):
 
41
    """
 
42
    Class that checks that the user passes the given test, redirecting to
 
43
    the log-in page if necessary. If the test is passed, the view function
 
44
    is invoked. The test should be a callable that takes the user object
 
45
    and returns True if the user passes.
 
46
 
 
47
    We use a class here so that we can define __get__. This way, when a
 
48
    _CheckLogin object is used as a method decorator, the view function
 
49
    is properly bound to its instance.
 
50
    """
 
51
    def __init__(self, view_func, test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
 
52
        if not login_url:
 
53
            from django.conf import settings
 
54
            login_url = settings.LOGIN_URL
 
55
        self.view_func = view_func
 
56
        self.test_func = test_func
 
57
        self.login_url = login_url
 
58
        self.redirect_field_name = redirect_field_name
 
59
        update_wrapper(self, view_func)
 
60
        
 
61
    def __get__(self, obj, cls=None):
 
62
        view_func = self.view_func.__get__(obj, cls)
 
63
        return _CheckLogin(view_func, self.test_func, self.login_url, self.redirect_field_name)
 
64
    
 
65
    def __call__(self, request, *args, **kwargs):
 
66
        if self.test_func(request.user):
 
67
            return self.view_func(request, *args, **kwargs)
 
68
        path = urlquote(request.get_full_path())
 
69
        tup = self.login_url, self.redirect_field_name, path
 
70
        return HttpResponseRedirect('%s?%s=%s' % tup)