def _add_permissions_filter(self, query, model_class):
        """Filter by the users present in either the `viewers` or `owners`
        lists
        """
        # not used from a request handler - no relevant user
        if not has_request_context():
            return query

        # Queries of elements that aren't resources (tenants, users, etc.),
        # shouldn't be filtered
        if not model_class.is_resource:
            return query

        # For users that are allowed to see all resources, regardless of tenant
        is_admin = is_administrator(self.current_tenant)
        if is_admin:
            return query

        # Only get resources that are public - not private (note that ~ stands
        # for NOT, in SQLA), *or* those where the current user is the creator
        user_filter = sql_or(
            model_class.visibility != VisibilityState.PRIVATE,
            model_class.creator == current_user
        )
        return query.filter(user_filter)
示例#2
0
    def strain(self, query):
        if not self._filters:
            return query
        filters = []
        tables = set()
        basename = self._strainer.tablename
        for f in self._filters:
            filters.append(f['filter'])
            tbl, _ = self._strainer.split_name(f['name'])
            if tbl != basename:
                tables.add(tbl)

        join_type = 'join'
        if self._strainer.restrictive:
            query = query.filter(*filters)
        else:
            query = query.filter(sql_or(*filters))
            join_type = 'outerjoin'
            # todo: validate repeated join relations act as set

        for tbl in tables:
            query = getattr(query,
                            join_type)(*self._strainer.relatives[tbl].join)
            flags = self._strainer.relatives[tbl].flags
            if flags:
                query = query.filter(*flags)

        return query.distinct()
示例#3
0
    def strain(self, query):
        if not self._filters:
            return query
        filters = []
        tables = set()
        basename = self._strainer.tablename
        for f in self._filters:
            filters.append(f['filter'])
            tbl, _ = self._strainer.split_name(f['name'])
            if tbl != basename:
                tables.add(tbl)

        join_type = 'join'
        if self._strainer.restrictive:
            query = query.filter(*filters)
        else:
            query = query.filter(sql_or(*filters))
            join_type = 'outerjoin'
            # todo: validate repeated join relations act as set

        for tbl in tables:
            query = getattr(query, join_type)(*self._strainer.relatives[tbl].join)
            flags = self._strainer.relatives[tbl].flags
            if flags:
                query = query.filter(*flags)

        return query.distinct()
示例#4
0
    def _add_permissions_filter(self, query, model_class):
        """Filter by the users present in either the `viewers` or `owners`
        lists
        """
        # not used from a request handler - no relevant user
        if not has_request_context():
            return query

        # Queries of elements that aren't resources (tenants, users, etc.),
        # shouldn't be filtered
        if not model_class.is_resource:
            return query

        # For users that are allowed to see all resources, regardless of tenant
        is_admin = is_administrator(self.current_tenant)
        if is_admin:
            return query

        # Only get resources that are public - not private (note that ~ stands
        # for NOT, in SQLA), *or* those where the current user is the creator
        user_filter = sql_or(
            model_class.visibility != VisibilityState.PRIVATE,
            model_class.creator == current_user
        )
        return query.filter(user_filter)
示例#5
0
    def _add_tenant_filter(self, query, model_class, all_tenants):
        """Filter by the tenant ID associated with `model_class` (either
        directly via a relationship with the tenants table, or via an
        ancestor who has such a relationship)
        """
        # Users/Groups etc. don't have tenants
        if not model_class.is_resource:
            return query

        # not used from a request handler - no relevant user
        if not has_request_context():
            return query

        # If a user that is allowed to get all the tenants in the system
        # passed the `all_tenants` flag, no need to filter
        if all_tenants_authorization() and all_tenants:
            return query

        if all_tenants:
            tenant_ids = [tenant.id for tenant in current_user.all_tenants]
        else:
            tenant_ids = [self.current_tenant.id]

        # Match any of the applicable tenant ids or if it's a global resource
        tenant_filter = sql_or(
            model_class.resource_availability == AvailabilityState.GLOBAL,
            model_class._tenant_id.in_(tenant_ids))
        return query.filter(tenant_filter)
 def _get_unique_resource_id_query(self, model_class, resource_id, tenant):
     """
     Query for all the resources with the same id of the given instance,
     if it's in the given tenant, or if it's a global resource
     """
     query = model_class.query
     query = query.filter(model_class.id == resource_id)
     unique_resource_filter = sql_or(
         model_class.tenant == tenant,
         model_class.visibility == VisibilityState.GLOBAL)
     query = query.filter(unique_resource_filter)
     return query
 def _get_unique_resource_id_query(self, model_class, resource_id,
                                   tenant):
     """
     Query for all the resources with the same id of the given instance,
     if it's in the given tenant, or if it's a global resource
     """
     query = model_class.query
     query = query.filter(model_class.id == resource_id)
     unique_resource_filter = sql_or(
         model_class.tenant == tenant,
         model_class.visibility == VisibilityState.GLOBAL
     )
     query = query.filter(unique_resource_filter)
     return query
