Exemple #1
0
    def validate(self):
        # Parent JSON schema validation
        cleaned = super(RoleDefinitionFileFormatAPI, self).validate()

        # Custom validation

        # Validate that only the correct permission types are used
        permission_grants = getattr(self, 'permission_grants', [])
        for permission_grant in permission_grants:
            resource_uid = permission_grant.get('resource_uid', None)
            permission_types = permission_grant.get('permission_types', [])

            if resource_uid:
                # Permission types which apply to a resource
                resource_type, _ = parse_uid(uid=resource_uid)
                valid_permission_types = PermissionType.get_valid_permissions_for_resource_type(
                    resource_type=resource_type)

                for permission_type in permission_types:
                    if permission_type not in valid_permission_types:
                        message = ('Invalid permission type "%s" for resource type "%s"' %
                                   (permission_type, resource_type))
                        raise ValueError(message)
            else:
                # Right now we only support single permission type (list) which is global and
                # doesn't apply to a resource
                for permission_type in permission_types:
                    if not permission_type.endswith('_list'):
                        message = ('Invalid permission type "%s". Only "list" permission types '
                                   'can be used without a resource id' % (permission_type))
                        raise ValueError(message)

            return cleaned
Exemple #2
0
    def validate(self):
        # Parent JSON schema validation
        super(RoleDefinitionFileFormatAPI, self).validate()

        # Custom validation

        # Validate that only the correct permission types are used
        permission_grants = getattr(self, 'permission_grants', [])
        for permission_grant in permission_grants:
            resource_uid = permission_grant.get('resource_uid', None)
            permission_types = permission_grant.get('permission_types', [])

            if resource_uid:
                # Permission types which apply to a resource
                resource_type, _ = parse_uid(uid=resource_uid)
                valid_permission_types = PermissionType.get_valid_permissions_for_resource_type(
                    resource_type=resource_type)

                for permission_type in permission_types:
                    if permission_type not in valid_permission_types:
                        message = (
                            'Invalid permission type "%s" for resource type "%s"'
                            % (permission_type, resource_type))
                        raise ValueError(message)
            else:
                # Right now we only support single permission type (list) which is global and
                # doesn't apply to a resource
                for permission_type in permission_types:
                    if not permission_type.endswith('_list'):
                        message = (
                            'Invalid permission type "%s". Only "list" permission types '
                            'can be used without a resource id' %
                            (permission_type))
                        raise ValueError(message)
Exemple #3
0
    def validate(self):
        # Parent JSON schema validation
        cleaned = super(RoleDefinitionFileFormatAPI, self).validate()

        # Custom validation

        # Validate that only the correct permission types are used
        permission_grants = getattr(self, "permission_grants", [])
        for permission_grant in permission_grants:
            resource_uid = permission_grant.get("resource_uid", None)
            permission_types = permission_grant.get("permission_types", [])

            if resource_uid:
                # Permission types which apply to a resource
                resource_type, _ = parse_uid(uid=resource_uid)
                valid_permission_types = (
                    PermissionType.get_valid_permissions_for_resource_type(
                        resource_type=resource_type))

                for permission_type in permission_types:
                    if permission_type not in valid_permission_types:
                        message = (
                            'Invalid permission type "%s" for resource type "%s"'
                            % (
                                permission_type,
                                resource_type,
                            ))
                        raise ValueError(message)
            else:
                # Right now we only support single permission type (list) which is global and
                # doesn't apply to a resource
                for permission_type in permission_types:
                    if permission_type not in GLOBAL_PERMISSION_TYPES:
                        valid_global_permission_types = ", ".join(
                            GLOBAL_PERMISSION_TYPES)
                        message = (
                            'Invalid permission type "%s". Valid global permission types '
                            "which can be used without a resource id are: %s" %
                            (permission_type, valid_global_permission_types))
                        raise ValueError(message)

        return cleaned
Exemple #4
0
    def validate(self):
        # Parent JSON schema validation
        super(RoleDefinitionFileFormatAPI, self).validate()

        # Custom validation

        # Validate that only the correct permission types are used
        permission_grants = getattr(self, 'permission_grants', [])
        for permission_grant in permission_grants:
            resource_uid = permission_grant.get('resource_uid', None)
            permission_types = permission_grant.get('permission_types', [])

            if resource_uid:
                resource_type, _ = parse_uid(uid=resource_uid)
                valid_permission_types = PermissionType.get_valid_permissions_for_resource_type(
                    resource_type=resource_type)

                for permission_type in permission_types:
                    if permission_type not in valid_permission_types:
                        message = ('Invalid permission type "%s" for resource type "%s"' %
                                   (permission_type, resource_type))
                        raise ValueError(message)
Exemple #5
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
            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]
Exemple #6
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]