test_httpauth.py (5757B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\test\test_httpauth.py 2 import cherrypy 3 from cherrypy._cpcompat import md5, sha, ntob 4 from cherrypy.lib import httpauth 5 from cherrypy.test import helper 6 7 class HTTPAuthTest(helper.CPWebCase): 8 9 def setup_server(): 10 11 class Root: 12 13 def index(self): 14 return 'This is public.' 15 16 index.exposed = True 17 18 class DigestProtected: 19 20 def index(self): 21 return "Hello %s, you've been authorized." % cherrypy.request.login 22 23 index.exposed = True 24 25 class BasicProtected: 26 27 def index(self): 28 return "Hello %s, you've been authorized." % cherrypy.request.login 29 30 index.exposed = True 31 32 class BasicProtected2: 33 34 def index(self): 35 return "Hello %s, you've been authorized." % cherrypy.request.login 36 37 index.exposed = True 38 39 def fetch_users(): 40 return {'test': 'test'} 41 42 def sha_password_encrypter(password): 43 return sha(ntob(password)).hexdigest() 44 45 def fetch_password(username): 46 return sha(ntob('test')).hexdigest() 47 48 conf = {'/digest': {'tools.digest_auth.on': True, 49 'tools.digest_auth.realm': 'localhost', 50 'tools.digest_auth.users': fetch_users}, 51 '/basic': {'tools.basic_auth.on': True, 52 'tools.basic_auth.realm': 'localhost', 53 'tools.basic_auth.users': {'test': md5(ntob('test')).hexdigest()}}, 54 '/basic2': {'tools.basic_auth.on': True, 55 'tools.basic_auth.realm': 'localhost', 56 'tools.basic_auth.users': fetch_password, 57 'tools.basic_auth.encrypt': sha_password_encrypter}} 58 root = Root() 59 root.digest = DigestProtected() 60 root.basic = BasicProtected() 61 root.basic2 = BasicProtected2() 62 cherrypy.tree.mount(root, config=conf) 63 64 setup_server = staticmethod(setup_server) 65 66 def testPublic(self): 67 self.getPage('/') 68 self.assertStatus('200 OK') 69 self.assertHeader('Content-Type', 'text/html;charset=utf-8') 70 self.assertBody('This is public.') 71 72 def testBasic(self): 73 self.getPage('/basic/') 74 self.assertStatus(401) 75 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"') 76 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZX60')]) 77 self.assertStatus(401) 78 self.getPage('/basic/', [('Authorization', 'Basic dGVzdDp0ZXN0')]) 79 self.assertStatus('200 OK') 80 self.assertBody("Hello test, you've been authorized.") 81 82 def testBasic2(self): 83 self.getPage('/basic2/') 84 self.assertStatus(401) 85 self.assertHeader('WWW-Authenticate', 'Basic realm="localhost"') 86 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZX60')]) 87 self.assertStatus(401) 88 self.getPage('/basic2/', [('Authorization', 'Basic dGVzdDp0ZXN0')]) 89 self.assertStatus('200 OK') 90 self.assertBody("Hello test, you've been authorized.") 91 92 def testDigest(self): 93 self.getPage('/digest/') 94 self.assertStatus(401) 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 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 base_auth = 'Digest username="test", realm="wrong realm", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"' 131 auth = base_auth % (nonce, '', '00000001') 132 params = httpauth.parseAuthorization(auth) 133 response = httpauth._computeDigestResponse(params, 'test') 134 auth = base_auth % (nonce, response, '00000001') 135 self.getPage('/digest/', [('Authorization', auth)]) 136 self.assertStatus(401) 137 base_auth = 'Digest username="test", realm="localhost", nonce="%s", uri="/digest/", algorithm=MD5, response="%s", qop=auth, nc=%s, cnonce="1522e61005789929"' 138 auth = base_auth % (nonce, '', '00000001') 139 params = httpauth.parseAuthorization(auth) 140 response = httpauth._computeDigestResponse(params, 'test') 141 auth = base_auth % (nonce, response, '00000001') 142 self.getPage('/digest/', [('Authorization', auth)]) 143 self.assertStatus('200 OK') 144 self.assertBody("Hello test, you've been authorized.")