def test_get_admin_info_invalid_expires(self): controller = self.get_controller(expose_info=True, admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = 1 sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('401 Unauthorized', str(resp)) expires = 'abc' sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('401 Unauthorized', str(resp))
def test_get_admin_info_invalid_expires(self): controller = self.get_controller(expose_info=True, admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = 1 sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('401 Unauthorized', str(resp)) expires = 'abc' sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('401 Unauthorized', str(resp))
def test_head_admin_info(self): controller = self.get_controller(expose_info=True, admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'HEAD'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('200 OK', str(resp)) expires = int(time.time() + 86400) sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'HEAD'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('200 OK', str(resp))
def test_head_admin_info(self): controller = self.get_controller(expose_info=True, admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'HEAD'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('200 OK', str(resp)) expires = int(time.time() + 86400) sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'HEAD'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('200 OK', str(resp))
def test_admin_disallow_info(self): controller = self.get_controller(expose_info=True, disallowed_sections=['foo2'], admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}, 'foo2': {'bar2': 'baz2'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('200 OK', str(resp)) info = json.loads(resp.body) self.assertNotIn('foo2', info) self.assertIn('admin', info) self.assertIn('disallowed_sections', info['admin']) self.assertIn('foo2', info['admin']['disallowed_sections']) self.assertIn('qux', info['admin']) self.assertIn('quux', info['admin']['qux']) self.assertEqual(info['admin']['qux']['quux'], 'corge')
def _get_hmacs(self, env, expires, path, scoped_keys, hash_algorithm, request_method=None, ip_range=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param path: The path which is used for hashing. :param scoped_keys: (key, scope) tuples like _get_keys() returns :param hash_algorithm: The hash algorithm to use. :param request_method: Optional override of the request in the WSGI env. For example, if a HEAD does not match, you may wish to override with GET to still allow the HEAD. :param ip_range: The ip range from which the resource is allowed to be accessed :returns: a list of (hmac, scope) 2-tuples """ if not request_method: request_method = env['REQUEST_METHOD'] digest = functools.partial(hashlib.new, hash_algorithm) return [ (get_hmac( request_method, path, expires, key, digest=digest, ip_range=ip_range ), scope) for (key, scope) in scoped_keys]
def _get_hmacs(self, env, expires, path, scoped_keys, hash_algorithm, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param path: The path which is used for hashing. :param scoped_keys: (key, scope) tuples like _get_keys() returns :param hash_algorithm: The hash algorithm to use. :param request_method: Optional override of the request in the WSGI env. For example, if a HEAD does not match, you may wish to override with GET to still allow the HEAD. :returns: a list of (hmac, scope) 2-tuples """ if not request_method: request_method = env['REQUEST_METHOD'] digest = functools.partial(hashlib.new, hash_algorithm) return [(get_hmac(request_method, path, expires, key, digest), scope) for (key, scope) in scoped_keys]
def test_admin_disallow_info(self): controller = self.get_controller(expose_info=True, disallowed_sections=['foo2'], admin_key='secret-admin-key') utils._swift_info = {'foo': {'bar': 'baz'}, 'foo2': {'bar2': 'baz2'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('200 OK', str(resp)) info = json.loads(resp.body) self.assertTrue('foo2' not in info) self.assertTrue('admin' in info) self.assertTrue('disallowed_sections' in info['admin']) self.assertTrue('foo2' in info['admin']['disallowed_sections']) self.assertTrue('qux' in info['admin']) self.assertTrue('quux' in info['admin']['qux']) self.assertEqual(info['admin']['qux']['quux'], 'corge')
def GETorHEAD(self, req): """Handler for HTTP GET/HEAD requests.""" """ Handles requests to /info Should return a WSGI-style callable (such as swob.Response). :param req: swob.Request object """ if not self.expose_info: return HTTPForbidden(request=req) admin_request = False sig = req.params.get('swiftinfo_sig', '') expires = req.params.get('swiftinfo_expires', '') if sig != '' or expires != '': admin_request = True if not self.admin_key: return HTTPForbidden(request=req) try: expires = int(expires) except ValueError: return HTTPUnauthorized(request=req) if expires < time(): return HTTPUnauthorized(request=req) valid_sigs = [] for method in self.allowed_hmac_methods[req.method]: valid_sigs.append(get_hmac(method, '/info', expires, self.admin_key)) # While it's true that any() will short-circuit, this doesn't # affect the timing-attack resistance since the only way this will # short-circuit is when a valid signature is passed in. is_valid_hmac = any(streq_const_time(valid_sig, sig) for valid_sig in valid_sigs) if not is_valid_hmac: return HTTPUnauthorized(request=req) headers = {} if 'Origin' in req.headers: headers['Access-Control-Allow-Origin'] = req.headers['Origin'] headers['Access-Control-Expose-Headers'] = ', '.join( ['x-trans-id']) #json.dumps(dict)可以将字典形式的dict对象转换为json格式的对象 info = json.dumps(get_swift_info( admin=admin_request, disallowed_sections=self.disallowed_sections)) return HTTPOk(request=req, headers=headers, body=info, content_type='application/json; charset=UTF-8')
def GETorHEAD(self, req): """Handler for HTTP GET/HEAD requests.""" """ Handles requests to /info Should return a WSGI-style callable (such as swob.Response). :param req: swob.Request object """ if not self.expose_info: return HTTPForbidden(request=req) admin_request = False sig = req.params.get('swiftinfo_sig', '') expires = req.params.get('swiftinfo_expires', '') if sig != '' or expires != '': admin_request = True if not self.admin_key: return HTTPForbidden(request=req) try: expires = int(expires) except ValueError: return HTTPUnauthorized(request=req) if expires < time(): return HTTPUnauthorized(request=req) valid_sigs = [] for method in self.allowed_hmac_methods[req.method]: valid_sigs.append( get_hmac(method, '/info', expires, self.admin_key)) # While it's true that any() will short-circuit, this doesn't # affect the timing-attack resistance since the only way this will # short-circuit is when a valid signature is passed in. is_valid_hmac = any( streq_const_time(valid_sig, sig) for valid_sig in valid_sigs) if not is_valid_hmac: return HTTPUnauthorized(request=req) headers = {} if 'Origin' in req.headers: headers['Access-Control-Allow-Origin'] = req.headers['Origin'] headers['Access-Control-Expose-Headers'] = ', '.join( ['x-trans-id']) info = json.dumps( get_swift_info(admin=admin_request, disallowed_sections=self.disallowed_sections)) return HTTPOk(request=req, headers=headers, body=info, content_type='application/json; charset=UTF-8')
def _get_hmacs(self, env, expires, keys, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of the account. """ if not request_method: request_method = env['REQUEST_METHOD'] return [get_hmac( request_method, env['PATH_INFO'], expires, key) for key in keys]
def test_disabled_admin_info(self): controller = self.get_controller(expose_info=True, admin_key='') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, '') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank(path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertTrue(isinstance(resp, HTTPException)) self.assertEqual('403 Forbidden', str(resp))
def _get_hmacs(self, env, expires, keys, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of the account. """ if not request_method: request_method = env['REQUEST_METHOD'] return [ get_hmac(request_method, env['PATH_INFO'], expires, key) for key in keys ]
def test_disabled_admin_info(self): controller = self.get_controller(expose_info=True, admin_key='') utils._swift_info = {'foo': {'bar': 'baz'}} utils._swift_admin_info = {'qux': {'quux': 'corge'}} expires = int(time.time() + 86400) sig = utils.get_hmac('GET', '/info', expires, '') path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format( sig=sig, expires=expires) req = Request.blank( path, environ={'REQUEST_METHOD': 'GET'}) resp = controller.GET(req) self.assertIsInstance(resp, HTTPException) self.assertEqual('403 Forbidden', str(resp))
def GETorHEAD(self, req): """Handler for HTTP GET/HEAD requests.""" """ Handles requests to /info Should return a WSGI-style callable (such as swob.Response). :param req: swob.Request object """ if not self.expose_info: return HTTPForbidden(request=req) admin_request = False sig = req.params.get('swiftinfo_sig', '') expires = req.params.get('swiftinfo_expires', '') if sig != '' or expires != '': admin_request = True if not self.admin_key: return HTTPForbidden(request=req) try: expires = int(expires) except ValueError: return HTTPUnauthorized(request=req) if expires < time(): return HTTPUnauthorized(request=req) valid_sigs = [] for method in self.allowed_hmac_methods[req.method]: valid_sigs.append( get_hmac(method, '/info', expires, self.admin_key)) if sig not in valid_sigs: return HTTPUnauthorized(request=req) headers = {} if 'Origin' in req.headers: headers['Access-Control-Allow-Origin'] = req.headers['Origin'] headers['Access-Control-Expose-Headers'] = ', '.join( ['x-trans-id']) info = json.dumps( get_swift_info(admin=admin_request, disallowed_sections=self.disallowed_sections)) return HTTPOk(request=req, headers=headers, body=info, content_type='application/json; charset=UTF-8')
def _get_hmacs(self, env, expires, keys, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of the account. :param request_method: Optional override of the request in the WSGI env. For example, if a HEAD does not match, you may wish to override with GET to still allow the HEAD. """ if not request_method: request_method = env['REQUEST_METHOD'] return [get_hmac( request_method, env['PATH_INFO'], expires, key) for key in keys]
def _get_hmacs(self, env, expires, scoped_keys, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param scoped_keys: (key, scope) tuples like _get_keys() returns :param request_method: Optional override of the request in the WSGI env. For example, if a HEAD does not match, you may wish to override with GET to still allow the HEAD. :returns: a list of (hmac, scope) 2-tuples """ if not request_method: request_method = env["REQUEST_METHOD"] return [(get_hmac(request_method, env["PATH_INFO"], expires, key), scope) for (key, scope) in scoped_keys]
def _get_hmacs(self, env, expires, scoped_keys, request_method=None): """ :param env: The WSGI environment for the request. :param expires: Unix timestamp as an int for when the URL expires. :param scoped_keys: (key, scope) tuples like _get_keys() returns :param request_method: Optional override of the request in the WSGI env. For example, if a HEAD does not match, you may wish to override with GET to still allow the HEAD. :returns: a list of (hmac, scope) 2-tuples """ if not request_method: request_method = env['REQUEST_METHOD'] return [(get_hmac(request_method, env['PATH_INFO'], expires, key), scope) for (key, scope) in scoped_keys]
def GETorHEAD(self, req): """Handler for HTTP GET/HEAD requests.""" """ Handles requests to /info Should return a WSGI-style callable (such as swob.Response). :param req: swob.Request object """ if not self.expose_info: return HTTPForbidden(request=req) admin_request = False sig = req.params.get("swiftinfo_sig", "") expires = req.params.get("swiftinfo_expires", "") if sig != "" or expires != "": admin_request = True if not self.admin_key: return HTTPForbidden(request=req) try: expires = int(expires) except ValueError: return HTTPUnauthorized(request=req) if expires < time(): return HTTPUnauthorized(request=req) valid_sigs = [] for method in self.allowed_hmac_methods[req.method]: valid_sigs.append(get_hmac(method, "/info", expires, self.admin_key)) if sig not in valid_sigs: return HTTPUnauthorized(request=req) headers = {} if "Origin" in req.headers: headers["Access-Control-Allow-Origin"] = req.headers["Origin"] headers["Access-Control-Expose-Headers"] = ", ".join(["x-trans-id"]) info = json.dumps(get_swift_info(admin=admin_request, disallowed_sections=self.disallowed_sections)) return HTTPOk(request=req, headers=headers, body=info, content_type="application/json; charset=UTF-8")