source: TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/authn/test_httpbasicauth.py @ 5838

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg_security_test/ndg/security/test/unit/wsgi/authn/test_httpbasicauth.py@5838
Revision 5838, 5.5 KB checked in by pjkersha, 10 years ago (diff)

Unit tested HTTPBasicAuthMiddleware. This will be used together MyProxyClientMiddleware? to make a myproxy-logon web service interface.

Line 
1#!/usr/bin/env python
2"""Unit tests for WSGI HTTP Basic Auth handler
3
4NERC DataGrid Project
5"""
6__author__ = "P J Kershaw"
7__date__ = "13/10/09"
8__copyright__ = "(C) 2009 Science and Technology Facilities Council"
9__license__ = "BSD - see LICENSE file in top-level directory"
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = '$Id$'
12import logging
13logging.basicConfig(level=logging.DEBUG)
14
15import urllib2
16import base64
17import paste.fixture
18from ndg.security.test.unit import BaseTestCase
19from ndg.security.server.wsgi.authn import HTTPBasicAuthMiddleware, \
20    HTTPBasicAuthUnauthorized
21
22
23class TestAuthnApp(object):
24    '''Test Application for the Authentication handler to protect'''
25    response = "Test HTTP Basic Authentication application"
26   
27    loggedIn = lambda self, environ: 'username' in environ.get(
28                                                self.beakerSessionKeyName, {})
29   
30    def __init__(self, app_conf, **local_conf):
31        self.beakerSessionKeyName = app_conf.get('beakerSessionKeyName')
32       
33    def __call__(self, environ, start_response):
34       
35        if environ['PATH_INFO'] == '/test_401WithNotLoggedIn':
36            status = "401 Unauthorized"
37           
38        elif environ['PATH_INFO'] == '/test_401WithLoggedIn':
39            status = "401 Unauthorized"
40           
41        elif environ['PATH_INFO'] == '/test_200WithNotLoggedIn':
42            status = "200 OK"
43           
44        elif environ['PATH_INFO'] == '/test_200':
45            status = "200 OK"
46       
47        elif environ['PATH_INFO'] == '/test_sslClientAuthn':
48            if self.loggedIn(environ):
49                status = "200 OK"
50            else:
51                status = "401 Unauthorized"
52        else:
53            status = "404 Not found"
54               
55        start_response(status,
56                       [('Content-length', 
57                         str(len(TestAuthnApp.response))),
58                        ('Content-type', 'text/plain')])
59        return [TestAuthnApp.response]
60
61
62class HTTPBasicAuthPluginMiddleware(object):
63    USERNAME = 'testuser'
64    PASSWORD = 'password'
65   
66    def __init__(self, app):
67        self._app = app
68       
69    def __call__(self, environ, start_response):
70        def authenticate(environ, username, password):
71            if username == HTTPBasicAuthPluginMiddleware.USERNAME and \
72               password == HTTPBasicAuthPluginMiddleware.PASSWORD:
73                return
74            else:
75                raise HTTPBasicAuthUnauthorized("Invalid credentials")
76           
77        environ['authenticate'] = authenticate
78        return self._app(environ, start_response)
79   
80   
81class HTTPBasicAuthMiddlewareTestCase(BaseTestCase):
82    SERVICE_PORTNUM = 10443
83    WGET_CMD = 'wget'
84    WGET_USER_OPTNAME = '--http-user'
85    WGET_PASSWD_OPTNAME = '--http-password'
86    WGET_OUTPUT_OPTNAME = '--output-document'
87    WGET_STDOUT = '-'
88   
89    def __init__(self, *args, **kwargs):
90        app = TestAuthnApp({})
91        app = HTTPBasicAuthMiddleware(app, {}, prefix='',
92                                               authnFunc='authenticate')
93        self.wsgiapp = HTTPBasicAuthPluginMiddleware(app)
94       
95        self.app = paste.fixture.TestApp(self.wsgiapp)
96         
97        BaseTestCase.__init__(self, *args, **kwargs)
98
99    def test01PasteFixture(self):
100        username = HTTPBasicAuthPluginMiddleware.USERNAME
101        password = HTTPBasicAuthPluginMiddleware.PASSWORD
102       
103        base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
104        authHeader =  "Basic %s" % base64String
105        headers = {'Authorization': authHeader}
106
107        url = '/test_200'
108       
109        response = self.app.get(url, headers=headers, status=200)
110        print response
111       
112    def test02Urllib2Client(self):
113        # Thread separate Paster based service
114        self.addService(app=self.wsgiapp, 
115                        port=HTTPBasicAuthMiddlewareTestCase.SERVICE_PORTNUM)
116       
117        username = HTTPBasicAuthPluginMiddleware.USERNAME
118        password = HTTPBasicAuthPluginMiddleware.PASSWORD
119        url = 'http://localhost:%d/test_200' % \
120            HTTPBasicAuthMiddlewareTestCase.SERVICE_PORTNUM
121           
122        req = urllib2.Request(url)
123        base64String = base64.encodestring('%s:%s' % (username, password))[:-1]
124        authHeader =  "Basic %s" % base64String
125        req.add_header("Authorization", authHeader)
126        try:
127            handle = urllib2.urlopen(req)
128        except IOError, e:
129            print("It looks like the username or password is wrong: %s" % e)
130            return
131       
132        response = handle.read()
133        print (response)
134       
135    def test03WGetClient(self):
136        uri = ('http://localhost:%d/test_200' % 
137                  HTTPBasicAuthMiddlewareTestCase.SERVICE_PORTNUM)
138                 
139        username = HTTPBasicAuthPluginMiddleware.USERNAME
140        password = HTTPBasicAuthPluginMiddleware.PASSWORD
141       
142        import os
143        import subprocess
144        cmd = "%s %s %s=%s %s=%s %s=%s" % (
145            HTTPBasicAuthMiddlewareTestCase.WGET_CMD, 
146            uri,
147            HTTPBasicAuthMiddlewareTestCase.WGET_USER_OPTNAME,
148            username,
149            HTTPBasicAuthMiddlewareTestCase.WGET_PASSWD_OPTNAME,
150            password,
151            HTTPBasicAuthMiddlewareTestCase.WGET_OUTPUT_OPTNAME,
152            HTTPBasicAuthMiddlewareTestCase.WGET_STDOUT)
153       
154        p = subprocess.Popen(cmd, shell=True)
155        status = os.waitpid(p.pid, 0)
156        self.failIf(status[-1] != 0, "Expecting 0 exit status for %r" % cmd)
157
158
159if __name__ == "__main__":
160    unittest.main()
Note: See TracBrowser for help on using the repository browser.