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

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

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

  • fixed yadis template syntax
  • updating securedapp template.
  • Property svn:keywords set to Id
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$"
13
14   
15def app_factory(globalConfig, **localConfig):
16    '''AuthZTestMiddleware factory for Paste app pattern'''
17    return AuthZTestMiddleware(None, globalConfig, **localConfig)
18
19def filter_app_factory(app, globalConfig, **localConfig):
20    '''AuthZTestMiddleware factory for Paste filter app pattern'''
21    return AuthZTestMiddleware(app, globalConfig, **localConfig)
22
23class AuthZTestMiddleware(object):
24    """This class simulates the application to be secured by the NDG Security
25    authorization middleware
26    """
27    method = {
28"/": 'default',
29"/test_401": "test_401",
30"/test_403": "test_403",
31"/test_securedURI": "test_securedURI",
32"/test_accessDeniedToSecuredURI": "test_accessDeniedToSecuredURI"
33    }
34    header = """        <h1>Authorisation Integration Tests:</h1>
35        <p>Test Authorisation middleware with no Session Manager running.
36        See the authz/ integration test directory for a configuration including
37        a Session Manager</p>
38        <p>These tests use require the security services application to be
39        running.  See securityserviceapp.py and securityservices.ini in the
40        authz_lite/ integration test directory.</p>
41        <h2>To Run:</h2>
42        <p>Try any of the links below.  When prompt for username and password,
43        enter one of the sets of credentials from securityservices.ini
44        openid.provider.authN.userCreds section.  The defaults are:
45        </p>
46        <p>pjk/testpassword</p>
47        <p>another/testpassword</p>
48        <p>The attributeinterface.py AttributeAuthority plugin is configured to
49        grant access to 'pjk' for all URLs below apart from
50        'test_accessDeniedToSecuredURI'.  The 'another' account will be denied
51        access from all URLs apart from 'test_401'</p>
52"""
53
54    def __init__(self, app, globalConfig, **localConfig):
55        self.app = app
56           
57    def __call__(self, environ, start_response):
58       
59        methodName = self.method.get(environ['PATH_INFO'], '').rstrip()
60        if methodName:
61            action = getattr(self, methodName)
62            return action(environ, start_response)
63        elif environ['PATH_INFO'] == '/logout':
64            return self.default(environ, start_response)
65       
66        elif self.app is not None:
67            return self.app(environ, start_response)
68        else:
69            start_response('404 Not Found', [('Content-type', 'text/plain')])
70            return "Authorisation integration tests: invalid URI"
71           
72    def default(self, environ, start_response):
73        if 'REMOTE_USER' in environ:
74            response = """<html>
75    <head/>
76    <body>
77        %s
78        <ul>%s</ul>
79        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
80    </body>
81</html>
82""" % (AuthZTestMiddleware.header,
83       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
84                 for link,name in self.method.items() if name != 'default']),
85       environ['REMOTE_USER'])
86       
87            start_response('200 OK', 
88                           [('Content-type', 'text/html'),
89                            ('Content-length', str(len(response)))])
90        else:
91            response = """<html>
92    <head/>
93    <body>
94        %s
95        <ul>%s</ul>
96    </body>
97</html>
98""" % (AuthZTestMiddleware.header,
99       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
100                 for link,name in self.method.items() if name != 'default'])
101       )
102
103            start_response('200 OK', 
104                           [('Content-type', 'text/html'),
105                            ('Content-length', str(len(response)))])
106        return response
107
108    def test_401(self, environ, start_response):
109        if 'REMOTE_USER' in environ:
110            response = """<html>
111    <head/>
112    <body>
113        <h1>Authenticated!</h1>
114        <ul>%s</ul>
115        <p>You are logged in.  <a href="/logout">Logout</a></p>
116    </body>
117</html>
118""" % '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
119                 for link,name in self.method.items() if name != 'default'])
120
121            start_response('200 OK', 
122                           [('Content-type', 'text/html'),
123                            ('Content-length', str(len(response)))])
124        else:
125            response = "Trigger OpenID Relying Party..."
126            start_response('401 Unauthorized', 
127                           [('Content-type', 'text/plain'),
128                            ('Content-length', str(len(response)))])
129        return response
130
131    def test_403(self, environ, start_response):
132        """Trigger the Authorization middleware by returning a 403 Forbidden
133        HTTP status code from this URI"""
134       
135        if 'REMOTE_USER' in environ:
136            response = """<html>
137    <head/>
138    <body>
139        <h1>Authorised!</h1>
140        <ul>%s</ul>
141        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
142    </body>
143</html>
144""" % ('\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
145                 for link,name in self.method.items() if name != 'default']),
146       environ['REMOTE_USER'])
147
148            start_response('200 OK', 
149                           [('Content-type', 'text/html'),
150                            ('Content-length', str(len(response)))])
151        else:
152            response = ("Authorization middleware is triggered becuase this "
153                        "page returns a 403 Forbidden status.")
154            start_response('403 Forbidden', 
155                           [('Content-type', 'text/plain'),
156                            ('Content-length', str(len(response)))])
157        return response
158
159    def test_securedURI(self, environ, start_response):
160        """To be secured, the Authorization middleware must have this URI in
161        its policy"""
162        if 'REMOTE_USER' in environ:
163            response = """<html>
164    <head/>
165    <body>
166        <h1>Authorised for path [%s]!</h1>
167        <ul>%s</ul>
168        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
169    </body>
170</html>
171""" % (environ['PATH_INFO'],
172       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
173                 for link,name in self.method.items() if name != 'default']),
174       environ['REMOTE_USER'])
175
176
177            start_response('200 OK', 
178                           [('Content-type', 'text/html'),
179                            ('Content-length', str(len(response)))])
180        else:
181            response = ("Authorization middleware must have this URI in its "
182                        "policy in order to secure it!")
183            start_response('200 OK', 
184                           [('Content-type', 'text/plain'),
185                            ('Content-length', str(len(response)))])
186        return response
187
188
189    def test_accessDeniedToSecuredURI(self, environ, start_response):
190        """To be secured, the Authorization middleware must have this URI in
191        its policy and the user must not have the required role as specified
192        in the policy.  See ndg.security.test.config.attributeauthority.sitea
193        for user role settings retrieved from the attribute authority"""
194        if 'REMOTE_USER' in environ:
195            response = """<html>
196    <head/>
197    <body>
198        <h1>Authorised for path [%s]!</h1>
199        <ul>%s</ul>
200        <p>You are logged in with OpenID [%s].  <a href="/logout">Logout</a></p>
201    </body>
202</html>
203""" % (environ['PATH_INFO'],
204       '\n'.join(['<li><a href="%s">%s</a></li>' % (link, name) 
205                 for link,name in self.method.items() if name != 'default']),
206       environ['REMOTE_USER'])
207
208
209            start_response('200 OK', 
210                           [('Content-type', 'text/html'),
211                            ('Content-length', str(len(response)))])
212        else:
213            response = ("Authorization middleware must have this URI in its "
214                        "policy in order to secure it!")
215            start_response('200 OK', 
216                           [('Content-type', 'text/plain'),
217                            ('Content-length', str(len(response)))])
218        return response
219   
220    @classmethod
221    def app_factory(cls, globalConfig, **localConfig):
222        return cls(None, globalConfig, **localConfig)
223   
224    @classmethod
225    def filter_app_factory(cls, app, globalConfig, **localConfig):
226        return cls(app, globalConfig, **localConfig)
227
228
229INI_FILENAME = 'securedapp.ini'
230   
231# To start run
232# $ paster serve services.ini or run this file as a script
233# $ ./securedapp.py [port #]
234if __name__ == '__main__': 
235    import optparse   
236    from os import path
237    from ndg.security.server.utils.paste_utils import PasteDeployAppServer
238   
239    cfgFilePath = path.join(path.dirname(path.abspath(__file__)), INI_FILENAME)
240       
241    parser = optparse.OptionParser()
242    parser.add_option("-p",
243                      "--port",
244                      dest="port",
245                      default=7080,
246                      type='int',
247                      help="port number to run under")
248
249    parser.add_option("-c",
250                      "--conf",
251                      dest="configFilePath",
252                      default=cfgFilePath,
253                      help="Configuration file path")
254   
255    opt = parser.parse_args()[0]
256
257    server = PasteDeployAppServer(cfgFilePath=opt.configFilePath, 
258                                  port=opt.port) 
259    server.start()
Note: See TracBrowser for help on using the repository browser.