1 | ''' |
---|
2 | BSD Licence |
---|
3 | Copyright (c) 2012, Science & Technology Facilities Council (STFC) |
---|
4 | All rights reserved. |
---|
5 | |
---|
6 | Redistribution and use in source and binary forms, with or without modification, |
---|
7 | are 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 | |
---|
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
---|
20 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
---|
21 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
---|
22 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
---|
23 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
---|
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
---|
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
28 | |
---|
29 | Created on 2 Nov 2012 |
---|
30 | |
---|
31 | @author: mnagni |
---|
32 | ''' |
---|
33 | from paste.auth.auth_tkt import AuthTicket |
---|
34 | from django.conf import settings |
---|
35 | import socket |
---|
36 | import urlparse |
---|
37 | |
---|
38 | import logging |
---|
39 | |
---|
40 | # Get an instance of a logger |
---|
41 | LOGGER = logging.getLogger(__name__) |
---|
42 | |
---|
43 | class DJ_Security_Middleware(object): |
---|
44 | """ |
---|
45 | Validates if the actual user is authenticated agains a |
---|
46 | given authentication service. |
---|
47 | Actually the middleware intercepts all the requests submitted |
---|
48 | to the underlying Django application and verifies if the presence |
---|
49 | or not of a valid paste cookie in the request. |
---|
50 | """ |
---|
51 | def process_response(self, request, response): |
---|
52 | # 'auth_user' is set by the dj_security_login |
---|
53 | # module after a succesfull authentication |
---|
54 | if not request.POST.get('username', None) \ |
---|
55 | or not getattr(request, 'auth_user', False): |
---|
56 | return response |
---|
57 | |
---|
58 | remote_ip = _calculate_remote_ip(request.GET.get('r')) |
---|
59 | LOGGER.debug("responding to remote_ip: %s" % (remote_ip)) |
---|
60 | username = request.POST.get('username') |
---|
61 | token = AuthTicket( |
---|
62 | getattr(settings, 'SHARED_SECRET', 'sharedsecret'), |
---|
63 | username, |
---|
64 | remote_ip, |
---|
65 | user_data = getattr(request, 'auth_user', '')) |
---|
66 | LOGGER.debug("Created authTicket for %s from %s" % (username, remote_ip)) |
---|
67 | response.set_cookie('auth_tkt', |
---|
68 | token.cookie_value(), |
---|
69 | domain = getattr(settings, 'COOKIE_DOMAIN', None)) |
---|
70 | LOGGER.debug("Set authTicket in response for %s from %s" % (username, remote_ip)) |
---|
71 | return response |
---|
72 | |
---|
73 | def _calculate_remote_ip(url_path): |
---|
74 | remote_url = urlparse.urlparse(url_path) |
---|
75 | LOGGER.debug("calculating remote_ip for %s" % (str(remote_url))) |
---|
76 | port = 80 |
---|
77 | host = remote_url.netloc |
---|
78 | if remote_url.netloc: |
---|
79 | if ':' in remote_url.netloc: |
---|
80 | host, port = remote_url.netloc.split(':') |
---|
81 | addrinfo = socket.getaddrinfo(host, int(port)) |
---|
82 | LOGGER.debug("%s has remote_ip %s" % (url_path, addrinfo[0][-1][0])) |
---|
83 | return addrinfo[0][-1][0] |
---|
84 | return None |
---|