Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / aai / middleware.py @ 9c0ac5af

History | View | Annotate | Download (5.3 kB)

1 48130e66 Georgios Gousios
# Copyright 2011 GRNET S.A. All rights reserved.
2 48130e66 Georgios Gousios
#
3 48130e66 Georgios Gousios
# Redistribution and use in source and binary forms, with or without
4 48130e66 Georgios Gousios
# modification, are permitted provided that the following conditions
5 48130e66 Georgios Gousios
# are met:
6 48130e66 Georgios Gousios
#
7 48130e66 Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
8 48130e66 Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
9 48130e66 Georgios Gousios
#
10 48130e66 Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
11 48130e66 Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
12 48130e66 Georgios Gousios
#     documentation and/or other materials provided with the distribution.
13 48130e66 Georgios Gousios
#
14 48130e66 Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 48130e66 Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 48130e66 Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 48130e66 Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 48130e66 Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 48130e66 Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 48130e66 Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 48130e66 Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 48130e66 Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 48130e66 Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 48130e66 Georgios Gousios
# SUCH DAMAGE.
25 48130e66 Georgios Gousios
#
26 48130e66 Georgios Gousios
# The views and conclusions contained in the software and documentation are
27 48130e66 Georgios Gousios
# those of the authors and should not be interpreted as representing official
28 48130e66 Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
29 48130e66 Georgios Gousios
30 ef39e7ee Georgios Gousios
from django.conf import settings
31 ef39e7ee Georgios Gousios
from django.http import HttpResponse, HttpResponseRedirect
32 5032e934 Faidon Liambotis
from django.utils.cache import patch_vary_headers
33 89f86fd3 Georgios Gousios
from synnefo.db.models import SynnefoUser
34 8f377cd6 Georgios Gousios
from synnefo.aai.shibboleth import Tokens, register_shibboleth_user
35 faa26af8 Georgios Gousios
import time
36 89f86fd3 Georgios Gousios
37 e26fb12b Georgios Gousios
DONT_CHECK = getattr(settings, "AAI_SKIP_AUTH_URLS", ['/api', '/invitations/login'])
38 5ac53b64 Georgios Gousios
39 89f86fd3 Georgios Gousios
class SynnefoAuthMiddleware(object):
40 89f86fd3 Georgios Gousios
41 89f86fd3 Georgios Gousios
    def process_request(self, request):
42 c06de383 Georgios Gousios
43 1b68fa48 Georgios Gousios
        for path in DONT_CHECK:
44 1b68fa48 Georgios Gousios
            if request.path.startswith(path):
45 1b68fa48 Georgios Gousios
                return
46 def2c5c1 Georgios Gousios
47 89b6b240 Georgios Gousios
        # Special case for testing purposes, delivers the cookie for the
48 89b6b240 Georgios Gousios
        # test user on first access
49 6ff84e93 Georgios Gousios
        if settings.BYPASS_AUTHENTICATION and \
50 6ff84e93 Georgios Gousios
           request.GET.get('test') is not None:
51 34d1013b Vangelis Koukis
            try:
52 34d1013b Vangelis Koukis
                u = SynnefoUser.objects.get(
53 34d1013b Vangelis Koukis
                    auth_token=settings.BYPASS_AUTHENTICATION_SECRET_TOKEN)
54 34d1013b Vangelis Koukis
            except SynnefoUser.DoesNotExist:
55 34d1013b Vangelis Koukis
                raise Exception("No user found with token matching "
56 34d1013b Vangelis Koukis
                                "BYPASS_AUTHENTICATION_SECRET_TOKEN.")
57 c9fdfa27 Georgios Gousios
            return self._redirect_shib_auth_user(user = u)
58 89b6b240 Georgios Gousios
59 c06de383 Georgios Gousios
        token = None
60 c06de383 Georgios Gousios
61 5563866c Georgios Gousios
        # Try to find token in a cookie
62 d01e6404 Faidon Liambotis
        token = request.COOKIES.get('X-Auth-Token', None)
63 c06de383 Georgios Gousios
64 5563866c Georgios Gousios
        # Try to find token in request header
65 c06de383 Georgios Gousios
        if not token:
66 c06de383 Georgios Gousios
            token = request.META.get('HTTP_X_AUTH_TOKEN', None)
67 c06de383 Georgios Gousios
68 40777cc8 Giorgos Verigakis
        if token:
69 d01e6404 Faidon Liambotis
            # token was found, retrieve user from backing store
70 faa26af8 Georgios Gousios
            try:
