Example #1
0
    def setUp(self):
        super(RBACRemoteGroupToRoleSyncerTestCase, self).setUp()

        self.roles = {}
        self.role_assignments = {}

        # Insert mock local role assignments
        role_db = create_role(name='mock_local_role_1')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_1 = 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 = create_role(name='mock_local_role_2')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_2 = 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 = create_role(name='mock_remote_role_3')
        self.roles['mock_remote_role_3'] = role_db

        role_db = create_role(name='mock_remote_role_4')
        self.roles['mock_remote_role_4'] = role_db

        role_db = create_role(name='mock_role_5')
        self.roles['mock_role_5'] = role_db
Example #2
0
    def _insert_mock_roles(self):
        # Create some mock roles
        role_1_db = create_role(name='role_1')
        role_2_db = create_role(name='role_2')

        self.roles['role_1'] = role_1_db
        self.roles['role_2'] = role_2_db

        return self.roles
Example #3
0
    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 = create_role(name='mock_role_7')

        source = 'assignments/user_6_one.yaml'
        assign_role_to_user(role_db=role_db, user_db=user_db, source=source, is_remote=False)

        source = 'assignments/user_6_two.yaml'
        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"
        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"
        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 = 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 = 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 = 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 = get_role_assignments_for_user(user_db=self.users['user_6'])
        self.assertEqual(len(role_assignment_dbs), 3)
Example #4
0
    def setUp(self):
        super(HandlerTestCase, self).setUp()

        cfg.CONF.auth.backend = 'mock'

        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 = create_role(name='mock_local_role_1')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_1 = 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 = create_role(name='mock_local_role_2')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_2 = 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 = create_role(name='mock_role_3')
        self.roles['mock_role_3'] = role_db

        role_db = create_role(name='mock_role_4')
        self.roles['mock_role_4'] = role_db

        role_db = create_role(name='mock_role_5')
        self.roles['mock_role_5'] = role_db
Example #5
0
    def setUp(self):
        super(RBACServicesTestCase, self).setUp()

        # 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_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_services.create_role(name='custom_role_1')
        role_2_db = rbac_services.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

        # Create some mock role assignments
        role_assignment_1 = UserRoleAssignmentDB(user=self.users['1_custom_role'].name,
                                                 role=self.roles['custom_role_1'].name)
        role_assignment_1 = UserRoleAssignment.add_or_update(role_assignment_1)

        # 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
Example #6
0
    def _insert_mock_roles(self):
        # Create some mock roles
        role_1_db = create_role(name='role_1')
        role_2_db = create_role(name='role_2')
        role_3_db = 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
Example #7
0
    def _insert_common_mock_roles(self):
        # Insert common mock roles
        admin_role_db = rbac_services.get_role_by_name(name=SystemRole.ADMIN)
        observer_role_db = rbac_services.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_services.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
Example #8
0
    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_services.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_services.create_role(name=role_api.name, description=role_api.description)

            # Create associated permission grants
            for permission_grant in role_api.permission_grants:
                resource_uid = permission_grant["resource_uid"]
                resource_type, _ = parse_uid(resource_uid)
                permission_types = permission_grant["permission_types"]
                assignment_db = rbac_services.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]
Example #9
0
    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 = create_role(name='mock_role_7')

        source = 'assignments/user_6_one.yaml'
        assign_role_to_user(role_db=role_db,
                            user_db=user_db,
                            source=source,
                            is_remote=False)

        source = 'assignments/user_6_two.yaml'
        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"
        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"
        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 = 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 = 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 = 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 = get_role_assignments_for_user(
            user_db=self.users['user_6'])
        self.assertEqual(len(role_assignment_dbs), 3)
    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_services.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_services.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_services.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]
Example #11
0
    def setUp(self):
        super(RBACServicesTestCase, self).setUp()

        # 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_services.create_role(name='custom_role_1')
        role_2_db = rbac_services.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_services.create_role(name='role_1')
        rbac_services.create_role(name='role_2')
        rbac_services.create_role(name='role_3')
        rbac_services.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