diff --git a/keystone/federation/utils.py b/keystone/federation/utils.py index c62979fa08..da0a25c1f0 100644 --- a/keystone/federation/utils.py +++ b/keystone/federation/utils.py @@ -500,6 +500,9 @@ class RuleProcessor(object): 'domain': { 'name': 'default_domain' } + }, + { + 'group_ids': ['abc123', 'def456', '0cd5e9'] } ] @@ -571,6 +574,17 @@ class RuleProcessor(object): group_names_list] group_names.extend(group_dicts) + if 'group_ids' in identity_value: + # If identity_values['group_ids'] is a string representation + # of a list, parse it to a real list. Also, if the provided + # group_ids parameter contains only one element, it will be + # parsed as a simple string, and not a list or the + # representation of a list. + try: + group_ids.update( + ast.literal_eval(identity_value['group_ids'])) + except (ValueError, SyntaxError): + group_ids.update([identity_value['group_ids']]) normalize_user(user) diff --git a/keystone/tests/unit/contrib/federation/test_utils.py b/keystone/tests/unit/contrib/federation/test_utils.py index dbd09f2a83..58ef487cd6 100644 --- a/keystone/tests/unit/contrib/federation/test_utils.py +++ b/keystone/tests/unit/contrib/federation/test_utils.py @@ -620,3 +620,52 @@ class MappingRuleEngineTests(unit.BaseTestCase): self.assertNotIn('id', mapped_properties['user']) self.assertNotIn('name', mapped_properties['user']) + + def test_rule_engine_group_ids_mapping_whitelist(self): + """Test mapping engine when group_ids is explicitly set + + Also test whitelists on group ids + + """ + mapping = mapping_fixtures.MAPPING_GROUPS_IDS_WHITELIST + assertion = mapping_fixtures.GROUP_IDS_ASSERTION + rp = mapping_utils.RuleProcessor(mapping['rules']) + mapped_properties = rp.process(assertion) + self.assertIsNotNone(mapped_properties) + self.assertEqual('opilotte', mapped_properties['user']['name']) + self.assertListEqual([], mapped_properties['group_names']) + self.assertItemsEqual(['abc123', 'ghi789', 'klm012'], + mapped_properties['group_ids']) + + def test_rule_engine_group_ids_mapping_blacklist(self): + """Test mapping engine when group_ids is explicitly set. + + Also test blacklists on group ids + + """ + mapping = mapping_fixtures.MAPPING_GROUPS_IDS_BLACKLIST + assertion = mapping_fixtures.GROUP_IDS_ASSERTION + rp = mapping_utils.RuleProcessor(mapping['rules']) + mapped_properties = rp.process(assertion) + self.assertIsNotNone(mapped_properties) + self.assertEqual('opilotte', mapped_properties['user']['name']) + self.assertListEqual([], mapped_properties['group_names']) + self.assertItemsEqual(['abc123', 'ghi789', 'klm012'], + mapped_properties['group_ids']) + + def test_rule_engine_group_ids_mapping_only_one_group(self): + """Test mapping engine when group_ids is explicitly set. + + If the group ids list has only one group, + test if the transformation is done correctly + + """ + mapping = mapping_fixtures.MAPPING_GROUPS_IDS_WHITELIST + assertion = mapping_fixtures.GROUP_IDS_ASSERTION_ONLY_ONE_GROUP + rp = mapping_utils.RuleProcessor(mapping['rules']) + mapped_properties = rp.process(assertion) + self.assertIsNotNone(mapped_properties) + self.assertEqual('opilotte', mapped_properties['user']['name']) + self.assertListEqual([], mapped_properties['group_names']) + self.assertItemsEqual(['210mlk', '321cba'], + mapped_properties['group_ids']) diff --git a/keystone/tests/unit/mapping_fixtures.py b/keystone/tests/unit/mapping_fixtures.py index 94b0713359..f8adb00e08 100644 --- a/keystone/tests/unit/mapping_fixtures.py +++ b/keystone/tests/unit/mapping_fixtures.py @@ -1036,6 +1036,78 @@ MAPPING_WITH_DOMAINID_ONLY = { ] } +MAPPING_GROUPS_IDS_WHITELIST = { + "rules": [ + { + "local": [ + { + "user": { + "name": "{0}" + } + }, + { + "group_ids": "{1}" + }, + { + "group": { + "id": "{2}" + } + } + ], + "remote": [ + { + "type": "name" + }, + { + "type": "group_ids", + "whitelist": [ + "abc123", "ghi789", "321cba" + ] + }, + { + "type": "group" + } + ] + } + ] +} + +MAPPING_GROUPS_IDS_BLACKLIST = { + "rules": [ + { + "local": [ + { + "user": { + "name": "{0}" + } + }, + { + "group_ids": "{1}" + }, + { + "group": { + "id": "{2}" + } + } + ], + "remote": [ + { + "type": "name" + }, + { + "type": "group_ids", + "blacklist": [ + "def456" + ] + }, + { + "type": "group" + } + ] + } + ] +} + # Mapping used by tokenless test cases, it maps the domain_name only. MAPPING_WITH_DOMAINNAME_ONLY = { 'rules': [ @@ -1184,7 +1256,6 @@ MAPPING_GROUPS_WHITELIST_PASS_THROUGH = { ] } - EMPLOYEE_ASSERTION = { 'Email': 'tim@example.com', 'UserName': 'tbo', @@ -1310,3 +1381,15 @@ UNMATCHED_GROUP_ASSERTION = { 'REMOTE_USER': 'Any Momoose', 'REMOTE_USER_GROUPS': 'EXISTS;NO_EXISTS' } + +GROUP_IDS_ASSERTION = { + 'name': 'opilotte', + 'group_ids': 'abc123;def456;ghi789', + 'group': 'klm012' +} + +GROUP_IDS_ASSERTION_ONLY_ONE_GROUP = { + 'name': 'opilotte', + 'group_ids': '321cba', + 'group': '210mlk' +}