diff --git a/swift/common/middleware/tempurl.py b/swift/common/middleware/tempurl.py index 15b6bca74e..517bb332d7 100644 --- a/swift/common/middleware/tempurl.py +++ b/swift/common/middleware/tempurl.py @@ -46,9 +46,9 @@ limited to the expiration time set when the website created the link. To create such temporary URLs, first an X-Account-Meta-Temp-URL-Key header must be set on the Swift account. Then, an HMAC-SHA1 (RFC 2104) -signature is generated using the HTTP method to allow (GET or PUT), -the Unix timestamp the access should be allowed until, the full path -to the object, and the key set on the account. +signature is generated using the HTTP method to allow (GET, PUT, +DELETE, etc.), the Unix timestamp the access should be allowed until, +the full path to the object, and the key set on the account. For example, here is code generating the signature for a GET for 60 seconds on /v1/AUTH_account/container/object:: @@ -75,7 +75,7 @@ da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires ends up Any alteration of the resource path or query arguments would result in 401 Unauthorized. Similary, a PUT where GET was the allowed method -would 401. HEAD is allowed if GET or PUT is allowed. +would 401. HEAD is allowed if GET, PUT, or POST is allowed. Using this in combination with browser form post translation middleware could also allow direct-from-browser uploads to specific @@ -300,6 +300,8 @@ class TempURL(object): self._get_hmacs(env, temp_url_expires, keys) + self._get_hmacs(env, temp_url_expires, keys, request_method='GET') + + self._get_hmacs(env, temp_url_expires, keys, + request_method='POST') + self._get_hmacs(env, temp_url_expires, keys, request_method='PUT')) else: diff --git a/test/unit/common/middleware/test_tempurl.py b/test/unit/common/middleware/test_tempurl.py index 3a48bfe8bf..bb73993731 100644 --- a/test/unit/common/middleware/test_tempurl.py +++ b/test/unit/common/middleware/test_tempurl.py @@ -451,6 +451,23 @@ class TestTempURL(unittest.TestCase): self.assertEquals(req.environ['swift.authorize_override'], True) self.assertEquals(req.environ['REMOTE_USER'], '.wsgi.tempurl') + def test_head_allowed_by_post(self): + method = 'POST' + expires = int(time() + 86400) + path = '/v1/a/c/o' + key = 'abc' + hmac_body = '%s\n%s\n%s' % (method, expires, path) + sig = hmac.new(key, hmac_body, sha1).hexdigest() + req = self._make_request( + path, keys=[key], + environ={'REQUEST_METHOD': 'HEAD', + 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( + sig, expires)}) + resp = req.get_response(self.tempurl) + self.assertEquals(resp.status_int, 404) + self.assertEquals(req.environ['swift.authorize_override'], True) + self.assertEquals(req.environ['REMOTE_USER'], '.wsgi.tempurl') + def test_head_otherwise_not_allowed(self): method = 'PUT' expires = int(time() + 86400)