示例#8
0
    def _add_permissions_filter(query, model_class):
        """Filter by the users present in either the `viewers` or `owners`
        lists
        """
        # System administrators should see all resources, regardless of tenant.
        # Queries of elements that aren't resources (tenants, users, etc.),
        # shouldn't be filtered as well
        if not model_class.is_resource or current_user.is_admin:
            return query

        # Only get resources that are public - not private (note that ~ stands
        # for NOT, in SQLA), *or* those where the current user is the creator
        user_filter = sql_or(~model_class.private_resource,
                             model_class.creator == current_user)
        return query.filter(user_filter)
    def _add_tenant_filter(self, query, model_class, all_tenants):
        """Filter by the tenant ID associated with `model_class` (either
        directly via a relationship with the tenants table, or via an
        ancestor who has such a relationship)
        """
        # Users/Groups etc. don't have tenants
        if not model_class.is_resource:
            return query

        # not used from a request handler - no relevant user
        if not has_request_context():
            return query

        current_tenant = self.current_tenant

        # If a user passed the `all_tenants` flag
        if all_tenants:
            # If a user that is allowed to get all the tenants in the system
            # no need to filter
            if all_tenants_authorization():
                return query
            # Filter by all the tenants the user is allowed to list in
            tenant_ids = [
                tenant.id for tenant in current_user.all_tenants
                if utils.tenant_specific_authorization(tenant,
                                                       model_class.__name__)
                ]
        else:
            # Specific tenant only
            tenant_ids = [current_tenant.id] if current_tenant else []

        # Match any of the applicable tenant ids or if it's a global resource
        tenant_filter = sql_or(
            model_class.visibility == VisibilityState.GLOBAL,
            model_class._tenant_id.in_(tenant_ids)
        )
        return query.filter(tenant_filter)
示例#10
0
    def _add_tenant_filter(self, query, model_class, all_tenants):
        """Filter by the tenant ID associated with `model_class` (either
        directly via a relationship with the tenants table, or via an
        ancestor who has such a relationship)
        """
        # Users/Groups etc. don't have tenants
        if not model_class.is_resource:
            return query

        # not used from a request handler - no relevant user
        if not has_request_context():
            return query

        current_tenant = self.current_tenant

        # If a user passed the `all_tenants` flag
        if all_tenants:
            # If a user that is allowed to get all the tenants in the system
            # no need to filter
            if all_tenants_authorization():
                return query
            # Filter by all the tenants the user is allowed to list in
            tenant_ids = [
                tenant.id for tenant in current_user.all_tenants
                if utils.tenant_specific_authorization(tenant,
                                                       model_class.__name__)
                ]
        else:
            # Specific tenant only
            tenant_ids = [current_tenant.id] if current_tenant else []

        # Match any of the applicable tenant ids or if it's a global resource
        tenant_filter = sql_or(
            model_class.visibility == VisibilityState.GLOBAL,
            model_class._tenant_id.in_(tenant_ids)
        )
        return query.filter(tenant_filter)
示例#11
0
    def _build_select_subquery(model, filters, range_filters, tenant_id):
        """Build select subquery.

        :param model: Model used to build the query (either Event or Log)
        :type model:
            :class:`manager_rest.storage.resource_models.Event`
            :class:`manager_rest.storage.resource_models.Log`
        :param filters: Filters passed as request argument
        :type filters: dict(str, list(str))
        :param range_filters: Range filtres passed as request argument
        :type range_filters: dict(str, dict(str))
        :returns: Select events query
        :rtype: :class:`sqlalchemy.orm.query.Query`

        """
        def select_column(column_name, label=None):
            """Select column from model by name.

            If column is not present in the model, then select `NULL` value
            instead.

            :param column_name: Name of the column to select
            :type column_name: str
            :return: Selected colum
            :rtype: :class:``

            """
            if not label:
                label = column_name
            if hasattr(model, column_name):
                return getattr(model, column_name).label(label)
            return literal_column('NULL').label(label)

        query = (db.session.query(
            select_column('id'),
            select_column('_storage_id'),
            select_column('timestamp'),
            select_column('reported_timestamp'),
            Blueprint.id.label('blueprint_id'),
            Deployment.id.label('deployment_id'),
            Execution.id.label('execution_id'),
            Execution.workflow_id.label('workflow_id'),
            select_column('message'),
            select_column('message_code'),
            select_column('error_causes'),
            select_column('event_type'),
            select_column('operation'),
            select_column('node_id'),
            select_column('source_id'),
            select_column('target_id'),
            NodeInstance.id.label('node_instance_id'),
            Node.id.label('node_name'),
            select_column('logger'),
            select_column('level'),
            literal_column("'cloudify_{}'".format(
                model.__name__.lower())).label('type'),
        ).filter(
            sql_or(model._tenant_id == tenant_id,
                   model.visibility == VisibilityState.GLOBAL)
        ).outerjoin(NodeInstance, NodeInstance.id == model.node_id).outerjoin(
            Node, Node._storage_id == NodeInstance._node_fk).outerjoin(
                Execution,
                Execution._storage_id == model._execution_fk).outerjoin(
                    Deployment, Deployment._storage_id ==
                    Execution._deployment_fk).outerjoin(
                        Blueprint,
                        Blueprint._storage_id == Deployment._blueprint_fk))

        query = Events._apply_filters(query, model, filters)
        query = Events._apply_range_filters(query, model, range_filters)
        return query
示例#12
0
    def _build_select_subquery(model, filters, range_filters, tenant_id):
        """Build select subquery.

        :param model: Model used to build the query (either Event or Log)
        :type model:
            :class:`manager_rest.storage.resource_models.Event`
            :class:`manager_rest.storage.resource_models.Log`
        :param filters: Filters passed as request argument
        :type filters: dict(str, list(str))
        :param range_filters: Range filtres passed as request argument
        :type range_filters: dict(str, dict(str))
        :returns: Select events query
        :rtype: :class:`sqlalchemy.orm.query.Query`

        """
        def select_column(column_name, label=None):
            """Select column from model by name.

            If column is not present in the model, then select `NULL` value
            instead.

            :param column_name: Name of the column to select
            :type column_name: str
            :return: Selected colum
            :rtype: :class:``

            """
            if not label:
                label = column_name
            if hasattr(model, column_name):
                return getattr(model, column_name).label(label)
            return literal_column('NULL').label(label)

        query = (
            db.session.query(
                select_column('id'),
                select_column('_storage_id'),
                select_column('timestamp'),
                select_column('reported_timestamp'),
                Blueprint.id.label('blueprint_id'),
                Deployment.id.label('deployment_id'),
                Execution.id.label('execution_id'),
                Execution.workflow_id.label('workflow_id'),
                select_column('message'),
                select_column('message_code'),
                select_column('error_causes'),
                select_column('event_type'),
                select_column('operation'),
                select_column('node_id'),
                select_column('source_id'),
                select_column('target_id'),
                NodeInstance.id.label('node_instance_id'),
                Node.id.label('node_name'),
                select_column('logger'),
                select_column('level'),
                literal_column("'cloudify_{}'".format(model.__name__.lower()))
                .label('type'),
            )
            .filter(
                sql_or(
                    model._tenant_id == tenant_id,
                    model.visibility == VisibilityState.GLOBAL
                )
            )
            .outerjoin(NodeInstance, NodeInstance.id == model.node_id)
            .outerjoin(Node, Node._storage_id == NodeInstance._node_fk)
            .outerjoin(Execution, Execution._storage_id == model._execution_fk)
            .outerjoin(Deployment,
                       Deployment._storage_id == Execution._deployment_fk)
            .outerjoin(
                Blueprint, Blueprint._storage_id == Deployment._blueprint_fk)
        )

        query = Events._apply_filters(query, model, filters)
        query = Events._apply_range_filters(query, model, range_filters)
        return query