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

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

Improved the 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
42import logging
43
44# Get an instance of a logger
45logger = logging.getLogger(__name__)
46
47LOGIN_SERVICE_ERROR = 'No LOGIN_SETTING parameter is defined in the \
48application settings.py file. Please define a proper URL to the \
49authenticating service'
50
51DJ_SECURITY_SHAREDSECRET_ERROR = 'No DJ_SECURITY_SHAREDSECRET parameter \
52is defined in the application settings.py file. \
53Please define it accordingly to the used LOGIN_SERVICE'
54
55AUTHENTICATION_COOKIE_MISSING = 'The expected cookie is missing. \
56Redirect to the authentication service'
57
58DJ_MIDDLEWARE_IP_ERROR = 'No DJ_MIDDLEWARE_IP parameter \
59is defined in the application settings.py file. \
60Please define it accordingly to the machine/proxy seen by the LOGIN_SERVICE'
61
62class DJ_Security_Middleware(object):
63    """
64        Validates if the actual user is authenticated agains a
65        given authentication service.
66        Actually the middleware intercepts all the requests submitted
67        to the underlying Django application and verifies if the presence
68        or not of a valid paste cookie in the request.
69    """   
70    def process_request(self, request):
71        if not settings.DJ_SECURITY_LOGIN_SERVICE:
72            raise DJMiddlewareException(LOGIN_SERVICE_ERROR) 
73        if not settings.DJ_SECURITY_SHAREDSECRET:
74            raise DJMiddlewareException(DJ_SECURITY_SHAREDSECRET_ERROR)       
75        #if not settings.DJ_MIDDLEWARE_IP:
76        #    raise DJMiddlewareException(DJ_MIDDLEWARE_IP_ERROR)       
77         
78        try:
79            timestamp, userid, tokens, user_data = _is_authenticated(request)
80        except (MissingCookieException, DJMiddlewareException):             
81            url = '%s?%s' % (settings.DJ_SECURITY_LOGIN_SERVICE, _build_ret_url(request))
82            return HttpResponseRedirect(url)       
83
84def _build_ret_url(request):
85    hostname = _get_hostname()
86    if request.META['SERVER_PORT'] != 80:
87        hostname = "%s:%s" % (hostname, request.META['SERVER_PORT'])
88    qs = {}
89    qs['r'] = escape('http://%s%s' % (hostname, request.path))
90    return urlencode(qs)           
91
92def _is_authenticated(request):
93    """
94        Verifies the presence and validity of a paste cookie.
95        If the cookie is not present the request is redirected
96        to the url specified in LOGIN_SERVICE
97        ** Return ** a tuple containing (timestamp, userid, tokens, user_data)
98        ** raise ** a DJ_SecurityException if the ticket is not valid
99    """
100    if request.COOKIES.has_key('auth_tkt'):
101        try:
102            return auth_tkt.parse_ticket(
103                    settings.DJ_SECURITY_SHAREDSECRET,
104                    request.COOKIES['auth_tkt'], _get_host_ip())
105        except BadTicket as ex:
106            raise DJMiddlewareException(ex)   
107    raise MissingCookieException(AUTHENTICATION_COOKIE_MISSING)
108
109def _get_hostname():
110    import socket
111    ret = 'localhost'
112    try:
113        hostname = socket.gethostname()
114        ret = socket.gethostbyname_ex(hostname)[0]
115    except Exception:
116        pass   
117    return ret
118   
119def _get_host_ip():
120    if getattr(settings, 'DJ_MIDDLEWARE_IP', None):
121        return settings.DJ_MIDDLEWARE_IP
122       
123    import urlparse
124    import socket
125    remote_urls = socket.getaddrinfo(socket.gethostname(), None)
126    for remote_url in remote_urls:
127        ret = remote_url[4][0]
128        if not ret.startswith('127'):
129            logger.debug("remote_url: %s" % (ret))
130            return ret
Note: See TracBrowser for help on using the repository browser.