1 from cherrypy.test import test
2 test.prefer_parent_path()
3
4 import md5, sha
5
6 import cherrypy
7 from cherrypy.lib import httpauth
8
10 class Root:
11 def index(self):
12 return "This is public."
13 index.exposed = True
14
15 class DigestProtected:
16 def index(self):
17 return "Hello %s, you've been authorized." % cherrypy.request.login
18 index.exposed = True
19
20 class BasicProtected:
21 def index(self):
22 return "Hello %s, you've been authorized." % cherrypy.request.login
23 index.exposed = True
24
25 class BasicProtected2:
26 def index(self):
27 return "Hello %s, you've been authorized." % cherrypy.request.login
28 index.exposed = True
29
30 def fetch_users():
31 return {'test': 'test'}
32
33 def sha_password_encrypter(password):
34 return sha.new(password).hexdigest()
35
36 def fetch_password(username):
37 return sha.new('test').hexdigest()
38
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.new('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}}
49 root = Root()
50 root.digest = DigestProtected()
51 root.basic = BasicProtected()
52 root.basic2 = BasicProtected2()
53 cherrypy.tree.mount(root, config=conf)
54 cherrypy.config.update({'environment': 'test_suite'})
55
56 from cherrypy.test import helper
57
59
65
67 self.getPage("/basic/")
68 self.assertStatus('401 Unauthorized')
69 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
70
71 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZX60')])
72 self.assertStatus('401 Unauthorized')
73
74 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
75 self.assertStatus('200 OK')
76 self.assertBody("Hello test, you've been authorized.")
77
79 self.getPage("/basic2/")
80 self.assertStatus('401 Unauthorized')
81 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"')
82
83 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZX60')])
84 self.assertStatus('401 Unauthorized')
85
86 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZXN0')])
87 self.assertStatus('200 OK')
88 self.assertBody("Hello test, you've been authorized.")
89
91 self.getPage("/digest/")
92 self.assertStatus('401 Unauthorized')
93
94 value = None
95 for k, v in self.headers:
96 if k.lower() == "www-authenticate":
97 if v.startswith("Digest"):
98 value = v
99 break
100
101 if value is None:
102 self._handlewebError("Digest authentification scheme was not found")
103
104 value = value[7:]
105 items = value.split(', ')
106 tokens = {}
107 for item in items:
108 key, value = item.split('=')
109 tokens[key.lower()] = value
110
111 missing_msg = "%s is missing"
112 bad_value_msg = "'%s' was expecting '%s' but found '%s'"
113 nonce = None
114 if 'realm' not in tokens:
115 self._handlewebError(missing_msg % 'realm')
116 elif tokens['realm'] != '"localhost"':
117 self._handlewebError(bad_value_msg % ('realm', '"localhost"', tokens['realm']))
118 if 'nonce' not in tokens:
119 self._handlewebError(missing_msg % 'nonce')
120 else:
121 nonce = tokens['nonce'].strip('"')
122 if 'algorithm' not in tokens:
123 self._handlewebError(missing_msg % 'algorithm')
124 elif tokens['algorithm'] != '"MD5"':
125 self._handlewebError(bad_value_msg % ('algorithm', '"MD5"', tokens['algorithm']))
126 if 'qop' not in tokens:
127 self._handlewebError(missing_msg % 'qop')
128 elif tokens['qop'] != '"auth"':
129 self._handlewebError(bad_value_msg % ('qop', '"auth"', tokens['qop']))
130
131
132 base_auth = 'Digest username="test", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"'
133
134 auth = base_auth % (nonce, '', '00000001')
135
136 params = httpauth.parseAuthorization(auth)
137 response = httpauth._computeDigestResponse(params, 'test')
138
139 auth = base_auth % (nonce, response, '00000001')
140 self.getPage('/digest/', [('Authorization', auth)])
141 self.assertStatus('200 OK')
142 self.assertBody("Hello test, you've been authorized.")
143
144 if __name__ == "__main__":
145 setup_server()
146 helper.testmain()
147