Statistics
| Branch: | Tag: | Revision:

root / aai / middleware.py @ d994d118

History | View | Annotate | Download (4.3 kB)

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

    
8
class SynnefoAuthMiddleware(object):
9

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

    
14
    def process_request(self, request):
15
        if not request.path.startswith('/api/') :
16
            #print time.strftime("[%d/%b/%Y %H:%M:%S]"), " Path", \
17
            #  request.path , ": Not authenticated"
18
            return
19
        token = request.META.get('HTTP_X_AUTH_TOKEN', None)        
20
        if token:
21
            user = None
22
            #Retrieve user from DB or other caching mechanism
23
            try:
24
                user = SynnefoUser.objects.get(auth_token=token)
25
            except SynnefoUser.DoesNotExist:
26
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
27

    
28
            #Check user's auth token
29
            if (time.time() -
30
                time.mktime(user.auth_token_created.timetuple()) -
31
                settings.AUTH_TOKEN_DURATION * 3600) > 0:
32
                #The user's token has expired, re-login
33
                return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
34

    
35
            request.user = user
36
            return
37

    
38
        #A user authenticated by Shibboleth, must include a uniq id
39
        if Tokens.SIB_EPPN in request.META and Tokens.SIB_SESSION_ID in request.META:
40
            user = None
41
            try:
42
                user = SynnefoUser.objects.get(
43
                    uniq = request.META[Tokens.SIB_EPPN])
44
            except SynnefoUser.DoesNotExist:
45
                pass
46

    
47
            #No user with this id could be found in the database
48
            if user is None:
49
                #Attempt to register the incoming user
50
                if register_shibboleth_user(request.META):
51
                    user = SynnefoUser.objects.get(
52
                        uniq = request.META[Tokens.SIB_EPPN])
53
                    return self._redirect_shib_auth_user(user)
54
                else:
55
                    return HttpResponseRedirect(settings.APP_INSTALL_URL + settings.LOGIN_PATH)
56

    
57
            #User and authentication token valid, user allowed to proceed
58
            return self._redirect_shib_auth_user(user)
59

    
60
        #An API authentication request
61
        if self.auth_user in request.META and self.auth_key in request.META and 'GET' == request.method:
62
            # This is here merely for compatibility with the Openstack API.
63
            # All normal users should authenticate through Sibbolleth. Admin
64
            # users or other selected users could use this as a bypass
65
            # mechanism
66
            user = SynnefoUser.objects\
67
                    .filter(name = request.META[self.auth_user]) \
68
                    .filter(uniq = request.META[self.auth_key])
69

    
70
            response = HttpResponse()
71
            if user.count() <= 0:
72
                response.status_code = 401
73
            else:
74
                response.status_code = 204
75
                response['X-Auth-Token'] = user[0].auth_token
76
                #TODO: set the following fields when we do have this info
77
                response['X-Server-Management-Url'] = ""
78
                response['X-Storage-Url'] = ""
79
                response['X-CDN-Management-Url'] = ""
80
            return response
81

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

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

    
100

    
101
    def _redirect_shib_auth_user(self, user):
102
        response = HttpResponse()
103
        response[self.auth_token] = user.auth_token
104
        response['Location'] = settings.APP_INSTALL_URL
105
        response.status_code = 302
106
        return response