From f5f1caf9e9e4dc0d916fc48b32a408f477a87829 Mon Sep 17 00:00:00 2001 From: Lance Bragstad Date: Thu, 28 May 2015 13:45:13 +0000 Subject: [PATCH] Don't assume project IDs are UUID format Since Keystone has the ability to be deployed with an LDAP backend, we can't guarantee that project IDs will always be UUID formatted. That change makes it so that we attempt to convert project IDs to bytes before packing and if we fail, pass the original project ID into the payload at the expense of a slightly longer payload. Change-Id: Id81ed23879ee7a9adeb50454ef0cb7acd13f1a0a Related-Bug: 1459382 --- .../tests/unit/token/test_fernet_provider.py | 42 +++++++++++++++++++ .../providers/fernet/token_formatters.py | 8 ++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/keystone/tests/unit/token/test_fernet_provider.py b/keystone/tests/unit/token/test_fernet_provider.py index e23164d58a..3c2d32d0bd 100644 --- a/keystone/tests/unit/token/test_fernet_provider.py +++ b/keystone/tests/unit/token/test_fernet_provider.py @@ -219,6 +219,26 @@ class TestPayloads(tests.TestCase): self.assertEqual(exp_expires_at, expires_at) self.assertEqual(exp_audit_ids, audit_ids) + def test_project_scoped_payload_with_non_uuid_project_id(self): + exp_user_id = uuid.uuid4().hex + exp_methods = ['password'] + exp_project_id = 'someNonUuidProjectId' + exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_audit_ids = [provider.random_urlsafe_str()] + + payload = token_formatters.ProjectScopedPayload.assemble( + exp_user_id, exp_methods, exp_project_id, exp_expires_at, + exp_audit_ids) + + (user_id, methods, project_id, expires_at, audit_ids) = ( + token_formatters.ProjectScopedPayload.disassemble(payload)) + + self.assertEqual(exp_user_id, user_id) + self.assertEqual(exp_methods, methods) + self.assertEqual(exp_project_id, project_id) + self.assertEqual(exp_expires_at, expires_at) + self.assertEqual(exp_audit_ids, audit_ids) + def test_domain_scoped_payload_with_non_uuid_user_id(self): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] @@ -261,6 +281,28 @@ class TestPayloads(tests.TestCase): self.assertEqual(exp_audit_ids, audit_ids) self.assertEqual(exp_trust_id, trust_id) + def test_trust_scoped_payload_with_non_uuid_project_id(self): + exp_user_id = uuid.uuid4().hex + exp_methods = ['password'] + exp_project_id = 'someNonUuidProjectId' + exp_expires_at = timeutils.isotime(timeutils.utcnow()) + exp_audit_ids = [provider.random_urlsafe_str()] + exp_trust_id = uuid.uuid4().hex + + payload = token_formatters.TrustScopedPayload.assemble( + exp_user_id, exp_methods, exp_project_id, exp_expires_at, + exp_audit_ids, exp_trust_id) + + (user_id, methods, project_id, expires_at, audit_ids, trust_id) = ( + token_formatters.TrustScopedPayload.disassemble(payload)) + + self.assertEqual(exp_user_id, user_id) + self.assertEqual(exp_methods, methods) + self.assertEqual(exp_project_id, project_id) + self.assertEqual(exp_expires_at, expires_at) + self.assertEqual(exp_audit_ids, audit_ids) + self.assertEqual(exp_trust_id, trust_id) + def test_federated_payload_with_non_uuid_ids(self): exp_user_id = 'someNonUuidUserId' exp_methods = ['password'] diff --git a/keystone/token/providers/fernet/token_formatters.py b/keystone/token/providers/fernet/token_formatters.py index 248642c8e5..ce684bff9a 100644 --- a/keystone/token/providers/fernet/token_formatters.py +++ b/keystone/token/providers/fernet/token_formatters.py @@ -414,7 +414,7 @@ class ProjectScopedPayload(BasePayload): """ b_user_id = cls.attempt_convert_uuid_hex_to_bytes(user_id) methods = auth_plugins.convert_method_list_to_integer(methods) - b_project_id = cls.convert_uuid_hex_to_bytes(project_id) + b_project_id = cls.attempt_convert_uuid_hex_to_bytes(project_id) expires_at_int = cls._convert_time_string_to_int(expires_at) b_audit_ids = list(map(provider.random_urlsafe_str_to_bytes, audit_ids)) @@ -431,7 +431,7 @@ class ProjectScopedPayload(BasePayload): """ user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0]) methods = auth_plugins.convert_integer_to_method_list(payload[1]) - project_id = cls.convert_uuid_bytes_to_hex(payload[2]) + project_id = cls.attempt_convert_uuid_bytes_to_hex(payload[2]) expires_at_str = cls._convert_int_to_time_string(payload[3]) audit_ids = list(map(provider.base64_encode, payload[4])) @@ -457,7 +457,7 @@ class TrustScopedPayload(BasePayload): """ b_user_id = cls.attempt_convert_uuid_hex_to_bytes(user_id) methods = auth_plugins.convert_method_list_to_integer(methods) - b_project_id = cls.convert_uuid_hex_to_bytes(project_id) + b_project_id = cls.attempt_convert_uuid_hex_to_bytes(project_id) b_trust_id = cls.convert_uuid_hex_to_bytes(trust_id) expires_at_int = cls._convert_time_string_to_int(expires_at) b_audit_ids = list(map(provider.random_urlsafe_str_to_bytes, @@ -477,7 +477,7 @@ class TrustScopedPayload(BasePayload): """ user_id = cls.attempt_convert_uuid_bytes_to_hex(payload[0]) methods = auth_plugins.convert_integer_to_method_list(payload[1]) - project_id = cls.convert_uuid_bytes_to_hex(payload[2]) + project_id = cls.attempt_convert_uuid_bytes_to_hex(payload[2]) expires_at_str = cls._convert_int_to_time_string(payload[3]) audit_ids = list(map(provider.base64_encode, payload[4])) trust_id = cls.convert_uuid_bytes_to_hex(payload[5])