From 5e16b13985e9633e3295d0c6efbfb2bb4dfb60c5 Mon Sep 17 00:00:00 2001 From: Michael Barton Date: Fri, 8 Apr 2011 22:36:03 +0000 Subject: [PATCH 1/3] support URL-param signed requests in swift3 middleware --- swift/common/middleware/swift3.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/swift/common/middleware/swift3.py b/swift/common/middleware/swift3.py index a41c8cb695..39da35665f 100644 --- a/swift/common/middleware/swift3.py +++ b/swift/common/middleware/swift3.py @@ -16,9 +16,6 @@ """ The swift3 middleware will emulate the S3 REST api on top of swift. -The boto python library is necessary to use this middleware (install -the python-boto package if you use Ubuntu). - The following opperations are currently supported: * GET Service @@ -451,7 +448,16 @@ class Swift3Middleware(object): def __call__(self, env, start_response): req = Request(env) - if not'Authorization' in req.headers: + + if 'AWSAccessKeyId' in req.GET: + try: + req.headers['Date'] = req.GET['Expires'] + req.headers['Authorization'] = \ + 'AWS %(AWSAccessKeyId)s:%(Signature)s' % req.GET + except KeyError: + return get_err_response('InvalidArgument')(env, start_response) + + if not 'Authorization' in req.headers: return self.app(env, start_response) try: controller, path_parts = self.get_controller(req.path) From 14d8e8f3c3e05fc82a1255caeb10f4439ea040fc Mon Sep 17 00:00:00 2001 From: Michael Barton Date: Sat, 16 Apr 2011 05:57:53 +0000 Subject: [PATCH 2/3] add at least one test --- swift/common/middleware/swift3.py | 26 +++++++++------------- test/unit/common/middleware/test_swift3.py | 20 +++++++++++++++++ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/swift/common/middleware/swift3.py b/swift/common/middleware/swift3.py index 39da35665f..45fd662dd9 100644 --- a/swift/common/middleware/swift3.py +++ b/swift/common/middleware/swift3.py @@ -435,17 +435,6 @@ class Swift3Middleware(object): return BucketController, d return ServiceController, d - def get_account_info(self, env, req): - try: - account, user, _junk = \ - req.headers['Authorization'].split(' ')[-1].split(':') - except Exception: - return None, None - - h = canonical_string(req) - token = base64.urlsafe_b64encode(h) - return '%s:%s' % (account, user), token - def __call__(self, env, start_response): req = Request(env) @@ -459,17 +448,22 @@ class Swift3Middleware(object): if not 'Authorization' in req.headers: return self.app(env, start_response) + + try: + account, signature = \ + req.headers['Authorization'].split(' ')[-1].rsplit(':', 1) + except Exception: + return get_err_response('InvalidArgument')(env, start_response) + try: controller, path_parts = self.get_controller(req.path) except ValueError: return get_err_response('InvalidURI')(env, start_response) - account_name, token = self.get_account_info(env, req) - if not account_name: - return get_err_response('InvalidArgument')(env, start_response) + token = base64.urlsafe_b64encode(canonical_string(req)) + + controller = controller(env, self.app, account, token, **path_parts) - controller = controller(env, self.app, account_name, token, - **path_parts) if hasattr(controller, req.method): res = getattr(controller, req.method)(env, start_response) else: diff --git a/test/unit/common/middleware/test_swift3.py b/test/unit/common/middleware/test_swift3.py index 8d88da8332..8e765bf352 100644 --- a/test/unit/common/middleware/test_swift3.py +++ b/test/unit/common/middleware/test_swift3.py @@ -594,5 +594,25 @@ class TestSwift3(unittest.TestCase): self.assertEquals(swift3.canonical_string(req2), swift3.canonical_string(req3)) + def test_signed_urls(self): + class FakeApp(object): + def __call__(self, env, start_response): + self.req = Request(env) + start_response('200 OK') + start_response([]) + app = FakeApp() + local_app = swift3.filter_factory({})(app) + req = Request.blank('/bucket/object?Signature=X&Expires=Y&' + 'AWSAccessKeyId=Z', environ={'REQUEST_METHOD': 'PUT'}, + headers={'Authorization': 'AWS test:tester:hmac', + 'Content-MD5': 'ffoHqOWd280dyE1MT4KuoQ=='}) + req.date = datetime.now() + print req.GET + req.content_type = 'text/plain' + resp = local_app(req.environ, lambda *args: None) + print ''.join(resp) + self.assertEquals(app.req.headers['Authorization'], 'AWS Z:X') + self.assertEquals(app.req.headers['Date'], 'Y') + if __name__ == '__main__': unittest.main() From eea65967eb3132a22f57831b819c44c1ca19ac27 Mon Sep 17 00:00:00 2001 From: Michael Barton Date: Sat, 16 Apr 2011 06:02:01 +0000 Subject: [PATCH 3/3] clean up at least one test --- test/unit/common/middleware/test_swift3.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/unit/common/middleware/test_swift3.py b/test/unit/common/middleware/test_swift3.py index 8e765bf352..5396ab1dd2 100644 --- a/test/unit/common/middleware/test_swift3.py +++ b/test/unit/common/middleware/test_swift3.py @@ -603,14 +603,10 @@ class TestSwift3(unittest.TestCase): app = FakeApp() local_app = swift3.filter_factory({})(app) req = Request.blank('/bucket/object?Signature=X&Expires=Y&' - 'AWSAccessKeyId=Z', environ={'REQUEST_METHOD': 'PUT'}, - headers={'Authorization': 'AWS test:tester:hmac', - 'Content-MD5': 'ffoHqOWd280dyE1MT4KuoQ=='}) + 'AWSAccessKeyId=Z', environ={'REQUEST_METHOD': 'GET'}) req.date = datetime.now() - print req.GET req.content_type = 'text/plain' resp = local_app(req.environ, lambda *args: None) - print ''.join(resp) self.assertEquals(app.req.headers['Authorization'], 'AWS Z:X') self.assertEquals(app.req.headers['Date'], 'Y')