Statistics
| Branch: | Tag: | Revision:

root / aai / middleware.py @ 60de282a

History | View | Annotate | Download (4.3 kB)

1 dbf97ed2 Georgios Gousios
from time import time
2 ef39e7ee Georgios Gousios
from django.conf import settings
3 ef39e7ee Georgios Gousios
from django.http import HttpResponse, HttpResponseRedirect
4 89f86fd3 Georgios Gousios
from synnefo.db.models import SynnefoUser
5 8f377cd6 Georgios Gousios
from synnefo.aai.shibboleth import Tokens, register_shibboleth_user
6 faa26af8 Georgios Gousios
import time
7 89f86fd3 Georgios Gousios
8 89f86fd3 Georgios Gousios
class SynnefoAuthMiddleware(object):
9 89f86fd3 Georgios Gousios
10 89f86fd3 Georgios Gousios
    auth_token = "X-Auth-Token"
11 89f86fd3 Georgios Gousios
    auth_user  = "X-Auth-User"
12 89f86fd3 Georgios Gousios
    auth_key   = "X-Auth-Key"
13 89f86fd3 Georgios Gousios
14 89f86fd3 Georgios Gousios
    def process_request(self, request):
15 ef39e7ee Georgios Gousios
16 89f86fd3 Georgios Gousios
        if self.auth_token in request.META:
17 faa26af8 Georgios Gousios
            user = None
18 ef39e7ee Georgios Gousios
            #Retrieve user from DB or other caching mechanism
19 faa26af8 Georgios Gousios
            try:
20 faa26af8 Georgios Gousios
                user = SynnefoUser.objects.get(auth_token = request.META[self.auth_token])
21 faa26af8 Georgios Gousios
            except SynnefoUser.DoesNotExist:
22 60de282a Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_PATH)
23 faa26af8 Georgios Gousios
24 faa26af8 Georgios Gousios
            #Check user's auth token
25 faa26af8 Georgios Gousios
            if (time.time() -
26 faa26af8 Georgios Gousios
                time.mktime(user.auth_token_created.timetuple()) +
27 faa26af8 Georgios Gousios
                settings.AUTH_TOKEN_DURATION * 3600) > 0:
28 faa26af8 Georgios Gousios
                #The user's token has expired, re-login
29 60de282a Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_PATH)
30 faa26af8 Georgios Gousios
31 89f86fd3 Georgios Gousios
            request.user = user
32 ef39e7ee Georgios Gousios
            return
33 89f86fd3 Georgios Gousios
34 faa26af8 Georgios Gousios
        #A user authenticated by Shibboleth, must include a uniq id
35 dbf97ed2 Georgios Gousios
        if Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME in request.META:
36 57e59589 Georgios Gousios
            #We must somehow make sure that we only process
37 57e59589 Georgios Gousios
            #SIB headers when coming from a URL whitelist,
38 57e59589 Georgios Gousios
            #or a similar form of restriction
39 1896d262 Georgios Gousios
            if request.get_host() not in settings.SHIBBOLETH_WHITELIST.keys():
40 60de282a Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_PATH)
41 dbf97ed2 Georgios Gousios
42 1896d262 Georgios Gousios
            user = None
43 1896d262 Georgios Gousios
            try:
44 1896d262 Georgios Gousios
                user = SynnefoUser.objects.get(
45 1896d262 Georgios Gousios
                    uniq = request.META[Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME])
46 1896d262 Georgios Gousios
            except SynnefoUser.DoesNotExist:
47 1896d262 Georgios Gousios
                pass
48 dbf97ed2 Georgios Gousios
49 dbf97ed2 Georgios Gousios
            #No user with this id could be found in the database
50 dbf97ed2 Georgios Gousios
            if user is None:
51 57e59589 Georgios Gousios
                #Attempt to register the incoming user
52 dbf97ed2 Georgios Gousios
                if register_shibboleth_user(request.META):
