Fixed python_path problem.
[smonitor.git] / lib / cherrypy / test / test_httpauth.py
blob9d0eecb28cbcb636ca07824d574741a2b6217e24
1 import cherrypy
2 from cherrypy._cpcompat import md5, sha, ntob
3 from cherrypy.lib import httpauth
5 from cherrypy.test import helper
7 class HTTPAuthTest(helper.CPWebCase):
9 def setup_server():
10 class Root:
11 def index(self):
12 return "This is public."
13 index.exposed = True
15 class DigestProtected:
16 def index(self):
17 return "Hello %s, you've been authorized." % cherrypy.request.login
18 index.exposed = True
20 class BasicProtected:
21 def index(self):
22 return "Hello %s, you've been authorized." % cherrypy.request.login
23 index.exposed = True
25 class BasicProtected2:
26 def index(self):
27 return "Hello %s, you've been authorized." % cherrypy.request.login
28 index.exposed = True
30 def fetch_users():
31 return {'test': 'test'}
33 def sha_password_encrypter(password):
34 return sha(ntob(password)).hexdigest()
36 def fetch_password(username):
37 return sha(ntob('test')).hexdigest()
39 conf = {'/digest': {'tools.digest_auth.on': True,
40 'tools.digest_auth.realm': 'localhost',
41 'tools.digest_auth.users': fetch_users},
42 '/basic': {'tools.basic_auth.on': True,
43 'tools.basic_auth.realm': 'localhost',
44 'tools.basic_auth.users': {'test': md5(ntob('test')).hexdigest()}},
45 '/basic2': {'tools.basic_auth.on': True,
46 'tools.basic_auth.realm': 'localhost',
47 'tools.basic_auth.users': fetch_password,
48 'tools.basic_auth.encrypt': sha_password_encrypter}}
50 root = Root()
51 root.digest = DigestProtected()
52 root.basic = BasicProtected()
53 root.basic2 = BasicProtected2()
54 cherrypy.tree.mount(root, config=conf)
55 setup_server = staticmethod(setup_server)
58 def testPublic(self):
59 self.getPage("/")
60 self.assertStatus('200 OK')
61 self.assertHeader('Content-Type', 'text/html;charset=utf-8')
62 self.assertBody('This is public.')
64 def testBasic(self):
65 self.getPage("/basic/")
66 self.assertStatus(401)
67 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
69 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZX60')])
70 self.assertStatus(401)
72 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
73 self.assertStatus('200 OK')
74 self.assertBody("Hello test, you've been authorized.")
76 def testBasic2(self):
77 self.getPage("/basic2/")
78 self.assertStatus(401)
79 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
81 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZX60')])
82 self.assertStatus(401)
84 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
85 self.assertStatus('200 OK')
86 self.assertBody("Hello test, you've been authorized.")
88 def testDigest(self):
89 self.getPage("/digest/")
90 self.assertStatus(401)
92 value = None
93 for k, v in self.headers:
94 if k.lower() == "www-authenticate":
95 if v.startswith("Digest"):
96 value = v
97 break
99 if value is None:
100 self._handlewebError("Digest authentification scheme was not found")
102 value = value[7:]
103 items = value.split(', ')
104 tokens = {}
105 for item in items:
106 key, value = item.split('=')
107 tokens[key.lower()] = value
109 missing_msg = "%s is missing"
110 bad_value_msg = "'%s' was expecting '%s' but found '%s'"
111 nonce = None
112 if 'realm' not in tokens:
113 self._handlewebError(missing_msg % 'realm')
114 elif tokens['realm'] != '"localhost"':
115 self._handlewebError(bad_value_msg % ('realm', '"localhost"', tokens['realm']))
116 if 'nonce' not in tokens:
117 self._handlewebError(missing_msg % 'nonce')
118 else:
119 nonce = tokens['nonce'].strip('"')
120 if 'algorithm' not in tokens:
121 self._handlewebError(missing_msg % 'algorithm')
122 elif tokens['algorithm'] != '"MD5"':
123 self._handlewebError(bad_value_msg % ('algorithm', '"MD5"', tokens['algorithm']))
124 if 'qop' not in tokens:
125 self._handlewebError(missing_msg % 'qop')
126 elif tokens['qop'] != '"auth"':
127 self._handlewebError(bad_value_msg % ('qop', '"auth"', tokens['qop']))
129 # Test a wrong 'realm' value
130 base_auth = 'Digest username="test", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
132 auth = base_auth % (nonce, '', '00000001')
133 params = httpauth.parseAuthorization(auth)
134 response = httpauth._computeDigestResponse(params, 'test')
136 auth = base_auth % (nonce, response, '00000001')
137 self.getPage('/digest/', [('Authorization', auth)])
138 self.assertStatus(401)
140 # Test that must pass
141 base_auth = 'Digest username="test", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
143 auth = base_auth % (nonce, '', '00000001')
144 params = httpauth.parseAuthorization(auth)
145 response = httpauth._computeDigestResponse(params, 'test')
147 auth = base_auth % (nonce, response, '00000001')
148 self.getPage('/digest/', [('Authorization', auth)])
149 self.assertStatus('200 OK')
150 self.assertBody("Hello test, you've been authorized.")