71 40777cc8 Giorgos Verigakis
                user = SynnefoUser.objects.get(auth_token=token)
72 5563866c Georgios Gousios
73 faa26af8 Georgios Gousios
            except SynnefoUser.DoesNotExist:
74 79d8af70 Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_URL)
75 d01e6404 Faidon Liambotis
            # check user's auth token validity
76 faa26af8 Georgios Gousios
            if (time.time() -
77 c9fdfa27 Georgios Gousios
                time.mktime(user.auth_token_expires.timetuple())) > 0:
78 d01e6404 Faidon Liambotis
                # the user's token has expired, prompt to re-login
79 79d8af70 Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_URL)
80 faa26af8 Georgios Gousios
81 89f86fd3 Georgios Gousios
            request.user = user
82 ef39e7ee Georgios Gousios
            return
83 89f86fd3 Georgios Gousios
84 d01e6404 Faidon Liambotis
        # token was not found but user authenticated by Shibboleth
85 d01e6404 Faidon Liambotis
        if Tokens.SHIB_EPPN in request.META and \
86 d01e6404 Faidon Liambotis
           Tokens.SHIB_SESSION_ID in request.META:
87 1896d262 Georgios Gousios
            try:
88 d01e6404 Faidon Liambotis
                user = SynnefoUser.objects.get(uniq=request.META[Tokens.SHIB_EPPN])
89 d01e6404 Faidon Liambotis
                return self._redirect_shib_auth_user(user)
90 1896d262 Georgios Gousios
            except SynnefoUser.DoesNotExist:
91 dbf97ed2 Georgios Gousios
                if register_shibboleth_user(request.META):
92 d01e6404 Faidon Liambotis
                    user = SynnefoUser.objects.get(uniq=request.META[Tokens.SHIB_EPPN])
93 ac3c3a4b Georgios Gousios
                    return self._redirect_shib_auth_user(user)
94 57e59589 Georgios Gousios
                else:
95 79d8af70 Georgios Gousios
                    return HttpResponseRedirect(settings.LOGIN_URL)
96 dbf97ed2 Georgios Gousios
97 d01e6404 Faidon Liambotis
        if settings.TEST and 'TEST-AAI' in request.META:
98 79d8af70 Georgios Gousios
            return HttpResponseRedirect(settings.LOGIN_URL)
99 25380811 Georgios Gousios
100 79d8af70 Georgios Gousios
        if request.path.endswith(settings.LOGIN_URL):
101 d01e6404 Faidon Liambotis
            # avoid redirect loops
102 d01e6404 Faidon Liambotis
            return
103 8f377cd6 Georgios Gousios
        else:
104 d01e6404 Faidon Liambotis
            # no authentication info found in headers, redirect back
105 79d8af70 Georgios Gousios
            return HttpResponseRedirect(settings.LOGIN_URL)
106 dd53338a Georgios Gousios
107 dd53338a Georgios Gousios
    def process_response(self, request, response):
108 d01e6404 Faidon Liambotis
        # Tell proxies and other interested parties that the request varies
109 d01e6404 Faidon Liambotis
        # based on X-Auth-Token, to avoid caching of results
110 5032e934 Faidon Liambotis
        patch_vary_headers(response, ('X-Auth-Token',))
111 dd53338a Georgios Gousios
        return response
112 63efc637 Georgios Gousios
113 ac3c3a4b Georgios Gousios
    def _redirect_shib_auth_user(self, user):
114 c9fdfa27 Georgios Gousios
        expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z')
115 c06de383 Georgios Gousios
116 ac3c3a4b Georgios Gousios
        response = HttpResponse()
117 4733c1b0 Georgios Gousios
        response.set_cookie('X-Auth-Token', value=user.auth_token,
118 4733c1b0 Georgios Gousios
                            expires=expire_fmt, path='/')
119 d01e6404 Faidon Liambotis
        response['X-Auth-Token'] = user.auth_token
120 ac3c3a4b Georgios Gousios
        response['Location'] = settings.APP_INSTALL_URL
121 ac3c3a4b Georgios Gousios
        response.status_code = 302
122 ac3c3a4b Georgios Gousios
        return response
123 5ac53b64 Georgios Gousios
124 5ac53b64 Georgios Gousios
125 5ac53b64 Georgios Gousios
def add_url_exception(url):
126 5ac53b64 Georgios Gousios
    if not url in DONT_CHECK:
127 5ac53b64 Georgios Gousios
        DONT_CHECK.append(url)