source: mauRepo/dj_security_middleware/trunk/dj_security_middleware/dj_security_middleware/middleware.py @ 8669

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/dj_security_middleware/trunk/dj_security_middleware/dj_security_middleware/middleware.py@8669
Revision 8669, 5.1 KB checked in by mnagni, 8 years ago (diff)

Improved the middleware hostname/IP retrivial feature

  • Property svn:mime-type set to text/plain
Line 
1'''
2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29Created on 2 Nov 2012
30
31@author: mnagni
32'''
33from django.http import HttpResponseRedirect
34from paste.auth import auth_tkt
35from paste.auth.auth_tkt import BadTicket
36from django.conf import settings
37from dj_security_middleware.exception import DJMiddlewareException,\
38    MissingCookieException
39from django.utils.html import escape
40from django.utils.http import urlencode
41
42LOGIN_SERVICE_ERROR = 'No LOGIN_SETTING parameter is defined in the \
43application settings.py file. Please define a proper URL to the \
44authenticating service'
45
46DJ_SECURITY_SHAREDSECRET_ERROR = 'No DJ_SECURITY_SHAREDSECRET parameter \
47is defined in the application settings.py file. \
48Please define it accordingly to the used LOGIN_SERVICE'
49
50AUTHENTICATION_COOKIE_MISSING = 'The expected cookie is missing. \
51Redirect to the authentication service'
52
53DJ_MIDDLEWARE_IP_ERROR = 'No DJ_MIDDLEWARE_IP parameter \
54is defined in the application settings.py file. \
55Please define it accordingly to the machine/proxy seen by the LOGIN_SERVICE'
56
57class DJ_Security_Middleware(object):
58    """
59        Validates if the actual user is authenticated agains a
60        given authentication service.
61        Actually the middleware intercepts all the requests submitted
62        to the underlying Django application and verifies if the presence
63        or not of a valid paste cookie in the request.
64    """   
65    def process_request(self, request):
66        if not settings.DJ_SECURITY_LOGIN_SERVICE:
67            raise DJMiddlewareException(LOGIN_SERVICE_ERROR) 
68        if not settings.DJ_SECURITY_SHAREDSECRET:
69            raise DJMiddlewareException(DJ_SECURITY_SHAREDSECRET_ERROR)       
70        if not settings.DJ_MIDDLEWARE_IP:
71            raise DJMiddlewareException(DJ_MIDDLEWARE_IP_ERROR)       
72         
73        try:
74            timestamp, userid, tokens, user_data = _is_authenticated(request)
75        except MissingCookieException:             
76            url = '%s?%s' % (settings.DJ_SECURITY_LOGIN_SERVICE, _build_ret_url(request))
77            return HttpResponseRedirect(url)       
78
79def _build_ret_url(request):
80    hostname = _get_hostname()
81    if request.META['SERVER_PORT'] != 80:
82        hostname = "%s:%s" % (hostname, request.META['SERVER_PORT'])
83    qs = {}
84    qs['r'] = escape('http://%s%s' % (hostname, request.path))
85    return urlencode(qs)           
86
87def _is_authenticated(request):
88    """
89        Verifies the presence and validity of a paste cookie.
90        If the cookie is not present the request is redirected
91        to the url specified in LOGIN_SERVICE
92        ** Return ** a tuple containing (timestamp, userid, tokens, user_data)
93        ** raise ** a DJ_SecurityException if the ticket is not valid
94    """
95    if request.COOKIES.has_key('auth_tkt'):
96        try:
97            return auth_tkt.parse_ticket(
98                    settings.DJ_SECURITY_SHAREDSECRET,
99                    request.COOKIES['auth_tkt'], _get_host_ip())
100        except BadTicket as ex:
101            raise DJMiddlewareException(ex)   
102    raise MissingCookieException(AUTHENTICATION_COOKIE_MISSING)
103
104def _get_hostname():
105    import socket
106    ret = 'localhost'
107    try:
108        hostname = socket.gethostname()
109        ret = socket.gethostbyname_ex(hostname)[0]
110    except Exception:
111        pass   
112    return ret
113   
114def _get_host_ip():
115    if settings.DJ_MIDDLEWARE_IP:
116        return settings.DJ_MIDDLEWARE_IP
117       
118    import socket
119    ret = 'localhost'
120    try:
121        hostname = socket.gethostname()
122        ret = socket.gethostbyname_ex(hostname)[2][0]
123    except Exception:
124        pass   
125    return ret   
Note: See TracBrowser for help on using the repository browser.