53 57e59589 Georgios Gousios
                    user = SynnefoUser.objects.get(
54 57e59589 Georgios Gousios
                        uniq = request.META[Tokens.SIB_EDU_PERSON_PRINCIPAL_NAME])
55 57e59589 Georgios Gousios
                    response = HttpResponse()
56 57e59589 Georgios Gousios
                    response[self.auth_token] = user.auth_token
57 57e59589 Georgios Gousios
                    response['Location'] = "/"
58 57e59589 Georgios Gousios
                    response.status_code = 302
59 57e59589 Georgios Gousios
                    return response
60 57e59589 Georgios Gousios
                else:
61 60de282a Georgios Gousios
                    return HttpResponseRedirect(settings.LOGIN_PATH)
62 dbf97ed2 Georgios Gousios
63 dbf97ed2 Georgios Gousios
            #User and authentication token valid, user allowed to proceed
64 dbf97ed2 Georgios Gousios
            return
65 25380811 Georgios Gousios
66 dbf97ed2 Georgios Gousios
        #An API authentication request
67 25380811 Georgios Gousios
        if self.auth_user in request.META and self.auth_key in request.META and 'GET' == request.method:
68 ef39e7ee Georgios Gousios
            # This is here merely for compatibility with the Openstack API.
69 ef39e7ee Georgios Gousios
            # All normal users should authenticate through Sibbolleth. Admin
70 ef39e7ee Georgios Gousios
            # users or other selected users could use this as a bypass
71 ef39e7ee Georgios Gousios
            # mechanism
72 25380811 Georgios Gousios
            user = SynnefoUser.objects\
73 25380811 Georgios Gousios
                    .filter(name = request.META[self.auth_user]) \
74 25380811 Georgios Gousios
                    .filter(uniq = request.META[self.auth_key])
75 25380811 Georgios Gousios
76 25380811 Georgios Gousios
            response = HttpResponse()
77 25380811 Georgios Gousios
            if user.count() <= 0:
78 25380811 Georgios Gousios
                response.status_code = 401
79 25380811 Georgios Gousios
            else:
80 25380811 Georgios Gousios
                response.status_code = 204
81 25380811 Georgios Gousios
                response['X-Auth-Token'] = user[0].auth_token
82 25380811 Georgios Gousios
                #TODO: set the following fields when we do have this info
83 25380811 Georgios Gousios
                response['X-Server-Management-Url'] = ""
84 25380811 Georgios Gousios
                response['X-Storage-Url'] = ""
85 25380811 Georgios Gousios
                response['X-CDN-Management-Url'] = ""
86 25380811 Georgios Gousios
            return response
87 ef39e7ee Georgios Gousios
88 ea2bea47 Georgios Gousios
        if settings.TEST:
89 8f377cd6 Georgios Gousios
            if 'TEST-AAI' in request.META:
90 60de282a Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_PATH)
91 8f377cd6 Georgios Gousios
        else:
92 60de282a Georgios Gousios
            #Avoid redirect loops
93 60de282a Georgios Gousios
            if 'Referer' in request.META and request.META['Referer'].endswith(settings.LOGIN_PATH):
94 60de282a Georgios Gousios
                return
95 60de282a Georgios Gousios
            else :
96 60de282a Georgios Gousios
                #No authentication info found in headers, redirect to Shibboleth
97 60de282a Georgios Gousios
                return HttpResponseRedirect(settings.LOGIN_PATH)
98 dd53338a Georgios Gousios
99 dd53338a Georgios Gousios
    def process_response(self, request, response):
100 dbf97ed2 Georgios Gousios
        #Tell proxies and other interested parties that the
101 dbf97ed2 Georgios Gousios
        #request varies based on the auth token, to avoid
102 dbf97ed2 Georgios Gousios
        #caching of results
103 57e59589 Georgios Gousios
        response['Vary'] = self.auth_token
104 dd53338a Georgios Gousios
        return response