summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Hardy <shardy@redhat.com>2014-01-15 21:47:52 +0000
committerSteven Hardy <shardy@redhat.com>2014-01-17 11:45:20 +0000
commit6a051c19817292f4e221759f80d0b298aebbcee1 (patch)
treef27fcff0c687273b39b4d4df24225c3c61dcc091
parent949a2cdc3a4e15b3df56b79473d97c16fda9f422 (diff)
downloadkeystone-6a051c19817292f4e221759f80d0b298aebbcee1.tar.gz
v3 credentials, ensure blob response is json
The v3/credentials API specifies the blob response to be json, but due to bug #1259584, any credentials stored via the ec2tokens extension will incorrectly return a dict. This makes it hard for clients (and in particular users migrating from ec2tokens to v3/credentials) to handle the blob data consistently, so add a workaround to ensure the response is always serialized as json if the existing DB contents is a dict instead of a json string. Change-Id: I340cdf4e565fdadacb41b39acace3948aafb9b92 Related-Bug: #1259584 Closes-Bug: #1269637
-rw-r--r--keystone/credential/controllers.py18
-rw-r--r--keystone/tests/test_v3_credential.py21
2 files changed, 37 insertions, 2 deletions
diff --git a/keystone/credential/controllers.py b/keystone/credential/controllers.py
index 8d63933ca..de9752dc8 100644
--- a/keystone/credential/controllers.py
+++ b/keystone/credential/controllers.py
@@ -66,15 +66,29 @@ class CredentialV3(controller.V3Controller):
ref = self.credential_api.create_credential(ref['id'], ref)
return CredentialV3.wrap_member(context, ref)
+ @staticmethod
+ def _blob_to_json(ref):
+ # credentials stored via ec2tokens before the fix for #1259584
+ # need json serializing, as that's the documented API format
+ blob = ref.get('blob')
+ if isinstance(blob, dict):
+ new_ref = ref.copy()
+ new_ref['blob'] = json.dumps(blob)
+ return new_ref
+ else:
+ return ref
+
@controller.protected()
def list_credentials(self, context):
refs = self.credential_api.list_credentials()
- return CredentialV3.wrap_collection(context, refs)
+ ret_refs = [self._blob_to_json(r) for r in refs]
+ return CredentialV3.wrap_collection(context, ret_refs)
@controller.protected()
def get_credential(self, context, credential_id):
ref = self.credential_api.get_credential(credential_id)
- return CredentialV3.wrap_member(context, ref)
+ ret_ref = self._blob_to_json(ref)
+ return CredentialV3.wrap_member(context, ret_ref)
@controller.protected()
def update_credential(self, context, credential_id, credential):
diff --git a/keystone/tests/test_v3_credential.py b/keystone/tests/test_v3_credential.py
index a9735075b..a2a5bd281 100644
--- a/keystone/tests/test_v3_credential.py
+++ b/keystone/tests/test_v3_credential.py
@@ -142,6 +142,27 @@ class CredentialTestCase(CredentialBaseTestCase):
'/credentials',
body={'credential': ref}, expected_status=409)
+ def test_get_ec2_dict_blob(self):
+ """Ensure non-JSON blob data is correctly converted."""
+ expected_blob, credential_id = self._create_dict_blob_credential()
+
+ r = self.get(
+ '/credentials/%(credential_id)s' % {
+ 'credential_id': credential_id})
+ self.assertEqual(expected_blob, r.result['credential']['blob'])
+
+ def test_list_ec2_dict_blob(self):
+ """Ensure non-JSON blob data is correctly converted."""
+ expected_blob, credential_id = self._create_dict_blob_credential()
+
+ list_r = self.get('/credentials')
+ list_creds = list_r.result['credentials']
+ list_ids = [r['id'] for r in list_creds]
+ self.assertIn(credential_id, list_ids)
+ for r in list_creds:
+ if r['id'] == credential_id:
+ self.assertEqual(expected_blob, r['blob'])
+
def test_create_non_ec2_credential(self):
"""Call ``POST /credentials`` for creating non-ec2 credential."""
ref = self.new_credential_ref(user_id=self.user['id'])