Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/trunk/cherrypy/test/test_httpauth.py

Revision 2670 (checked in by fumanchu, 3 months ago)

Removed test.py etc.

  • Property svn:eol-style set to native
Line 
1 try:
2     # Python 2.5+
3     from hashlib import md5, sha1 as sha
4 except ImportError:
5     from md5 import new as md5
6     from sha import new as sha
7
8 import cherrypy
9 from cherrypy.lib import httpauth
10
11 from cherrypy.test import helper
12
13 class HTTPAuthTest(helper.CPWebCase):
14     @staticmethod
15     def setup_server():
16         class Root:
17             def index(self):
18                 return "This is public."
19             index.exposed = True
20
21         class DigestProtected:
22             def index(self):
23                 return "Hello %s, you've been authorized." % cherrypy.request.login
24             index.exposed = True
25
26         class BasicProtected:
27             def index(self):
28                 return "Hello %s, you've been authorized." % cherrypy.request.login
29             index.exposed = True
30
31         class BasicProtected2:
32             def index(self):
33                 return "Hello %s, you've been authorized." % cherrypy.request.login
34             index.exposed = True
35
36         def fetch_users():
37             return {'test': 'test'}
38
39         def sha_password_encrypter(password):
40             return sha(password).hexdigest()
41        
42         def fetch_password(username):
43             return sha('test').hexdigest()
44
45         conf = {'/digest': {'tools.digest_auth.on': True,
46                             'tools.digest_auth.realm': 'localhost',
47                             'tools.digest_auth.users': fetch_users},
48                 '/basic': {'tools.basic_auth.on': True,
49                            'tools.basic_auth.realm': 'localhost',
50                            'tools.basic_auth.users': {'test': md5('test').hexdigest()}},
51                 '/basic2': {'tools.basic_auth.on': True,
52                             'tools.basic_auth.realm': 'localhost',
53                             'tools.basic_auth.users': fetch_password,
54                             'tools.basic_auth.encrypt': sha_password_encrypter}}
55                
56         root = Root()
57         root.digest = DigestProtected()
58         root.basic = BasicProtected()
59         root.basic2 = BasicProtected2()
60         cherrypy.tree.mount(root, config=conf)
61
62
63     def testPublic(self):
64         self.getPage("/")
65         self.assertStatus('200 OK')
66         self.assertHeader('Content-Type', 'text/html;charset=utf-8')
67         self.assertBody('This is public.')
68
69     def testBasic(self):
70         self.getPage("/basic/")
71         self.assertStatus(401)
72         self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
73
74         self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZX60')])
75         self.assertStatus(401)
76        
77         self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
78         self.assertStatus('200 OK')
79         self.assertBody("Hello test, you've been authorized.")
80
81     def testBasic2(self):
82         self.getPage("/basic2/")
83         self.assertStatus(401)
84         self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
85
86         self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZX60')])
87         self.assertStatus(401)
88        
89         self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
90         self.assertStatus('200 OK')
91         self.assertBody("Hello test, you've been authorized.")
92
93     def testDigest(self):
94         self.getPage("/digest/")
95         self.assertStatus(401)
96        
97         value = None
98         for k, v in self.headers:
99             if k.lower() == "www-authenticate":
100                 if v.startswith("Digest"):
101                     value = v
102                     break
103
104         if value is None:
105             self._handlewebError("Digest authentification scheme was not found")
106
107         value = value[7:]
108         items = value.split(', ')
109         tokens = {}
110         for item in items:
111             key, value = item.split('=')
112             tokens[key.lower()] = value
113            
114         missing_msg = "%s is missing"
115         bad_value_msg = "'%s' was expecting '%s' but found '%s'"
116         nonce = None
117         if 'realm' not in tokens:
118             self._handlewebError(missing_msg % 'realm')
119         elif tokens['realm'] != '"localhost"':
120             self._handlewebError(bad_value_msg % ('realm', '"localhost"', tokens['realm']))
121         if 'nonce' not in tokens:
122             self._handlewebError(missing_msg % 'nonce')
123         else:
124             nonce = tokens['nonce'].strip('"')
125         if 'algorithm' not in tokens:
126             self._handlewebError(missing_msg % 'algorithm')
127         elif tokens['algorithm'] != '"MD5"':
128             self._handlewebError(bad_value_msg % ('algorithm', '"MD5"', tokens['algorithm']))
129         if 'qop' not in tokens:
130             self._handlewebError(missing_msg % 'qop')
131         elif tokens['qop'] != '"auth"':
132             self._handlewebError(bad_value_msg % ('qop', '"auth"', tokens['qop']))
133
134         # Test a wrong 'realm' value
135         base_auth = 'Digest username="test", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
136
137         auth = base_auth % (nonce, '', '00000001')
138         params = httpauth.parseAuthorization(auth)
139         response = httpauth._computeDigestResponse(params, 'test')
140        
141         auth = base_auth % (nonce, response, '00000001')
142         self.getPage('/digest/', [('Authorization', auth)])
143         self.assertStatus(401)
144
145         # Test that must pass
146         base_auth = 'Digest username="test", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
147
148         auth = base_auth % (nonce, '', '00000001')
149         params = httpauth.parseAuthorization(auth)
150         response = httpauth._computeDigestResponse(params, 'test')
151        
152         auth = base_auth % (nonce, response, '00000001')
153         self.getPage('/digest/', [('Authorization', auth)])
154         self.assertStatus('200 OK')
155         self.assertBody("Hello test, you've been authorized.")
156
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets