Always fetch temp URL key before generation

SwiftClientPlugin.get_temp_url has the potential to race with
itself when storing a new tempurl key to the swift account,
leading to tempurls being built with a key that has been
overridden.

This change always fetches the key from swift before creating a
temp URL.

Change-Id: Id5897fdd834cc5d3b74fda8d2317d084a5564c51
Closes-Bug: #1413366
This commit is contained in:
Steve Baker
2015-01-22 09:45:05 +13:00
parent f690f8d599
commit 7401c030ff
2 changed files with 16 additions and 9 deletions

View File

@@ -91,11 +91,12 @@ class SwiftClientPlugin(client_plugin.ClientPlugin):
Return a Swift TempURL. Return a Swift TempURL.
''' '''
key_header = 'x-account-meta-temp-url-key' key_header = 'x-account-meta-temp-url-key'
if key_header in self.client().head_account(): if key_header not in self.client().head_account():
self.client().post_account({
key_header: hashlib.sha224(
str(random.getrandbits(256))).hexdigest()[:32]})
key = self.client().head_account()[key_header] key = self.client().head_account()[key_header]
else:
key = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[:32]
self.client().post_account({key_header: key})
path = '/v1/AUTH_%s/%s/%s' % (self.context.tenant_id, container_name, path = '/v1/AUTH_%s/%s/%s' % (self.context.tenant_id, container_name,
obj_name) obj_name)

View File

@@ -84,16 +84,22 @@ class SwiftUtilsTests(SwiftClientPluginTestCase):
def test_get_temp_url_no_account_key(self): def test_get_temp_url_no_account_key(self):
self.swift_client.url = ("http://fake-host.com:8080/v1/" self.swift_client.url = ("http://fake-host.com:8080/v1/"
"AUTH_demo") "AUTH_demo")
self.swift_client.head_account = mock.Mock(return_value={}) head_account = {}
self.swift_client.post_account = mock.Mock()
self.assertFalse(self.swift_client.post_account.called) def post_account(data):
head_account.update(data)
self.swift_client.head_account = mock.Mock(return_value=head_account)
self.swift_client.post_account = post_account
container_name = '1234' # from stack.id container_name = '1234' # from stack.id
stack_name = 'test' stack_name = 'test'
handle_name = 'foo' handle_name = 'foo'
obj_name = '%s-%s' % (stack_name, handle_name) obj_name = '%s-%s' % (stack_name, handle_name)
self.assertNotIn('x-account-meta-temp-url-key', head_account)
self.swift_plugin.get_temp_url(container_name, obj_name) self.swift_plugin.get_temp_url(container_name, obj_name)
self.assertTrue(self.swift_client.post_account.called) self.assertIn('x-account-meta-temp-url-key', head_account)
def test_get_signal_url(self): def test_get_signal_url(self):
self.swift_client.url = ("http://fake-host.com:8080/v1/" self.swift_client.url = ("http://fake-host.com:8080/v1/"