source: TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/openidprovider/securedapp.py @ 7756

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/ndg_security_test/ndg/security/test/integration/openidprovider/securedapp.py@7756
Revision 7756, 6.4 KB checked in by pjkersha, 10 years ago (diff)

Incomplete - task 16: NDG Security 2.x.x - incl. updated Paster templates

Line 
1#!/usr/bin/env python
2"""NDG Security test harness for authorisation middleware used to secure an
3application
4
5NERC DataGrid Project
6"""
7__author__ = "P J Kershaw"
8__date__ = "20/11/08"
9__copyright__ = "(C) 2009 Science and Technology Facilities Council"
10__license__ = "BSD - See top-level directory for LICENSE file"
11__contact__ = "Philip.Kershaw@stfc.ac.uk"
12__revision__ = "$Id: securedapp.py 7077 2010-06-24 15:38:19Z pjkersha $"
13
14   
15def app_factory(globalConfig, **localConfig):
16    '''OpenIdTestHarnessApp factory for Paste app pattern'''
17    return OpenIdTestHarnessApp(None, globalConfig, **localConfig)
18
19def filter_app_factory(app, globalConfig, **localConfig):
20    '''OpenIdTestHarnessApp factory for Paste filter app pattern'''
21    return OpenIdTestHarnessApp(app, globalConfig, **localConfig)
22
23class OpenIdTestHarnessApp(object):
24    """This class simulates the application to be secured by the NDG Security
25    authorization middleware
26    """
27    method = {
28"/": 'default',
29"/test_securedURI": "test_securedURI",
30"/test_publicURI": "test_publicURI"
31    }
32    header = """        <h1>OpenID Provider Integration Tests:</h1>
33        <p>These tests require the OpenID Provider application to be
34        running.  See securityserviceapp.py and securityservices.ini in the
35        ndg/security/test/integration/openidprovider/ integration test
36        directory.</p>
37        <h2>To Run:</h2>
38        <p>Try any of the links below.  When prompt for username and password,
39        enter one of the sets of credentials from securityservices.ini
40        openid.provider.authN.userCreds section.  The defaults are:
41        </p>
42        <p>pjk/testpassword</p>
43        <p>another/testpassword</p>
44"""
45
46    def __init__(self, app, globalConfig, **localConfig):
47        self.app = app
48           
49    def __call__(self, environ, start_response):
50       
51        methodName = self.method.get(environ['PATH_INFO'], '').rstrip()
52        if methodName:
53            action = getattr(self, methodName)
54            return action(environ, start_response)
55        elif environ['PATH_INFO'] == '/logout':
56            return self.default(environ, start_response)
57       
58        elif self.app is not None:
59            return self.app(environ, start_response)
60        else:
61            start_response('404 Not Found', [('Content-type', 'text/plain')])
62            return "Authorisation integration tests: invalid URI"
63           
64    def default(self, environ, start_response):
65        if 'REMOTE_USER' in environ:
66            response = """<html>
67    <head/>
68    <body>
69        %s
70        <ul>%s</ul>
71        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
72    </body>
73</html>
74""" % (OpenIdTestHarnessApp.header,
75       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
76                 for link,name in self.method.items() if name != 'default']),
77       environ['REMOTE_USER'])
78       
79            start_response('200 OK', 
80                           [('Content-type', 'text/html'),
81                            ('Content-length', str(len(response)))])
82        else:
83            response = """<html>
84    <head/>
85    <body>
86        %s
87        <ul>%s</ul>
88    </body>
89</html>
90""" % (OpenIdTestHarnessApp.header,
91       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
92                 for link,name in self.method.items() if name != 'default'])
93       )
94
95            start_response('200 OK', 
96                           [('Content-type', 'text/html'),
97                            ('Content-length', str(len(response)))])
98        return response
99
100    def test_securedURI(self, environ, start_response):
101        if 'REMOTE_USER' in environ:
102            response = """<html>
103    <head/>
104    <body>
105        <h1>Authenticated!</h1>
106        <ul>%s</ul>
107        <p>You are logged in.  <a href="/logout">Logout</a></p>
108    </body>
109</html>
110""" % '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
111                 for link,name in self.method.items() if name != 'default'])
112
113            start_response('200 OK', 
114                           [('Content-type', 'text/html'),
115                            ('Content-length', str(len(response)))])
116        else:
117            response = "Trigger OpenID Relying Party..."
118            start_response('401 Unauthorized', 
119                           [('Content-type', 'text/plain'),
120                            ('Content-length', str(len(response)))])
121        return response
122
123    def test_publicURI(self, environ, start_response):
124        """This URI is expected NOT to match the interceptUriPat attribute
125        setting of AuthenticationEnforcementFilter
126        """
127        if 'REMOTE_USER' in environ:
128            response = """<html>
129    <head/>
130    <body>
131        <h1>Public path [%s], no authentication required</h1>
132        <ul>%s</ul>
133        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
134    </body>
135</html>
136""" % (environ['PATH_INFO'],
137       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
138                 for link,name in self.method.items() if name != 'default']),
139       environ['REMOTE_USER'])
140
141
142            start_response('200 OK', 
143                           [('Content-type', 'text/html'),
144                            ('Content-length', str(len(response)))])
145        else:
146            response = ("Public URI no authentication required to access it")
147            start_response('200 OK', 
148                           [('Content-type', 'text/plain'),
149                            ('Content-length', str(len(response)))])
150        return response
151   
152    @classmethod
153    def app_factory(cls, globalConfig, **localConfig):
154        return cls(None, globalConfig, **localConfig)
155   
156    @classmethod
157    def filter_app_factory(cls, app, globalConfig, **localConfig):
158        return cls(app, globalConfig, **localConfig)
159   
160# To start run
161# $ paster serve services.ini or run this file as a script
162# $ ./securedapp.py [port #]
163if __name__ == '__main__':
164    import sys
165    import os
166    from os.path import dirname, abspath
167    import logging
168    logging.basicConfig(level=logging.DEBUG)
169
170    if len(sys.argv) > 1:
171        port = int(sys.argv[1])
172    else:
173        port = 7080
174       
175    cfgFilePath = os.path.join(dirname(abspath(__file__)), 'securedapp.ini')
176       
177    from paste.httpserver import serve
178    from paste.deploy import loadapp
179    from paste.script.util.logging_config import fileConfig
180   
181    fileConfig(cfgFilePath)
182    app = loadapp('config:%s' % cfgFilePath)
183    serve(app, host='0.0.0.0', port=port)
Note: See TracBrowser for help on using the repository browser.