File: decorators.py

package info (click to toggle)
python-django-casclient 1.5.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212 kB
  • sloc: python: 756; makefile: 160
file content (106 lines) | stat: -rw-r--r-- 3,688 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps

try:
    from urllib import urlencode
except ImportError:
    from urllib.parse import urlencode

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponseForbidden, HttpResponseRedirect
from django.utils.http import urlquote
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

__all__ = ['permission_required', 'user_passes_test']


def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Replacement for django.contrib.auth.decorators.user_passes_test that
    returns 403 Forbidden if the user is already logged in.
    """

    if not login_url:
        login_url = settings.LOGIN_URL

    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):

            try:
                # use callable for pre-django 2.0
                is_authenticated = request.user.is_authenticated()
            except TypeError:
                is_authenticated = request.user.is_authenticated

            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            elif is_authenticated:
                return HttpResponseForbidden('<h1>Permission denied</h1>')
            else:
                path = '%s?%s=%s' % (login_url, redirect_field_name,
                                     urlquote(request.get_full_path()))
                return HttpResponseRedirect(path)
        return wrapper
    return decorator


def permission_required(perm, login_url=None):
    """
    Replacement for django.contrib.auth.decorators.permission_required that
    returns 403 Forbidden if the user is already logged in.
    """

    return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)


def gateway():
    """
    Authenticates single sign on session if ticket is available,
    but doesn't redirect to sign in url otherwise.
    """

    if settings.CAS_GATEWAY == False:
        raise ImproperlyConfigured('CAS_GATEWAY must be set to True')

    def wrap(func):
        def wrapped_f(*args):

            from cas.views import login
            request = args[0]

            try:
                # use callable for pre-django 2.0
                is_authenticated = request.user.is_authenticated()
            except TypeError:
                is_authenticated = request.user.is_authenticated

            if is_authenticated:
                # Is Authed, fine
                pass
            else:
                path_with_params = request.path + '?' + urlencode(request.GET.copy())
                if request.GET.get('ticket'):
                    # Not Authed, but have a ticket!
                    # Try to authenticate
                    response = login(request, path_with_params, False, True)
                    if isinstance(response, HttpResponseRedirect):
                        # For certain instances where a forbidden occurs, we need to pass instead of return a response.
                        return response
                else:
                    #Not Authed, but no ticket
                    gatewayed = request.GET.get('gatewayed')
                    if gatewayed == 'true':
                        pass
                    else:
                        # Not Authed, try to authenticate
                        response = login(request, path_with_params, False, True)
                        if isinstance(response, HttpResponseRedirect):
                            return response

            return func(*args)
        return wrapped_f
    return wrap