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_group_to_role_sync_is_performed_on_successful_auth_no_groups_returned( 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 = {} # 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']) # No groups configured should return early h._auth_backend.groups = [] token = h.handle_auth(request, headers={}, remote_addr=None, remote_user=None, authorization=('basic', DUMMY_CREDS)) self.assertEqual(token.user, 'auser') # Verify nothing has changed 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'])
def test_assign_role_to_user_ignore_already_exists_error(self): user_db = UserDB(name='test-user-10') user_db = User.add_or_update(user_db) role_assignment_db_1 = rbac_service.assign_role_to_user( role_db=self.roles['custom_role_1'], user_db=user_db, source='assignments/%s_10.yaml' % user_db.name) # 1. Without ignore errors self.assertRaises(StackStormDBObjectConflictError, rbac_service.assign_role_to_user, role_db=self.roles['custom_role_1'], user_db=user_db, source='assignments/%s_10.yaml' % user_db.name) # 2. With ignore errors role_assignment_db_2 = rbac_service.assign_role_to_user( role_db=self.roles['custom_role_1'], user_db=user_db, source='assignments/%s_10.yaml' % user_db.name, ignore_already_exists_error=True) self.assertEqual(role_assignment_db_1, role_assignment_db_2) self.assertEqual(role_assignment_db_1.id, role_assignment_db_2.id) self.assertEqual(role_assignment_db_1.user, role_assignment_db_2.user) self.assertEqual(role_assignment_db_1.role, role_assignment_db_2.role)
def _insert_mock_roles(self): # Create some mock roles role_1_db = rbac_service.create_role(name='role_1') role_2_db = rbac_service.create_role(name='role_2') role_3_db = rbac_service.create_role(name='role_3') self.roles['role_1'] = role_1_db self.roles['role_2'] = role_2_db self.roles['role_3'] = role_3_db # Note: User use pymongo to insert mock data because we want to insert a # raw document and skip mongoengine to leave is_remote field unpopulated client = MongoClient() db = client['st2-test'] db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_1' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_2' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_3', 'is_remote': False }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_4', 'is_remote': True }) return self.roles
def test_sync_role_assignments_no_assignment_file_on_disk(self): syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() # Initial state, no roles user_db = self.users['user_3'] 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']) # Do the sync with no roles - existing assignments should be removed from the databse 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)
def test_get_roles_for_user(self): # User with no roles user_db = self.users['no_roles'] role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, []) # User with one custom role user_db = self.users['1_custom_role'] role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) # User with remote roles user_db = self.users['user_5'] role_dbs = user_db.get_roles() self.assertEqual(len(role_dbs), 4) user_db = self.users['user_5'] role_dbs = user_db.get_roles(include_remote=True) self.assertEqual(len(role_dbs), 4) user_db = self.users['user_5'] role_dbs = user_db.get_roles(include_remote=False) self.assertEqual(len(role_dbs), 3)
def test_sync_assignments_user_doesnt_exist_in_db(self): # Make sure that the assignments for the users which don't exist in the db are still saved 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/foobar.yaml') 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'])
def test_get_all_permission_grants_for_user(self): user_db = self.users['1_custom_role'] role_db = self.roles['custom_role_1'] permission_grants = rbac_service.get_all_permission_grants_for_user( user_db=user_db) self.assertItemsEqual(permission_grants, []) # Grant some permissions resource_db = self.resources['rule_1'] permission_types = [ PermissionType.RULE_CREATE, PermissionType.RULE_MODIFY ] permission_grant = rbac_service.create_permission_grant_for_resource_db( role_db=role_db, resource_db=resource_db, permission_types=permission_types) # Retrieve all grants permission_grants = rbac_service.get_all_permission_grants_for_user( user_db=user_db) self.assertItemsEqual(permission_grants, [permission_grant]) # Retrieve all grants, filter on resource with no grants permission_grants = rbac_service.get_all_permission_grants_for_user( user_db=user_db, resource_types=[ResourceType.PACK]) self.assertItemsEqual(permission_grants, []) # Retrieve all grants, filter on resource with grants permission_grants = rbac_service.get_all_permission_grants_for_user( user_db=user_db, resource_types=[ResourceType.RULE]) self.assertItemsEqual(permission_grants, [permission_grant])
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_get_all_role_assignments(self): role_assignment_dbs = rbac_service.get_all_role_assignments( include_remote=True) self.assertEqual(len(role_assignment_dbs), 5) role_assignment_dbs = rbac_service.get_all_role_assignments( include_remote=False) self.assertEqual(len(role_assignment_dbs), 4) for role_assignment_db in role_assignment_dbs: self.assertFalse(role_assignment_db.is_remote)
def test_insert_system_roles(self): role_dbs = rbac_service.get_all_roles() self.assertItemsEqual(role_dbs, []) insert_system_roles() role_dbs = rbac_service.get_all_roles() self.assertTrue(len(role_dbs), 3) role_names = [role_db.name for role_db in role_dbs] self.assertTrue('system_admin' in role_names) self.assertTrue('admin' in role_names) self.assertTrue('observer' in role_names)
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_remote_assignments_are_not_manipulated(self): # Verify remote assignments are not manipulated. syncer = RBACDefinitionsDBSyncer() self._insert_mock_roles() # Initial state, no roles user_db = UserDB(name='doesntexistwhaha') role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) # Create mock remote role assignment role_db = self.roles['role_3'] source = 'assignments/%s.yaml' % user_db.name role_assignment_db = rbac_service.assign_role_to_user(role_db=role_db, user_db=user_db, source=source, is_remote=True) self.assertTrue(role_assignment_db.is_remote) # Verify assignment has been created role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, [self.roles['role_3']]) # Do the sync with two roles defined - verify remote role assignment hasn't been # manipulated with. 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), 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']) # Do sync with no roles - verify all roles except remote one are removed. api = UserRoleAssignmentFileFormatAPI(username=user_db.name, roles=[], 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'])
def test_grant_and_revoke_role(self): user_db = UserDB(name='test-user-1') user_db = User.add_or_update(user_db) # Initial state, no roles role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, []) # Assign a role, should have one role assigned rbac_service.assign_role_to_user(role_db=self.roles['custom_role_1'], user_db=user_db, source='assignments/%s.yaml' % user_db.name) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']]) # Revoke previously assigned role, should have no roles again rbac_service.revoke_role_from_user(role_db=self.roles['custom_role_1'], user_db=user_db) role_dbs = rbac_service.get_roles_for_user(user_db=user_db) self.assertItemsEqual(role_dbs, []) role_dbs = user_db.get_roles() self.assertItemsEqual(role_dbs, [])
def setUp(self): super(RBACRemoteGroupToRoleSyncerTestCase, self).setUp() self.roles = {} self.role_assignments = {} # Insert mock local role assignments role_db = rbac_service.create_role(name='mock_local_role_1') user_db = self.users['user_1'] source = 'assignments/%s.yaml' % user_db.name role_assignment_db_1 = rbac_service.assign_role_to_user( role_db=role_db, user_db=user_db, source=source, is_remote=False) self.roles['mock_local_role_1'] = role_db self.role_assignments['assignment_1'] = role_assignment_db_1 role_db = rbac_service.create_role(name='mock_local_role_2') user_db = self.users['user_1'] source = 'assignments/%s.yaml' % user_db.name role_assignment_db_2 = rbac_service.assign_role_to_user( role_db=role_db, user_db=user_db, source=source, is_remote=False) self.roles['mock_local_role_2'] = role_db self.role_assignments['assignment_2'] = role_assignment_db_2 role_db = rbac_service.create_role(name='mock_remote_role_3') self.roles['mock_remote_role_3'] = role_db role_db = rbac_service.create_role(name='mock_remote_role_4') self.roles['mock_remote_role_4'] = role_db role_db = rbac_service.create_role(name='mock_role_5') self.roles['mock_role_5'] = role_db
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 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_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_sync_no_groups_and_on_disk_definitions(self): syncer = RBACRemoteGroupToRoleSyncer() user_db = self.users['user_1'] # 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']) # No groups - should result in no new remote assignments but existing local assignments # shouldn't be manipulated result = syncer.sync(user_db=self.users['user_1'], 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, []) 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 but no mapping to role definitions, should result in no new remote assignments groups = ['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(created_role_assignment_dbs, []) self.assertEqual(removed_role_assignment_dbs, []) 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'])
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_create_and_remove_permission_grant(self): role_db = self.roles['custom_role_2'] resource_db = self.resources['rule_1'] # Grant "ALL" permission to the resource permission_types = [PermissionType.RULE_ALL] rbac_service.create_permission_grant_for_resource_db( role_db=role_db, resource_db=resource_db, permission_types=permission_types) role_db.reload() self.assertItemsEqual(role_db.permission_grants, role_db.permission_grants) # Remove the previously granted permission rbac_service.remove_permission_grant_for_resource_db( role_db=role_db, resource_db=resource_db, permission_types=permission_types) role_db.reload() self.assertItemsEqual(role_db.permission_grants, [])
def test_sync_user_assignments_locally_removed_assignments_are_removed_from_db( 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']) # Do the sync with one role defined (one should be removed from the db) api = UserRoleAssignmentFileFormatAPI( username='******', roles=['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), 1) self.assertEqual(role_dbs[0], self.roles['role_2'])
def _insert_common_mock_roles(self): # Insert common mock roles admin_role_db = rbac_service.get_role_by_name(name=SystemRole.ADMIN) observer_role_db = rbac_service.get_role_by_name( name=SystemRole.OBSERVER) self.roles['admin_role'] = admin_role_db self.roles['observer_role'] = observer_role_db # Custom role 1 - no grants role_1_db = rbac_service.create_role(name='custom_role_1') self.roles['custom_role_1'] = role_1_db # Custom role 2 - one grant on pack_1 # "pack_create" on pack_1 grant_db = PermissionGrantDB( resource_uid=self.resources['pack_1'].get_uid(), resource_type=ResourceType.PACK, permission_types=[PermissionType.PACK_CREATE]) grant_db = PermissionGrant.add_or_update(grant_db) permission_grants = [str(grant_db.id)] role_3_db = RoleDB(name='custom_role_pack_grant', permission_grants=permission_grants) role_3_db = Role.add_or_update(role_3_db) self.roles['custom_role_pack_grant'] = role_3_db
def setUp(self): super(AuthHandlerRBACRoleSyncTestCase, self).setUp() cfg.CONF.set_override(group='auth', name='backend', override='mock') cfg.CONF.set_override(group='rbac', name='backend', override='enterprise') self.users = {} self.roles = {} self.role_assignments = {} # Insert some mock users user_1_db = UserDB(name='auser') user_1_db = User.add_or_update(user_1_db) self.users['user_1'] = user_1_db user_2_db = UserDB(name='buser') user_2_db = User.add_or_update(user_2_db) self.users['user_2'] = user_2_db # Insert mock local role assignments role_db = rbac_service.create_role(name='mock_local_role_1') user_db = self.users['user_1'] source = 'assignments/%s.yaml' % user_db.name role_assignment_db_1 = rbac_service.assign_role_to_user( role_db=role_db, user_db=user_db, source=source, is_remote=False) self.roles['mock_local_role_1'] = role_db self.role_assignments['assignment_1'] = role_assignment_db_1 role_db = rbac_service.create_role(name='mock_local_role_2') user_db = self.users['user_1'] source = 'assignments/%s.yaml' % user_db.name role_assignment_db_2 = rbac_service.assign_role_to_user( role_db=role_db, user_db=user_db, source=source, is_remote=False) self.roles['mock_local_role_2'] = role_db self.role_assignments['assignment_2'] = role_assignment_db_2 role_db = rbac_service.create_role(name='mock_role_3') self.roles['mock_role_3'] = role_db role_db = rbac_service.create_role(name='mock_role_4') self.roles['mock_role_4'] = role_db role_db = rbac_service.create_role(name='mock_role_5') self.roles['mock_role_5'] = role_db
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_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 user_has_role(user_db, role): """ :param user: User object to check for. :type user: :class:`UserDB` :param role: Role name to check for. :type role: ``str`` :rtype: ``bool`` """ assert isinstance(role, six.string_types) if not cfg.CONF.rbac.enable: return True user_role_dbs = rbac_service.get_roles_for_user(user_db=user_db) user_role_names = [role_db.name for role_db in user_role_dbs] return role in user_role_names
def test_sync_user_assignments_role_doesnt_exist_in_db(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=['doesnt_exist'], file_path='assignments/user2.yaml') expected_msg = ('Role "doesnt_exist" referenced in assignment file ' '"assignments/user2.yaml" doesn\'t exist') self.assertRaisesRegexp(ValueError, expected_msg, syncer.sync_users_role_assignments, role_assignment_apis=[assignment1])
def setUp(self): super(RBACServiceTestCase, self).setUp() # Make sure RBAC is enabeld cfg.CONF.set_override(name='enable', override=True, group='rbac') cfg.CONF.set_override(name='backend', override='enterprise', group='rbac') # TODO: Share mocks self.users = {} self.roles = {} self.resources = {} # Create some mock users user_1_db = UserDB(name='admin') user_1_db = User.add_or_update(user_1_db) self.users['admin'] = user_1_db user_2_db = UserDB(name='observer') user_2_db = User.add_or_update(user_2_db) self.users['observer'] = user_2_db user_3_db = UserDB(name='no_roles') user_3_db = User.add_or_update(user_3_db) self.users['no_roles'] = user_3_db user_5_db = UserDB(name='user_5') user_5_db = User.add_or_update(user_5_db) self.users['user_5'] = user_5_db user_4_db = UserDB(name='custom_role') user_4_db = User.add_or_update(user_4_db) self.users['1_custom_role'] = user_4_db # Create some mock roles role_1_db = rbac_service.create_role(name='custom_role_1') role_2_db = rbac_service.create_role(name='custom_role_2', description='custom role 2') self.roles['custom_role_1'] = role_1_db self.roles['custom_role_2'] = role_2_db rbac_service.create_role(name='role_1') rbac_service.create_role(name='role_2') rbac_service.create_role(name='role_3') rbac_service.create_role(name='role_4') # Create some mock role assignments role_assignment_1 = UserRoleAssignmentDB( user=self.users['1_custom_role'].name, role=self.roles['custom_role_1'].name, source='assignments/%s.yaml' % self.users['1_custom_role'].name) role_assignment_1 = UserRoleAssignment.add_or_update(role_assignment_1) # Note: User use pymongo to insert mock data because we want to insert a # raw document and skip mongoengine to leave is_remote field unpopulated client = MongoClient() db = client['st2-test'] db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_1' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_2' }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_3', 'is_remote': False }) db.user_role_assignment_d_b.insert_one({ 'user': '******', 'role': 'role_4', 'is_remote': True }) # Create some mock resources on which permissions can be granted rule_1_db = RuleDB(pack='test1', name='rule1', ref='test1.rule1') rule_1_db = Rule.add_or_update(rule_1_db) self.resources['rule_1'] = rule_1_db
def test_get_all_roles(self): role_dbs = rbac_service.get_all_roles() self.assertEqual(len(role_dbs), len(self.roles) + 4)