Package cherrypy :: Package test :: Module test_httpauth
[hide private]
[frames] | no frames]

Source Code for Module cherrypy.test.test_httpauth

  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   
9 -def setup_server():
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 50 root = Root() 51 root.digest = DigestProtected() 52 root.basic = BasicProtected() 53 root.basic2 = BasicProtected2() 54 cherrypy.tree.mount(root, config=conf) 55 cherrypy.config.update({'environment': 'test_suite'}) 56 57 from cherrypy.test import helper 58
59 -class HTTPAuthTest(helper.CPWebCase):
60
61 - def testPublic(self):
62 self.getPage("/") 63 self.assertStatus('200 OK') 64 self.assertHeader('Content-Type', 'text/html') 65 self.assertBody('This is public.')
66
67 - def testBasic(self):
68 self.getPage("/basic/") 69 self.assertStatus(401) 70 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"') 71 72 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZX60')]) 73 self.assertStatus(401) 74 75 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZXN0')]) 76 self.assertStatus('200 OK') 77 self.assertBody("Hello test, you've been authorized.")
78
79 - def testBasic2(self):
80 self.getPage("/basic2/") 81 self.assertStatus(401) 82 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"') 83 84 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZX60')]) 85 self.assertStatus(401) 86 87 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZXN0')]) 88 self.assertStatus('200 OK') 89 self.assertBody("Hello test, you've been authorized.")
90
91 - def testDigest(self):
92 self.getPage("/digest/") 93 self.assertStatus(401) 94 95 value = None 96 for k, v in self.headers: 97 if k.lower() == "www-authenticate": 98 if v.startswith("Digest"): 99 value = v 100 break 101 102 if value is None: 103 self._handlewebError("Digest authentification scheme was not found") 104 105 value = value[7:] 106 items = value.split(', ') 107 tokens = {} 108 for item in items: 109 key, value = item.split('=') 110 tokens[key.lower()] = value 111 112 missing_msg = "%s is missing" 113 bad_value_msg = "'%s' was expecting '%s' but found '%s'" 114 nonce = None 115 if 'realm' not in tokens: 116 self._handlewebError(missing_msg % 'realm') 117 elif tokens['realm'] != '"localhost"': 118 self._handlewebError(bad_value_msg % ('realm', '"localhost"', tokens['realm'])) 119 if 'nonce' not in tokens: 120 self._handlewebError(missing_msg % 'nonce') 121 else: 122 nonce = tokens['nonce'].strip('"') 123 if 'algorithm' not in tokens: 124 self._handlewebError(missing_msg % 'algorithm') 125 elif tokens['algorithm'] != '"MD5"': 126 self._handlewebError(bad_value_msg % ('algorithm', '"MD5"', tokens['algorithm'])) 127 if 'qop' not in tokens: 128 self._handlewebError(missing_msg % 'qop') 129 elif tokens['qop'] != '"auth"': 130 self._handlewebError(bad_value_msg % ('qop', '"auth"', tokens['qop'])) 131 132 # Test a wrong 'realm' value 133 base_auth = 'Digest username="test", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"' 134 135 auth = base_auth % (nonce, '', '00000001') 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(401) 142 143 # Test that must pass 144 base_auth = 'Digest username="test", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"' 145 146 auth = base_auth % (nonce, '', '00000001') 147 params = httpauth.parseAuthorization(auth) 148 response = httpauth._computeDigestResponse(params, 'test') 149 150 auth = base_auth % (nonce, response, '00000001') 151 self.getPage('/digest/', [('Authorization', auth)]) 152 self.assertStatus('200 OK') 153 self.assertBody("Hello test, you've been authorized.")
154 155 if __name__ == "__main__": 156 setup_server() 157 helper.testmain() 158