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 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 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 _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(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 sync_roles(self, role_definition_apis): """ Synchronize all the role definitions in the database. :param role_dbs: RoleDB objects for the roles which are currently in the database. :type role_dbs: ``list`` of :class:`RoleDB` :param role_definition_apis: RoleDefinition API objects for the definitions loaded from the files. :type role_definition_apis: ``list`` of :class:RoleDefinitionFileFormatAPI` :rtype: ``tuple`` """ LOG.info('Synchronizing roles...') # Retrieve all the roles currently in the DB role_dbs = rbac_service.get_all_roles(exclude_system=True) role_db_names = [role_db.name for role_db in role_dbs] role_db_names = set(role_db_names) role_api_names = [role_definition_api.name for role_definition_api in role_definition_apis] role_api_names = set(role_api_names) # A list of new roles which should be added to the database new_role_names = role_api_names.difference(role_db_names) # A list of roles which need to be updated in the database updated_role_names = role_db_names.intersection(role_api_names) # A list of roles which should be removed from the database removed_role_names = (role_db_names - role_api_names) LOG.debug('New roles: %r' % (new_role_names)) LOG.debug('Updated roles: %r' % (updated_role_names)) LOG.debug('Removed roles: %r' % (removed_role_names)) # Build a list of roles to delete role_names_to_delete = updated_role_names.union(removed_role_names) role_dbs_to_delete = [role_db for role_db in role_dbs if role_db.name in role_names_to_delete] # Build a list of roles to create role_names_to_create = new_role_names.union(updated_role_names) role_apis_to_create = [role_definition_api for role_definition_api in role_definition_apis if role_definition_api.name in role_names_to_create] ######## # 1. Remove obsolete roles and associated permission grants from the DB ######## # Remove roles role_ids_to_delete = [] for role_db in role_dbs_to_delete: role_ids_to_delete.append(role_db.id) LOG.debug('Deleting %s stale roles' % (len(role_ids_to_delete))) Role.query(id__in=role_ids_to_delete, system=False).delete() LOG.debug('Deleted %s stale roles' % (len(role_ids_to_delete))) # Remove associated permission grants permission_grant_ids_to_delete = [] for role_db in role_dbs_to_delete: permission_grant_ids_to_delete.extend(role_db.permission_grants) LOG.debug('Deleting %s stale permission grants' % (len(permission_grant_ids_to_delete))) PermissionGrant.query(id__in=permission_grant_ids_to_delete).delete() LOG.debug('Deleted %s stale permission grants' % (len(permission_grant_ids_to_delete))) ######## # 2. Add new / updated roles to the DB ######## LOG.debug('Creating %s new roles' % (len(role_apis_to_create))) # Create new roles created_role_dbs = [] for role_api in role_apis_to_create: role_db = rbac_service.create_role(name=role_api.name, description=role_api.description) # Create associated permission grants permission_grants = getattr(role_api, 'permission_grants', []) for permission_grant in permission_grants: resource_uid = permission_grant.get('resource_uid', None) if resource_uid: resource_type, _ = parse_uid(resource_uid) else: resource_type = None permission_types = permission_grant['permission_types'] assignment_db = rbac_service.create_permission_grant( role_db=role_db, resource_uid=resource_uid, resource_type=resource_type, permission_types=permission_types) role_db.permission_grants.append(str(assignment_db.id)) created_role_dbs.append(role_db) LOG.debug('Created %s new roles' % (len(created_role_dbs))) LOG.info('Roles synchronized (%s created, %s updated, %s removed)' % (len(new_role_names), len(updated_role_names), len(removed_role_names))) return [created_role_dbs, role_dbs_to_delete]
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)