예제 #1
0
def relevant(exp, object_class, target_class, query):
    "Filter by relevant object"
    if exp['object_name'] == "__previous__":
        exp = query[exp['ids'][0]]
    object_name = exp['object_name']
    ids = exp['ids']
    snapshoted = (object_class.__name__ in rules.Types.scoped
                  and object_name in rules.Types.all)
    if not snapshoted:
        return object_class.id.in_(
            RelationshipHelper.get_ids_related_to(
                object_class.__name__,
                object_name,
                ids,
            ))
    snapshot_qs = models.Snapshot.query.filter(
        models.Snapshot.parent_type == models.Audit.__name__,
        models.Snapshot.child_type == object_name,
        models.Snapshot.child_id.in_(ids),
    ).options(load_only(models.Snapshot.id), ).distinct().subquery("snapshot")
    dest_qs = models.Relationship.query.filter(
        models.Relationship.destination_id == snapshot_qs.c.id,
        models.Relationship.destination_type == models.Snapshot.__name__,
        models.Relationship.source_type == object_class.__name__,
    ).options(load_only("source_id")).distinct()
    source_qs = models.Relationship.query.filter(
        models.Relationship.source_id == snapshot_qs.c.id,
        models.Relationship.source_type == models.Snapshot.__name__,
        models.Relationship.destination_type == object_class.__name__,
    ).options(load_only("destination_id")).distinct()
    ids_qs = dest_qs.union(source_qs).distinct().subquery("ids")
    return object_class.id == ids_qs.c.relationships_source_id
예제 #2
0
 def relevant():
     """Filter by relevant object."""
     query = (self.query[exp["ids"][0]]
              if exp["object_name"] == "__previous__" else exp)
     return object_class.id.in_(
         RelationshipHelper.get_ids_related_to(
             object_class.__name__,
             query["object_name"],
             query["ids"],
         ))
예제 #3
0
        def relevant(object_name, ids):
            """Filter by relevant object.

      Args:
        object_name (basestring): the name of the related model.
        ids ([int]): the ids of related objects of type `object_name`.

      Returns:
        sqlalchemy.sql.elements.BinaryExpression if an object of `object_class`
        is related (via a Relationship or another m2m) to one the given objects.
      """
            return object_class.id.in_(
                RelationshipHelper.get_ids_related_to(
                    object_class.__name__,
                    object_name,
                    ids,
                ))
예제 #4
0
    def _relevant(object_name, ids):
      """Filter by relevant object.

      Args:
        object_name (basestring): the name of the related model.
        ids ([int]): the ids of related objects of type `object_name`.

      Returns:
        sqlalchemy.sql.elements.BinaryExpression if an object of `object_class`
        is related (via a Relationship or another m2m) to one the given objects.
      """
      return object_class.id.in_(
            RelationshipHelper.get_ids_related_to(
                object_class.__name__,
                object_name,
                ids,
            )
        )
예제 #5
0
        def related_people(related_type, related_ids):
            """Get people related to the specified object.

      Returns the following people:
        for each object type: the users mapped via PeopleObjects,
        for Program: the users that have a Program-wide role,
        for Audit: the users that have a Program-wide or Audit-wide role,
        for Workflow: the users mapped via WorkflowPeople and
                      the users that have a Workflow-wide role.

      Args:
        related_type: the name of the class of the related objects.
        related_ids: the ids of related objects.

      Returns:
        sqlalchemy.sql.elements.BinaryExpression if an object of `object_class`
        is related to the given users.
      """
            if "Person" not in [object_class.__name__, related_type]:
                return sa.sql.false()
            model = inflector.get_model(related_type)
            res = []
            res.extend(
                RelationshipHelper.person_object(
                    object_class.__name__,
                    related_type,
                    related_ids,
                ))

            if related_type in ('Program', 'Audit'):
                res.extend(
                    db.session.query(UserRole.person_id).join(
                        model,
                        sa.and_(
                            UserRole.context_id == model.context_id,
                            model.id.in_(related_ids),
                        )))

                if related_type == "Audit":
                    res.extend(
                        db.session.query(UserRole.person_id).join(
                            models.Program,
                            UserRole.context_id == models.Program.context_id,
                        ).join(
                            model,
                            sa.and_(
                                models.Program.id == model.program_id,
                                model.id.in_(related_ids),
                            )))
            if "Workflow" in (object_class.__name__, related_type):
                try:
                    from ggrc_workflows.models import (relationship_helper as
                                                       wf_relationship_handler)
                except ImportError:
                    # ggrc_workflows module is not enabled
                    return sa.sql.false()
                else:
                    res.extend(
                        wf_relationship_handler.workflow_person(
                            object_class.__name__,
                            related_type,
                            related_ids,
                        ))
            if res:
                return object_class.id.in_([obj[0] for obj in res])
            return sa.sql.false()
예제 #6
0
    def related_people(related_type, related_ids):
      """Get people related to the specified object.

      Returns the following people:
        for each object type: the users mapped via PeopleObjects,
        for Program: the users that have a Program-wide role,
        for Audit: the users that have a Program-wide or Audit-wide role,
        for Workflow: the users mapped via WorkflowPeople and
                      the users that have a Workflow-wide role.

      Args:
        related_type: the name of the class of the related objects.
        related_ids: the ids of related objects.

      Returns:
        sqlalchemy.sql.elements.BinaryExpression if an object of `object_class`
        is related to the given users.
      """
      if "Person" not in [object_class.__name__, related_type]:
        return sa.sql.false()
      model = inflector.get_model(related_type)
      res = []
      res.extend(RelationshipHelper.person_object(
          object_class.__name__,
          related_type,
          related_ids,
      ))

      if related_type in ('Program', 'Audit'):
        res.extend(
            db.session.query(UserRole.person_id).join(model, sa.and_(
                UserRole.context_id == model.context_id,
                model.id.in_(related_ids),
            ))
        )

        if related_type == "Audit":
          res.extend(
              db.session.query(UserRole.person_id).join(
                  models.Program,
                  UserRole.context_id == models.Program.context_id,
              ).join(model, sa.and_(
                  models.Program.id == model.program_id,
                  model.id.in_(related_ids),
              ))
          )
      if "Workflow" in (object_class.__name__, related_type):
        try:
          from ggrc_workflows.models import (relationship_helper as
                                             wf_relationship_handler)
        except ImportError:
          # ggrc_workflows module is not enabled
          return sa.sql.false()
        else:
          res.extend(wf_relationship_handler.workflow_person(
              object_class.__name__,
              related_type,
              related_ids,
          ))
      if res:
        return object_class.id.in_([obj[0] for obj in res])
      return sa.sql.false()