Statistics
| Branch: | Tag: | Revision:

root / aai / middleware.py @ fdc10aee

History | View | Annotate | Download (4 kB)

1
from django.conf import settings
2
from django.http import HttpResponse, HttpResponseRedirect
3
from synnefo.db.models import SynnefoUser
4
from synnefo.aai.shibboleth import Tokens, register_shibboleth_user
5
import time
6

    
7
class SynnefoAuthMiddleware(object):
8

    
9
    auth_token = "X-Auth-Token"
10
    auth_user  = "X-Auth-User"
11
    auth_key   = "X-Auth-Key"
12

    
13
    def process_request(self, request):
14
        if request.path.startswith('/api/') :
15
            return
16

    
17
        if request.path.startswith('/invitations/login') :
18
            return
19

    
20
        # Special case for testing purposes, delivers the cookie for the
21
        # test user on first access
22
        if settings.BYPASS_AUTHENTICATION and \
23
           request.GET.get('test') is not None:
24
            u = SynnefoUser.objects.get(
25
                auth_token='46e427d657b20defe352804f0eb6f8a2')
26
            return self._redirect_shib_auth_user(user = u)
27

    
28
        token = None
29
        #Try to find token in a cookie
30
        try:
31
            token = request.COOKIES['X-Auth-Token']
32
        except Exception:
33
            pass
34

    
35
        #Try to find token in request header
36
        if not token:
37
            token = request.META.get('HTTP_X_AUTH_TOKEN', None)
38

    
39
        if token:
40
            user = None
41
            #Retrieve user from DB or other caching mechanism
42
            try:
43
                user = SynnefoUser.objects.get(auth_token=token)
44
            except SynnefoUser.DoesNotExist:
45
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
46

    
47
            #Check user's auth token
48
            if (time.time() -
49
                time.mktime(user.auth_token_expires.timetuple())) > 0:
50
                #The user's token has expired, re-login
51
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
52

    
53
            request.user = user
54
            return
55

    
56
        #A user authenticated by Shibboleth, must include a uniq id
57
        if Tokens.SHIB_EPPN in request.META and Tokens.SHIB_SESSION_ID in request.META:
58
            user = None
59
            try:
60
                user = SynnefoUser.objects.get(
61
                    uniq = request.META[Tokens.SHIB_EPPN])
62
            except SynnefoUser.DoesNotExist:
63
                pass
64

    
65
            #No user with this id could be found in the database
66
            if user is None:
67
                #Attempt to register the incoming user
68
                if register_shibboleth_user(request.META):
69
                    user = SynnefoUser.objects.get(
70
                        uniq = request.META[Tokens.SHIB_EPPN])
71
                    return self._redirect_shib_auth_user(user)
72
                else:
73
                    return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
74

    
75
            #User and authentication token valid, user allowed to proceed
76
            return self._redirect_shib_auth_user(user)
77

    
78
        if settings.TEST:
79
            if 'TEST-AAI' in request.META:
80
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
81
        else:
82
            #Avoid redirect loops
83
            if request.path.endswith(settings.LOGIN_PATH): 
84
                return
85
            else :
86
                #No authentication info found in headers, redirect to Shibboleth
87
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
88

    
89
    def process_response(self, request, response):
90
        #Tell proxies and other interested parties that the
91
        #request varies based on the auth token, to avoid
92
        #caching of results
93
        response['Vary'] = self.auth_token
94
        return response
95

    
96
    def _redirect_shib_auth_user(self, user):
97
        expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z')
98

    
99
        response = HttpResponse()
100

    
101
        response.set_cookie('X-Auth-Token', value=user.auth_token, expires = expire_fmt, path='/')
102
        response[self.auth_token] = user.auth_token
103
        response['Location'] = settings.APP_INSTALL_URL
104
        response.status_code = 302
105
        return response