From 81976a76f439bcd93c2ca4c67d294cac3b553803 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Fri, 8 Jan 2016 11:59:56 +0900 Subject: [PATCH] Add unittests for verify_access Change-Id: Ife9ead3483bf4937a7ba1ec7f004d8dad3c20713 --- .../storlet_gateway/storlet_docker_gateway.py | 27 ++-- .../test_storlet_docker_gateway.py | 117 +++++++++++++++--- 2 files changed, 113 insertions(+), 31 deletions(-) diff --git a/Engine/swift/storlet_gateway/storlet_docker_gateway.py b/Engine/swift/storlet_gateway/storlet_docker_gateway.py index c9b1c9a9..514c76db 100644 --- a/Engine/swift/storlet_gateway/storlet_docker_gateway.py +++ b/Engine/swift/storlet_gateway/storlet_docker_gateway.py @@ -210,17 +210,13 @@ class StorletGatewayDocker(StorletGatewayBase): self._validate_dependency_upload(req) def authorizeStorletExecution(self, req): - res, headers = self.verify_access(req.environ, - self.version, - self.account, - self.sconf['storlet_container'], - req.headers['X-Run-Storlet']) - if not res: - raise HTTPUnauthorized('Account disabled for storlets', - request=req) - # keep the storlets headers for later use. - self.storlet_metadata = headers + self.storlet_metadata = self._verify_access( + req, + self.version, + self.account, + self.sconf['storlet_container'], + req.headers['X-Run-Storlet']) def augmentStorletRequest(self, req): if self.storlet_metadata: @@ -316,11 +312,11 @@ class StorletGatewayDocker(StorletGatewayBase): self.storlet_timeout, sprotocol._cancel) - def verify_access(self, env, version, account, container, object): + def _verify_access(self, req, version, account, container, object): self.logger.info('Verify access to {0}/{1}/{2}'.format(account, container, object)) - new_env = dict(env) + new_env = dict(req.environ) if 'HTTP_TRANSFER_ENCODING' in new_env.keys(): del new_env['HTTP_TRANSFER_ENCODING'] for key in CONDITIONAL_KEYS: @@ -336,9 +332,10 @@ class StorletGatewayDocker(StorletGatewayBase): storlet_req = Request.blank(new_env['PATH_INFO'], new_env) resp = storlet_req.get_response(self.app) - if resp.is_success: - return True, resp.headers - return False, [] + if not resp.is_success: + raise HTTPUnauthorized('Account disabled for storlets', + request=req) + return resp.headers def _validate_mandatory_headers(self, req): mandatory_md = None diff --git a/tests/unit/swift/storlet_gateway/test_storlet_docker_gateway.py b/tests/unit/swift/storlet_gateway/test_storlet_docker_gateway.py index a4cbc992..80e7a34a 100644 --- a/tests/unit/swift/storlet_gateway/test_storlet_docker_gateway.py +++ b/tests/unit/swift/storlet_gateway/test_storlet_docker_gateway.py @@ -73,8 +73,8 @@ class TestStorletGatewayDocker(unittest.TestCase): a = 'AUTH_xxxxxxxxxxxxxxxxxxxx' c = 'storlet' o = 'storlet-1.0.jar' - path = '/'.join([a, c, o]) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + path = '/'.join(['/v1', a, c, o]) + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) # sufficient headers @@ -100,8 +100,8 @@ class TestStorletGatewayDocker(unittest.TestCase): a = 'AUTH_xxxxxxxxxxxxxxxxxxxx' c = 'dependency' o = 'dep_file' - path = '/'.join([a, c, o]) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + path = '/'.join(['/v1', a, c, o]) + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) # sufficient headers @@ -118,33 +118,33 @@ class TestStorletGatewayDocker(unittest.TestCase): def test_validate_storlet_upload(self): a = 'AUTH_xxxxxxxxxxxxxxxxxxxx' - c = 'storlet' + c = self.sconf['storlet_container'] # correct name o = 'storlet-1.0.jar' - path = '/'.join([a, c, o]) + path = '/'.join(['/v1', a, c, o]) req = Request.blank(path, environ={'REQUEST_METHOD': 'PUT'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) gw._validate_storlet_upload(req) # wrong name o = 'storlet.jar' - path = '/'.join([a, c, o]) + path = '/'.join(['/v1', a, c, o]) req = Request.blank(path, environ={'REQUEST_METHOD': 'PUT'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) self.assertRaisesWithStatus(400, gw._validate_storlet_upload, req) def test_validate_dependency_upload(self): a = 'AUTH_xxxxxxxxxxxxxxxxxxxx' - c = 'dependency' + c = self.sconf['storlet_dependency'] o = 'dep_file' - path = '/'.join([a, c, o]) + path = '/'.join(['/v1', a, c, o]) # w/o dependency parameter req = Request.blank(path, environ={'REQUEST_METHOD': 'PUT'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) gw._validate_dependency_upload(req) @@ -153,7 +153,7 @@ class TestStorletGatewayDocker(unittest.TestCase): path, environ={'REQUEST_METHOD': 'PUT'}, headers={'x-object-meta-storlet-dependency-permissions': '755'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) gw._validate_dependency_upload(req) @@ -162,7 +162,7 @@ class TestStorletGatewayDocker(unittest.TestCase): path, environ={'REQUEST_METHOD': 'PUT'}, headers={'x-object-meta-storlet-dependency-permissions': '400'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) self.assertRaisesWithStatus(400, gw._validate_dependency_upload, req) @@ -171,7 +171,7 @@ class TestStorletGatewayDocker(unittest.TestCase): path, environ={'REQUEST_METHOD': 'PUT'}, headers={'x-object-meta-storlet-dependency-permissions': 'foo'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) self.assertRaisesWithStatus(400, gw._validate_dependency_upload, req) @@ -179,10 +179,95 @@ class TestStorletGatewayDocker(unittest.TestCase): path, environ={'REQUEST_METHOD': 'PUT'}, headers={'x-object-meta-storlet-dependency-permissions': '888'}) - gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 1.0, + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp(), 'v1', a, c, o) self.assertRaisesWithStatus(400, gw._validate_dependency_upload, req) + def test_authorizeStorletExecution(self): + a = 'a' + c = 'c' + o = 'o' + so = 'storlets-1.0.jar' + path = '/'.join(['/v1', a, c, o]) + + sheaders = { + 'X-Object-Meta-Storlet-Language': 'java', + 'X-Object-Meta-Storlet-Interface-Version': '1.0', + 'X-Object-Meta-Storlet-Dependency': 'dep_file', + 'X-Object-Meta-Storlet-Object-Metadata': 'no'} + + class FakeApp200(object): + def __call__(self, env, start_response): + req = Request(env) + return Response(request=req, headers=sheaders)( + env, start_response) + + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp200(), 'v1', + a, c, o) + env = {'REQUEST_METHOD': 'GET'} + req = Request.blank(path, environ=env, + headers={'X-Run-Storlet': so}) + gw.authorizeStorletExecution(req) + for key in sheaders.keys(): + self.assertEqual(sheaders[key], gw.storlet_metadata[key]) + + def test_verify_access(self): + a = 'a' + c = 'c' + o = 'o' + sc = self.sconf['storlet_container'] + so = 'storlets-1.0.jar' + path = '/'.join(['/v1', a, c, o]) + + sheaders = { + 'X-Object-Meta-Storlet-Language': 'java', + 'X-Object-Meta-Storlet-Interface-Version': '1.0', + 'X-Object-Meta-Storlet-Dependency': 'dep_file', + 'X-Object-Meta-Storlet-Object-Metadata': 'no'} + + class FakeApp200(object): + def __call__(self, env, start_response): + req = Request(env) + return Response(request=req, headers=sheaders)( + env, start_response) + + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp200(), 'v1', + a, c, o) + env = {'REQUEST_METHOD': 'GET'} + req = Request.blank(path, environ=env, + headers={'X-Run-Storlet': so}) + headers = gw._verify_access(req, 'v1', a, sc, so) + for key in sheaders.keys(): + self.assertEqual(sheaders[key], headers[key]) + + class FakeApp401(object): + def __call__(self, env, start_response): + req = Request(env) + return Response(request=req, status='401 Unauthorized')( + env, start_response) + + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp401(), 'v1', + a, c, o) + env = {'REQUEST_METHOD': 'GET'} + req = Request.blank(path, environ=env, + headers={'X-Run-Storlet': so}) + self.assertRaisesWithStatus(401, gw._verify_access, req, 'v1', + a, sc, so) + + class FakeApp404(object): + def __call__(self, env, start_response): + req = Request(env) + return Response(request=req, status='404 Not Found')( + env, start_response) + + gw = StorletGatewayDocker(self.sconf, self.logger, FakeApp404(), 'v1', + a, c, o) + env = {'REQUEST_METHOD': 'GET'} + req = Request.blank(path, environ=env, + headers={'X-Run-Storlet': so}) + self.assertRaisesWithStatus(401, gw._verify_access, req, 'v1', + a, sc, so) + if __name__ == '__main__': unittest.main()