source: TI12-security/trunk/python/Tests/xDomainCredsTransfer.py @ 986

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/xDomainCredsTransfer.py@986
Revision 986, 10.0 KB checked in by pjkersha, 13 years ago (diff)

Tests/xDomainCredsTransfer.py: test script to demonstrate passing of cookie credential info
between domains

NDG/SecurityCGI.py: above test script converted into a class (incomplete). This will form a
generic interface for required CGI functionality for sites deploying NDG security.

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3"""NDG Security CGI test program for passing cookie info between domains
4
5NERC Data Grid Project
6
7P J Kershaw 23/05/06
8
9Copyright (C) 2006 CCLRC & NERC
10
11This software may be distributed under the terms of the Q Public License,
12version 1.0 or later.
13"""
14
15from Cookie import SimpleCookie
16
17import sys
18import cgi
19import os
20import base64
21
22returnURI = 'https://glue.badc.rl.ac.uk/cgi-bin/xDomainCredsTransfer.py'
23__authorisationMethod = None
24
25def main(form=None):
26    if form is None:
27        form = cgi.FieldStorage()
28
29
30    if 'requestURI' in form:
31        # Request credentials from user's home site
32        requestCreds(form['requestURI'].value,
33                     returnURI,
34                     pageTitle='Going to user home site...',
35                     delayTime=3,
36                     redirectMsg=\
37        'Re-directing to home site to retrieve credentials...')
38
39    elif 'NDG-ID1' in form and 'NDG-ID2' in form:
40        # Receive credentials back from home site
41        receiveCredsResponse(form['NDG-ID1'].value, form['NDG-ID2'].value)
42
43    elif 'setCookie' in form and 'returnURI' in form:
44        # User has logged on at home site and a cookie is now to be set - next
45        # step is processCredsRequest() below
46        setCookie(returnURI=form['returnURI'].value)
47
48    elif 'returnURI' in form:
49        # Home site receives request from remote site for credentials and
50        # returns them
51        processCredsRequest(form['returnURI'].value,
52                            pageTitle='Home Site',
53                            delayTime=3,
54                            redirectMsg='Processing request from remote site...')
55    else:
56        showHomeSiteSelect()
57
58
59def requestCreds(requestURI,
60                 returnURI,
61                 pageTitle='',
62                 delayTime=0,
63                 redirectMsg=''):
64    """Request credentials from user's home site"""
65    output = """Content-type: text/html
66
67<html>
68<head>
69<title>%s</title>
70<meta http-equiv="REFRESH" content="%d; url=%s?returnURI=%s">
71</head>
72<body>
73%s
74</body>
75</html>""" % (pageTitle, delayTime, requestURI, returnURI, redirectMsg)
76    #sys.stderr.write(output)
77    print output
78
79
80def receiveCredsResponse(sessID, sessMgrURI):
81    """Remote site receives returned credentials and creates a new cookie for
82    its domain"""
83    setCookie(sessID, sessMgrURI)
84
85
86def processCredsRequest(returnURI, **returnCredsKwArgs):
87    """Receive request from remote site for credentials.  Process and return via
88    a redirect"""
89   
90    # Check for cookie in environment
91    if 'HTTP_COOKIE' in os.environ:
92        # Cookie is set - check for NDG cookie
93
94        # Get session ID from existing cookie
95        cookie = SimpleCookie(os.environ['HTTP_COOKIE'])
96        if "NDG-ID1" not in cookie:
97            raise Exception, 'Expecting "NDG-ID1" ID for session cookie'
98
99        if "NDG-ID2" not in cookie:
100            raise Exception, 'Expecting "NDG-ID2" ID for session cookie'
101
102        returnCreds(returnURI,
103                    cookie["NDG-ID1"].value,
104                    cookie["NDG-ID2"].value,
105                    **returnCredsKwArgs)
106    else:
107        # No cookie present - display login.  Submit must redirect back to
108        # sender
109        print """Content-type: text/html
110
111"""
112        showLogin(returnURI,
113                  setCookie=True,
114                  heading="Login",
115                  htmlTag=True,
116                  bodyTag=True)
117
118def returnCreds(returnURI,
119                sessID,
120                sessMgrURI,
121                pageTitle='',
122                delayTime=0,
123                redirectMsg=''):
124    """User's home site returns credentials to requestor"""
125
126    print """Content-type: text/html
127
128<html>
129<head>
130<title>%s</title>
131<meta http-equiv="REFRESH" content="%d; url=%s?NDG-ID1=%s&NDG-ID2=%s">
132</head>
133<body>
134%s
135</body>
136</html>""" % (pageTitle, delayTime, returnURI, sessID, sessMgrURI, redirectMsg)
137
138
139def setCookie(sessID=None, sessMgrURI=None, returnURI=None):
140    """Make NDG cookie"""
141
142    cookie = SimpleCookie()
143    if not sessID: sessID = base64.b64encode(os.urandom(128))
144    if not sessMgrURI: sessMgrURI = base64.b64encode(os.urandom(32))
145
146    cookie['NDG-ID1'] = sessID
147    cookie['NDG-ID1']['expires'] = "Tue, 13-12-2006 12:00:00 GMT"
148    cookie['NDG-ID2'] = sessMgrURI
149    cookie['NDG-ID2']['expires'] = "Tue, 13-12-2006 12:00:00 GMT"
150
151    if returnURI:
152        returnURIfield = """<meta http-equiv=\"REFRESH\"
153        content=\"0;url=./xDomainCredsTransfer.py?returnURI=%s\">""" % returnURI
154    else:
155        returnURIfield = ''
156
157    print "Content-type: text/html"
158    print cookie.output() + os.linesep + os.linesep
159    print """<html>
160<head>
161<title>Set Cookie</title>
162%s
163</head>
164
165<body>
166    <h1>Cookie set!</h1>
167</body>
168</html>""" % returnURIfield
169
170
171def showLogin(returnURI=None,
172              setCookie=False,
173              htmlTag=False,
174              heading=None,
175              bodyTag=False):
176    """Display initial NDG login form"""
177
178    if htmlTag: print "<html>"
179
180    if isinstance(heading, basestring):
181        print """<head>
182    <title>%s</title>
183    <style type=\"text/css\">
184    <!--
185    .al {
186    text-align: justify
187    }
188    a{
189    text-decoration:none;
190    }
191    a:hover{
192    color:#0000FF;
193    }
194        body { font-family: Verdana, sans-serif; font-size: 11}
195        table { font-family: Verdana, sans-serif; font-size: 11}
196    -->
197    </style>
198</head>""" % heading
199
200
201    if bodyTag: print "<body>"
202
203    if returnURI:
204        returnURIfield = "<input type=hidden name=returnURI value=\"%s\">" % \
205                                                                    returnURI
206    else:
207        returnURIfield = ''
208
209
210    if setCookie:
211        setCookieField = "<input type=hidden name=setCookie value=\"1\">"
212    else:
213        setCookieField = ''
214
215
216    bAuthorise=False
217    if bAuthorise:
218        authoriseArg = "<input type=hidden name=authorise value=\"1\">"
219    else:
220        authoriseArg = ""
221
222
223    # Set authorisation method default
224    authorisationMethodChk = { "allowMapping":              '',
225                            "allowMappingWithPrompt" :   '',
226                            "noMapping":                 ''}
227
228    if __authorisationMethod is None:
229        # Default to safest option for user
230        authorisationMethodChk["allowMappingWithPrompt"] = ' checked'
231    else:
232        authorisationMethodChk[__authorisationMethod] = ' checked'
233
234    print \
235"""<script language="javascript">
236<!--
237    function toggleLayer(layerId)
238    {
239        if (document.getElementById)
240        {
241            // Standard
242            var style = document.getElementById(layerId).style;
243        }
244        else if (document.all)
245        {
246            // Old msie versions
247            var style = document.all[whichLayer].style;
248        }
249        else if (document.layers)
250        {
251            // nn4
252            var style = document.layers[whichLayer].style;
253        }
254        style.visibility = style.visibility == "visible" ? "hidden":"visible";
255    }
256//-->
257</script>
258<h3>NERC Data Grid Site Login (Test)<BR clear=all></h3>
259<hr>
260
261<form action="./xDomainCredsTransfer.py" method="POST">
262
263<table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
264<tbody>
265<tr><td>User Name:</td> <td><input type=text name=userName value="">
266</td></tr>
267<tr>
268    <td>Password:</td>
269    <td><input type=password name=passPhrase></td>
270</tr>
271<tr>
272    <td colspan="2" align="right">
273        <a href="javascript:toggleLayer('advSettings');">Advanced Settings</a>
274        <input type=submit value="Login">
275    </td>
276</tr>
277%s
278%s"""  % (returnURIfield, setCookieField)
279
280    print \
281"""</tbody></table>
282<br>
283<div id="advSettings" style="position: relative; visibility: hidden;">
284    <h4>Role Mapping for access to other trusted sites</h4>
285    <p>Your account has roles or <i>privileges</i> which determine what data you have access to.  If you access data at another NDG trusted site, these roles can be mapped to local roles at that site to help you gain access:
286    </p>
287    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
288    <tbody>
289    <tr>
290    <td>
291        <input type="radio" name="authorisationMethod" value="allowMapping"%s>
292    </td>
293        <td>
294            Allow my roles to be mapped to local roles at other NDG trusted sites.
295        </td>
296    </tr>
297    <tr>
298        <td>
299            <input type="radio" name="authorisationMethod" value="allowMappingWithPrompt"%s>
300        </td>
301    <td>
302        Allow my roles to be mapped, but prompt me so that I may choose which roles to map before gaining access.
303    </td>
304    <tr>
305    <td>
306        <input type="radio" name="authorisationMethod" value="noMapping"%s>
307    </td>
308    <td>
309        Don't allow mapping of my roles.
310    </td>
311    </tr>
312    </tbody>
313    </table>
314</div>
315</form>
316""" % (authorisationMethodChk['allowMapping'], \
317       authorisationMethodChk['allowMappingWithPrompt'], \
318       authorisationMethodChk['noMapping'])
319
320    if bodyTag: print "</body>"
321    if htmlTag: print "</html>"
322
323    # end of showLogin()
324
325
326def showHomeSiteSelect(heading="NDG Home Site Select..."):
327
328    print """Content-type: text/html
329
330<html>
331<head>
332    <title>%s</title>
333    <style type=\"text/css\">
334    <!--
335    .al {
336    text-align: justify
337    }
338    a{
339    text-decoration:none;
340    }
341    a:hover{
342    color:#0000FF;
343    }
344        body { font-family: Verdana, sans-serif; font-size: 11}
345        table { font-family: Verdana, sans-serif; font-size: 11}
346    -->
347    </style>
348</head>""" % heading
349
350
351    print "<body>"
352    print \
353"""<h3>NERC Data Grid Home Site Select (Test)<BR clear=all></h3>
354<hr>
355
356<form action="./xDomainCredsTransfer.py" method="POST">
357<table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5>
358<tbody>
359<tr>
360  <td>
361    <select name="requestURI">
362      <option value="">Select your home site...
363      <option value="https://glue.badc.rl.ac.uk/cgi-bin/xDomainCredsTransfer.py">BADC
364      <option value="https://gabriel.bnsc.rl.ac.uk/cgi-bin/xDomainCredsTransfer.py">Gabriel
365    </select>
366  </td>
367  <td align="right">
368    <input type=submit value="Go">
369  </td>
370</tr>
371</tbody>
372</table>
373</form>
374</body>
375</html>"""
376
377    # end of showHomeSiteSelect()
378
379if __name__ == "__main__":
380    main()
Note: See TracBrowser for help on using the repository browser.