diff options
author | Steven Hardy <shardy@redhat.com> | 2014-01-15 21:47:52 +0000 |
---|---|---|
committer | Steven Hardy <shardy@redhat.com> | 2014-01-17 11:45:20 +0000 |
commit | 6a051c19817292f4e221759f80d0b298aebbcee1 (patch) | |
tree | f27fcff0c687273b39b4d4df24225c3c61dcc091 | |
parent | 949a2cdc3a4e15b3df56b79473d97c16fda9f422 (diff) | |
download | keystone-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.py | 18 | ||||
-rw-r--r-- | keystone/tests/test_v3_credential.py | 21 |
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']) |