1
2 """Unit tests for MyProxy WSGI Middleware classes and Application
3 """
4 __author__ = "P J Kershaw"
5 __date__ = "21/05/10"
6 __copyright__ = "(C) 2010 Science and Technology Facilities Council"
7 __license__ = "BSD - see LICENSE file in top-level directory"
8 __contact__ = "Philip.Kershaw@stfc.ac.uk"
9 __revision__ = '$Id: $'
10 import unittest
11 import os
12 import base64
13
14 import paste.fixture
15 from paste.deploy import loadapp
16
17 from myproxy.ws.server.wsgi.httpbasicauth import (HttpBasicAuthMiddleware,
18 HttpBasicAuthResponseException)
19
20
22 """Test WSGI Application for use with the unit tests for the HTTP Basic
23 Auth middleware developed for the myproxy.server.app.MyProxyApp application
24 """
25 - def __init__(self, global_conf, **app_conf):
26 """Follow standard Paste Deploy app factory function signature"""
27
28 - def __call__(self, environ, start_response):
29 """Make a simple response for unit test code to trap and validate
30 against. If this method is executed then the HTTP Basic Auth step in
31 the upstream middleware has succeeded.
32 """
33 contentType = 'text/plain'
34 response = 'Authenticated!'
35 status = 200
36 start_response(status,
37 [('Content-type', contentType),
38 ('Content-Length', str(len(response)))])
39 return [response]
40
41
43 """Add an authentication function to the environ for HttpBasicAuthMiddleware
44 to pick up and use. It behaves as an application returning a response
45 """
46 USERNAME = 'myusername'
47 PASSWORD = 'mypassword'
48 SUCCESS_RESPONSE = 'AUTHENTICATED'
49 FAILURE_RESPONSE = 'FAILED'
50
51 - def __init__(self, app, global_conf, **app_conf):
52 """Follow standard Paste Deploy app factory function signature"""
53 self.app = app
54
55 - def __call__(self, environ, start_response):
56 def authenticationApp(environ, start_response, username, password):
57 """Authentication callback application - its responsible for the
58 response message and response code
59 """
60 if (username == self.__class__.USERNAME and
61 password == self.__class__.PASSWORD):
62 response = self.__class__.SUCCESS_RESPONSE
63 status = '200 OK'
64 else:
65 response = self.__class__.FAILURE_RESPONSE
66 status = '401 Unauthorized'
67
68 start_response(status,
69 [('Content-type', 'text/plain'),
70 ('Content-Length', str(len(response)))])
71 return [response]
72
73 environ['HTTPBASICAUTH_FUNC'] = authenticationApp
74
75 return self.app(environ, start_response)
76
77
79 """Add an authentication function to the environ for HttpBasicAuthMiddleware
80 to pick up and use. The callback does not return a response leaving control
81 with the HttpBasicAuthMiddleware
82 """
83 USERNAME = 'myusername'
84 PASSWORD = 'mypassword'
85
86 - def __init__(self, app, global_conf, **app_conf):
87 """Follow standard Paste Deploy app factory function signature"""
88 self.app = app
89
90 - def __call__(self, environ, start_response):
91 """Create HTTP Basic Auth callback"""
92 def authenticate(environ, start_response, username, password):
93 """HTTP Basic Auth callback function"""
94 if (username != self.__class__.USERNAME or
95 password != self.__class__.PASSWORD):
96 raise HttpBasicAuthResponseException("Invalid credentials")
97
98 environ['HTTPBASICAUTH_FUNC'] = authenticate
99
100 return self.app(environ, start_response)
101
102
104 """Unit tests for HTTP Basic Auth middleware used with the MyProxyWebService
105 package
106 """
107 CONFIG_FILE = 'httpbasicauth.ini'
108
118
120
121 response = self.app.get('/auth', status=401)
122
135
137
138 username = 'x'
139 password = 'y'
140
141 base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
142 authHeader = "Basic %s" % base64String
143 headers = {'Authorization': authHeader}
144
145 response = self.app.get('/auth', headers=headers, status=401)
146 self.assert_((TestHttpBasicAuthCallBackAppMiddleware.FAILURE_RESPONSE in
147 response))
148
160
171
173 self._createCallbackMiddleware()
174 username = 'a'
175 password = 'b'
176
177 base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
178 authHeader = "Basic %s" % base64String
179 headers = {'Authorization': authHeader}
180
181 response = self.app.get('/auth', headers=headers, status=401)
182