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_sync_user_assignments_multiple_sources_same_role_assignment(self): syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() # Initial state, no roles role_dbs = rbac_service.get_roles_for_user( user_db=self.users['user_2']) self.assertItemsEqual(role_dbs, []) # Do the sync with role defined in separate files assignment1 = UserRoleAssignmentFileFormatAPI( username='******', roles=['role_1'], file_path='assignments/user2a.yaml') assignment2 = UserRoleAssignmentFileFormatAPI( username='******', roles=['role_1'], file_path='assignments/user2b.yaml') syncer.sync_users_role_assignments( role_assignment_apis=[assignment1, assignment2]) role_dbs = rbac_service.get_roles_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0], self.roles['role_1']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_assignment_dbs), 2) sources = [r.source for r in role_assignment_dbs] self.assertIn('assignments/user2a.yaml', sources) self.assertIn('assignments/user2b.yaml', sources) # Do another sync with one assignment file removed - only one assignment should be left syncer.sync_users_role_assignments(role_assignment_apis=[assignment2]) role_dbs = rbac_service.get_roles_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0], self.roles['role_1']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_assignment_dbs), 1) sources = [r.source for r in role_assignment_dbs] self.assertIn('assignments/user2b.yaml', sources)
def test_sync_user_assignments_multiple_custom_roles_assignments(self): syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() # Initial state, no roles role_dbs = rbac_service.get_roles_for_user( user_db=self.users['user_2']) self.assertItemsEqual(role_dbs, []) # Do the sync with two roles defined api = UserRoleAssignmentFileFormatAPI( username='******', roles=['role_1', 'role_2'], file_path='assignments/user2.yaml') syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = rbac_service.get_roles_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['role_1']) self.assertEqual(role_dbs[1], self.roles['role_2']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_2']) self.assertEqual(len(role_assignment_dbs), 2) self.assertEqual(role_assignment_dbs[0].source, 'assignments/user2.yaml') self.assertEqual(role_assignment_dbs[1].source, 'assignments/user2.yaml')
def test_sync_user_assignments_assignments_without_is_remote_are_deleted( self): # Test case which verifies roles without "is_remote" field (pre v2.3) are removed from the # database syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() # Initial state, 4 roles role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_5']) self.assertEqual(len(role_assignment_dbs), 4) # All 3 non remote roles should have been deleted syncer.sync_users_role_assignments(role_assignment_apis=[]) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=self.users['user_5']) self.assertEqual(len(role_assignment_dbs), 1) self.assertEqual(role_assignment_dbs[0].role, 'role_4') self.assertEqual(role_assignment_dbs[0].is_remote, True)
def test_get_role_assignments_for_user(self): # Test a case where a document doesn't exist is_remote field and when it # does user_db = self.users['user_5'] role_assignment_dbs = rbac_service.get_role_assignments_for_user(user_db=user_db, include_remote=False) self.assertEqual(len(role_assignment_dbs), 3) self.assertEqual(role_assignment_dbs[0].role, 'role_1') self.assertEqual(role_assignment_dbs[1].role, 'role_2') self.assertEqual(role_assignment_dbs[2].role, 'role_3') self.assertEqual(role_assignment_dbs[0].is_remote, False) self.assertEqual(role_assignment_dbs[1].is_remote, False) self.assertEqual(role_assignment_dbs[2].is_remote, False) user_db = self.users['user_5'] role_assignment_dbs = rbac_service.get_role_assignments_for_user(user_db=user_db, include_remote=True) self.assertEqual(len(role_assignment_dbs), 4) self.assertEqual(role_assignment_dbs[3].role, 'role_4') self.assertEqual(role_assignment_dbs[3].is_remote, True)
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_sync_assignments_are_removed_user_doesnt_exist_in_db(self): # Make sure that the assignments for the users which don't exist in the db are correctly # removed syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() username = '******' # Initial state, no roles user_db = UserDB(name=username) self.assertEqual(len(User.query(name=username)), 0) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) # Do the sync with two roles defined api = UserRoleAssignmentFileFormatAPI(username=user_db.name, roles=['role_1', 'role_2'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 2) self.assertEqual(role_dbs[0], self.roles['role_1']) self.assertEqual(role_dbs[1], self.roles['role_2']) # Sync with no roles on disk - existing roles should be removed syncer.sync_users_role_assignments(role_assignment_apis=[]) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 0) username = '******' # Initial state, no roles user_db = UserDB(name=username) self.assertEqual(len(User.query(name=username)), 0) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) # Do the sync with three roles defined api = UserRoleAssignmentFileFormatAPI( username=user_db.name, roles=['role_1', 'role_2', 'role_3'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 3) self.assertEqual(role_dbs[0], self.roles['role_1']) self.assertEqual(role_dbs[1], self.roles['role_2']) self.assertEqual(role_dbs[2], self.roles['role_3']) role_assignment_dbs = rbac_service.get_role_assignments_for_user( user_db=user_db) self.assertEqual(len(role_assignment_dbs), 3) self.assertEqual(role_assignment_dbs[0].source, 'assignments/%s.yaml' % user_db.name) # Sync with one role on disk - two roles should be removed api = UserRoleAssignmentFileFormatAPI(username=user_db.name, roles=['role_3'], file_path='assignments/%s.yaml' % user_db.name) syncer.sync_users_role_assignments(role_assignment_apis=[api]) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertEqual(len(role_dbs), 1) self.assertEqual(role_dbs[0], self.roles['role_3'])