def test_sync_no_mappings_exist_for_the_provided_groups(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_remote_role_3" and "mock_remote_role_4" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_3', 'mock_remote_role_4'], source='mappings/stormers.yaml') # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) groups = [ 'CN=testers1,OU=groups,DC=stackstorm,DC=net', 'CN=testers2,OU=groups,DC=stackstorm,DC=net' ] # No mappings exist for the groups user is a member of so no new assignments should be # created result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(created_role_assignment_dbs, []) self.assertEqual(removed_role_assignment_dbs, [])
def test_sync_success_one_existing_remote_assignment(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_remote_role_3" and "mock_remote_role_4" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_3', 'mock_remote_role_4'], source='mappings/stormers.yaml') # Assign existing remote mock_role_5 to the user role_db = self.roles['mock_role_5'] source = 'mappings/stormers.yaml' rbac_service.assign_role_to_user(role_db=role_db, user_db=user_db, source=source, is_remote=True) # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 3) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_role_5']) groups = [ 'CN=stormers,OU=groups,DC=stackstorm,DC=net', 'CN=testers,OU=groups,DC=stackstorm,DC=net' ] result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(created_role_assignment_dbs[1].role, 'mock_remote_role_4') self.assertEqual(len(removed_role_assignment_dbs), 1) self.assertEqual(removed_role_assignment_dbs[0].role, 'mock_role_5') # User should have two new roles assigned now, but the existing "mock_role_5" remote role # removed since it wasn't specified in any mapping role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 4) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3']) self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4'])
def test_sync_success_no_existing_remote_assignments(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_remote_role_3" and "mock_remote_role_4" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_3', 'mock_remote_role_4'], source='mappings/stormers.yaml') # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_1']) groups = [ 'CN=stormers,OU=groups,DC=stackstorm,DC=net', 'CN=testers,OU=groups,DC=stackstorm,DC=net', # We repeat the same group to validate that repated groups are correctly de-duplicated 'CN=stormers,OU=groups,DC=stackstorm,DC=net', ] result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(created_role_assignment_dbs[1].role, 'mock_remote_role_4') self.assertEqual(removed_role_assignment_dbs, []) # User should have two new roles assigned now role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 4) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3']) self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_1']) self.assertEqual(len(role_assignment_dbs), 4) self.assertEqual(role_assignment_dbs[2].source, 'mappings/stormers.yaml') self.assertEqual(role_assignment_dbs[3].source, 'mappings/stormers.yaml')
def test_group_to_role_sync_is_performed_on_successful_auth_with_groups_and_mappings( self): # Enable group sync cfg.CONF.set_override(group='rbac', name='sync_remote_groups', override=True) user_db = self.users['user_1'] h = handlers.StandaloneAuthHandler() request = {} # Single mapping, new remote assignment should be created rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_role_3', 'mock_role_4'], source='mappings/stormers.yaml') # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) h._auth_backend.groups = ['CN=stormers,OU=groups,DC=stackstorm,DC=net'] token = h.handle_auth(request, headers={}, remote_addr=None, remote_user=None, authorization=('basic', DUMMY_CREDS)) self.assertEqual(token.user, 'auser') # Verify a new role assignments based on the group mapping has been created role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 4) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_role_3']) self.assertEqual(role_dbs[3], self.roles['mock_role_4'])
def sync_group_to_role_maps(self, group_to_role_map_apis): LOG.info('Synchronizing group to role maps...') # Retrieve all the mappings currently in the db group_to_role_map_dbs = rbac_service.get_all_group_to_role_maps() # 1. Delete all the existing mappings in the db group_to_role_map_to_delete = [] for group_to_role_map_db in group_to_role_map_dbs: group_to_role_map_to_delete.append(group_to_role_map_db.id) GroupToRoleMapping.query(id__in=group_to_role_map_to_delete).delete() # 2. Insert all mappings read from disk for group_to_role_map_api in group_to_role_map_apis: source = getattr(group_to_role_map_api, 'file_path', None) rbac_service.create_group_to_role_map(group=group_to_role_map_api.group, roles=group_to_role_map_api.roles, description=group_to_role_map_api.description, enabled=group_to_role_map_api.enabled, source=source) LOG.info('Group to role map definitions synchronized.')
def test_sync_success_one_mapping_is_disabled_on_second_sync_run(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_remote_role_3" and CN=testers,OU=groups,DC=stackstorm,DC=net to # "mock_remote_role_4" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_3'], source='mappings/stormers.yaml', enabled=True) rbac_service.create_group_to_role_map( group='CN=testers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_4'], source='mappings/testers.yaml', enabled=True) # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) groups = [ 'CN=stormers,OU=groups,DC=stackstorm,DC=net', 'CN=testers,OU=groups,DC=stackstorm,DC=net' ] # Two new remote assignments should have been created # No mappings exist for the groups user is a member of so no new assignments should be # created result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(created_role_assignment_dbs[1].role, 'mock_remote_role_4') self.assertEqual(removed_role_assignment_dbs, []) # Verify post sync run state - two new assignments should have been created role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 4) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3']) self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4']) # Disable second mapping - one assignment should be removed mapping_db = GroupToRoleMapping.get( group='CN=testers,OU=groups,DC=stackstorm,DC=net') mapping_db.enabled = False GroupToRoleMapping.add_or_update(mapping_db) result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 1) self.assertEqual(len(removed_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(removed_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(removed_role_assignment_dbs[1].role, 'mock_remote_role_4') # Verify post sync run state - mock_remote_role_4 assignment should be removed role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 3) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3'])
def test_sync_user_same_role_granted_locally_and_remote_via_mapping(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_6'] # Insert 2 local assignments for mock_role_7 role_db = rbac_service.create_role(name='mock_role_7') source = 'assignments/user_6_one.yaml' rbac_service.assign_role_to_user(role_db=role_db, user_db=user_db, source=source, is_remote=False) source = 'assignments/user_6_two.yaml' rbac_service.assign_role_to_user(role_db=role_db, user_db=user_db, source=source, is_remote=False) # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_role_7" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_role_7'], source='mappings/stormers.yaml') # Create mock mapping which maps CN=testers,OU=groups,DC=stackstorm,DC=net # to "mock_role_7" rbac_service.create_group_to_role_map( group='CN=testers,OU=groups,DC=stackstorm,DC=net', roles=['mock_role_7'], source='mappings/testers.yaml') groups = [ 'CN=stormers,OU=groups,DC=stackstorm,DC=net', 'CN=testers,OU=groups,DC=stackstorm,DC=net' ] result = syncer.sync(user_db=self.users['user_6'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_role_7') self.assertEqual(created_role_assignment_dbs[1].role, 'mock_role_7') self.assertEqual(removed_role_assignment_dbs, []) # There should be one role and 4 assignments for the same role role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0].name, 'mock_role_7') role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_6']) self.assertEqual(len(role_assignment_dbs), 4) self.assertEqual(role_assignment_dbs[0].source, 'assignments/user_6_one.yaml') self.assertEqual(role_assignment_dbs[1].source, 'assignments/user_6_two.yaml') self.assertEqual(role_assignment_dbs[2].source, 'mappings/stormers.yaml') self.assertEqual(role_assignment_dbs[3].source, 'mappings/testers.yaml') # Remove one remote group - should be 3 left groups = ['CN=stormers,OU=groups,DC=stackstorm,DC=net'] result = syncer.sync(user_db=self.users['user_6'], groups=groups) role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0].name, 'mock_role_7') role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_6']) self.assertEqual(len(role_assignment_dbs), 3)
def test_no_mappings_in_db_old_mappings_are_deleted(self): # Test case which verifies that existing / old mappings are deleted from db if no mappings # exist on disk for a particular set of groups. syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net # to "mock_remote_role_3" and CN=testers,OU=groups,DC=stackstorm,DC=net to # "mock_remote_role_4" rbac_service.create_group_to_role_map( group='CN=stormers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_3'], source='mappings/stormers.yaml', enabled=True) rbac_service.create_group_to_role_map( group='CN=testers,OU=groups,DC=stackstorm,DC=net', roles=['mock_remote_role_4'], source='mappings/testers.yaml', enabled=True) # Verify initial state role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) groups = [ 'CN=stormers,OU=groups,DC=stackstorm,DC=net', 'CN=testers,OU=groups,DC=stackstorm,DC=net' ] # Two new remote assignments should have been created # No mappings exist for the groups user is a member of so no new assignments should be # created result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(len(created_role_assignment_dbs), 2) self.assertEqual(created_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(created_role_assignment_dbs[1].role, 'mock_remote_role_4') self.assertEqual(removed_role_assignment_dbs, []) # Verify post sync run state - two new assignments should have been created role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 4) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2']) self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3']) self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4']) # Delete all existing mappings, make sure all old assignments are deleted on sync GroupToRoleMapping.query(group__in=groups).delete() self.assertEqual(len(GroupToRoleMapping.query(group__in=groups)), 0) result = syncer.sync(user_db=self.users['user_1'], groups=groups) created_role_assignment_dbs = result[0] removed_role_assignment_dbs = result[1] self.assertEqual(created_role_assignment_dbs, []) self.assertEqual(len(removed_role_assignment_dbs), 2) self.assertEqual(removed_role_assignment_dbs[0].role, 'mock_remote_role_3') self.assertEqual(removed_role_assignment_dbs[1].role, 'mock_remote_role_4') # Verify post sync run state - two old remote assignments should have been deleted, but # local assignments shouldn't have been touched role_dbs = rbac_service.get_roles_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['mock_local_role_1']) self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])