source: TI12-security/trunk/MyProxyWebService/myproxy/server/test/test_myproxywsgi.py @ 6943

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/MyProxyWebService/myproxy/server/test/test_myproxywsgi.py@6943
Revision 6943, 6.5 KB checked in by pjkersha, 9 years ago (diff)

Incomplete - task 5: MyProxy? Logon HTTPS Interface

  • Working myproxy-ws-get-trustroots.sh http client shell script.
Line 
1#!/usr/bin/env python
2"""Unit tests for MyProxy WSGI Middleware classes and Application.  These are
3run using paste.fixture i.e. tests stubs to a web application server
4"""
5__author__ = "P J Kershaw"
6__date__ = "21/05/10"
7__copyright__ = "(C) 2010 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11import logging
12logging.basicConfig(level=logging.DEBUG)
13
14import unittest
15import os
16import base64
17from getpass import getpass
18from ConfigParser import SafeConfigParser, NoOptionError
19
20from OpenSSL import crypto
21import paste.fixture
22from paste.deploy import loadapp
23
24from myproxy.server.wsgi.middleware import MyProxyClientMiddleware
25
26
27class TestMyProxyClientMiddlewareApp(object):
28    '''Test Application for MyClientProxyMiddleware'''
29    RESPONSE = "Test MyProxyClientMiddleware"
30   
31    def __call__(self, environ, start_response):
32       
33        assert(environ[MyProxyClientMiddleware.DEFAULT_CLIENT_ENV_KEYNAME])
34        assert(environ[MyProxyClientMiddleware.DEFAULT_LOGON_FUNC_ENV_KEYNAME])
35        status = "200 OK"
36               
37        start_response(status,
38                       [('Content-length', 
39                         str(len(self.__class__.RESPONSE))),
40                        ('Content-type', 'text/plain')])
41        return [self.__class__.RESPONSE]
42
43
44class MyProxyClientMiddlewareTestCase(unittest.TestCase):
45    def __init__(self, *args, **kwargs):
46        app = TestMyProxyClientMiddlewareApp()
47        app = MyProxyClientMiddleware.filter_app_factory(app, {}, prefix='')
48        self.app = paste.fixture.TestApp(app)
49         
50        unittest.TestCase.__init__(self, *args, **kwargs)
51
52    def test01AssertMyProxyClientInEnviron(self):
53        # Check the middleware has set the MyProxy client object in environ
54        response = self.app.get('/', status=200)
55        self.assert_(response)
56       
57
58class MyProxyPasteDeployTestCaseBase(unittest.TestCase): 
59    """Base class for common Paste Deploy related set-up"""
60    INI_FILENAME = 'myproxywsgi.ini'
61    THIS_DIR = os.path.dirname(__file__)
62    CONFIG_FILENAME = 'test_myproxywsgi.cfg'
63    CONFIG_FILEPATH = os.path.join(THIS_DIR, CONFIG_FILENAME)
64   
65    def __init__(self, *args, **kwargs):
66        here_dir = os.path.dirname(os.path.abspath(__file__))
67        wsgiapp = loadapp('config:' + self.__class__.INI_FILENAME, 
68                          relative_to=here_dir)
69        self.app = paste.fixture.TestApp(wsgiapp)
70       
71        self.cfg = SafeConfigParser({'here': self.__class__.THIS_DIR})
72        self.cfg.optionxform = str
73        self.cfg.read(self.__class__.CONFIG_FILEPATH)
74       
75        unittest.TestCase.__init__(self, *args, **kwargs) 
76               
77               
78class MyProxyLogonAppTestCase(MyProxyPasteDeployTestCaseBase):
79    """Test HTTP MyProxy logon interface"""
80       
81    def _createRequestCreds(self):
82        keyPair = crypto.PKey()
83        keyPair.generate_key(crypto.TYPE_RSA, 1024)
84       
85        certReq = crypto.X509Req()
86       
87        # Create public key object
88        certReq.set_pubkey(keyPair)
89       
90        # Add the public key to the request
91        certReq.sign(keyPair, "md5")
92       
93        pemCertReq = crypto.dump_certificate_request(crypto.FILETYPE_PEM, 
94                                                     certReq)
95        return keyPair, pemCertReq
96       
97    def test01Logon(self):
98        # Test successful logon
99        username = self.cfg.get('MyProxyLogonAppTestCase.test01Logon', 
100                                'username')
101        try: 
102            password = self.cfg.get('MyProxyLogonAppTestCase.test01Logon', 
103                                    'password')
104        except NoOptionError:
105            password = getpass('MyProxyLogonAppTestCase.test01Logon password: ')
106           
107        base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
108        authHeader =  "Basic %s" % base64String
109        headers = {'Authorization': authHeader}
110       
111        # Create key pair and certificate request
112        keyPair, certReq = self._createRequestCreds()
113       
114        postData = {
115            MyProxyClientMiddleware.CERT_REQ_POST_PARAM_KEYNAME: certReq
116        }
117        response = self.app.post('/logon', postData, headers=headers, 
118                                 status=200)
119        print response
120        self.assert_(response)
121       
122    def test02NoAuthorisationHeaderSet(self):   
123        # Test failure with omission of HTTP Basic Auth header - a 401 result is
124        # expected.
125             
126        # Create key pair and certificate request
127        keyPair, certReq = self._createRequestCreds()
128        response = self.app.post('/logon', certReq, status=401)
129        print response
130        self.assert_(response) 
131       
132    def test03NoCertificateRequestSent(self):
133        # Test with missing certificate request
134       
135        # Username and password don't matter - exception is raised in server
136        # middleware prior to authentication
137        username = ''
138        password = ''
139                   
140        base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
141        authHeader =  "Basic %s" % base64String
142        headers = {'Authorization': authHeader}
143       
144        # Bad POST'ed content
145        response = self.app.post('/logon', 'x', headers=headers, status=400)
146        print response
147        self.assert_(response)
148       
149    def test04GET(self):
150        # Test HTTP GET request - should be rejected - POST is expected
151       
152        # Username and password don't matter - exception is raised in server
153        # middleware prior to authentication
154        username = ''
155        password = ''
156        base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
157        authHeader =  "Basic %s" % base64String
158        headers = {'Authorization': authHeader}
159       
160        response = self.app.get('/logon', headers=headers, status=405)
161        print response
162        self.assert_(response)               
163
164
165class MyProxyGetTrustRootsMiddlewareTestCase(MyProxyPasteDeployTestCaseBase):
166    """Test HTTP MyProxy get trust roots interface"""
167   
168    def test01(self):
169        response = self.app.get('/get-trustroots', status=200)
170        self.assert_(response)         
171        print response
172       
173        # Test deserialisation
174        for line in response.body.split('\n'):
175            fieldName, val = line.split('=', 1)
176            print("%s: %s\n" % (fieldName, base64.b64decode(val)))
177
178if __name__ == "__main__":
179    unittest.main()       
Note: See TracBrowser for help on using the repository browser.