def _assessment(self):
   """Get the assessment used in the query and verify its permissions."""
   assessment_id = self.query[0]["filters"]["expression"]["ids"][0]
   assessment = models.Assessment.query.get(assessment_id)
   if permissions.is_allowed_read_for(assessment):
     return assessment
   raise Forbidden()
Ejemplo n.º 2
0
    def _get_objects(self, object_query):
        """Get a set of objects described in the filters."""
        object_name = object_query["object_name"]
        expression = object_query.get("filters", {}).get("expression")

        if expression is None:
            return set()
        object_class = self.object_map[object_name]

        query = object_class.query
        filter_expression = self._build_expression(
            expression,
            object_class,
            object_query.get('fields', []),
        )
        if filter_expression is not None:
            query = query.filter(filter_expression)
        if object_query.get("order_by"):
            query = self._apply_order_by(
                object_class,
                query,
                object_query["order_by"],
            )
        requested_permissions = object_query.get("permissions", "read")
        if requested_permissions == "update":
            objs = [o for o in query if permissions.is_allowed_update_for(o)]
        else:
            objs = [o for o in query if permissions.is_allowed_read_for(o)]

        return objs
Ejemplo n.º 3
0
  def related_objects(self, id):
    """Get data for snapshot related_objects page."""
    # id name is used as a kw argument and can't be changed here
    # pylint: disable=invalid-name,redefined-builtin
    from ggrc import models
    from ggrc.rbac import permissions
    snapshot = models.Snapshot.query.get(id)
    if snapshot is None:
      return self.not_found_response()
    if not permissions.is_allowed_read_for(snapshot):
      raise exceptions.Forbidden()

    data = defaultdict(list)
    for obj in snapshot.related_objects():
      obj_data = _stub(obj)
      if obj.type == "Snapshot":
        child = referenced_objects.get(obj.child_type, obj.child_id)
        obj_data.update({
            "child": _stub(child),
            "revision:": {
                "content": {
                    "title": obj.revision.content.get("title", ""),
                    "updated_at": obj.revision.content.get("updated_at", "")}}
        })
      data[obj.type].append(obj_data)
    return self.json_success_response(data, )
Ejemplo n.º 4
0
    def related_objects(self, id):
        """Get data for snapshot related_objects page."""
        # id name is used as a kw argument and can't be changed here
        # pylint: disable=invalid-name,redefined-builtin
        from ggrc import models
        from ggrc.rbac import permissions
        snapshot = models.Snapshot.query.get(id)
        if snapshot is None:
            return self.not_found_response()
        if not permissions.is_allowed_read_for(snapshot):
            raise exceptions.Forbidden()

        data = defaultdict(list)
        for obj in snapshot.related_objects():
            obj_data = _stub(obj)
            if obj.type == "Snapshot":
                child = referenced_objects.get(obj.child_type, obj.child_id)
                obj_data.update({
                    "child": _stub(child),
                    "revision:": {
                        "content": {
                            "title":
                            obj.revision.content.get("title", ""),
                            "updated_at":
                            obj.revision.content.get("updated_at", "")
                        }
                    }
                })
            data[obj.type].append(obj_data)
        return self.json_success_response(data, )
Ejemplo n.º 5
0
def handle_workflow_post(sender, obj=None, src=None, service=None):
    _validate_post_workflow_fields(obj)

    source_workflow = None

    if src.get('clone'):
        source_workflow_id = src.get('clone')
        source_workflow = models.Workflow.query.get(source_workflow_id)
        # prevent from cloning without proper permissions
        if not is_allowed_read_for(source_workflow):
            raise Forbidden(
                description="You don't have permissions for reading an "
                "object")
        source_workflow.copy(obj, clone_people=src.get('clone_people', False))

        copied_workflows = models.Workflow.query.filter_by(
            parent_id=source_workflow.id).values('title')
        used_titles = [w.title for w in copied_workflows]
        obj.title = get_copy_title(source_workflow.title, used_titles)

    # get the personal context for this logged in user
    user = get_current_user(use_external_user=False)
    personal_context = user.get_or_create_object_context(context=1)
    workflow_context = obj.get_or_create_object_context(personal_context)
    obj.context = workflow_context

    if src.get('clone'):
        source_workflow.copy_task_groups(
            obj,
            clone_people=src.get('clone_people', False),
            clone_tasks=src.get('clone_tasks', False),
            clone_objects=src.get('clone_objects', False))
Ejemplo n.º 6
0
 def related_objects(self, id):
     """Get data for assessment related_objects page."""
     # id name is used as a kw argument and can't be changed here
     # pylint: disable=invalid-name,redefined-builtin
     with benchmark("check assessment permissions"):
         assessment = models.Assessment.query.options(
             orm.undefer_group("Assessment_complete")).get(id)
         if not permissions.is_allowed_read_for(assessment):
             raise Forbidden()
     with benchmark("Get assessment related_objects data"):
         data = self._get_related_data(assessment)
     with benchmark("Make response"):
         return self.json_success_response(data, )
Ejemplo n.º 7
0
  def handle_model_clone(cls, query):
    """Process cloning of objects.

    Args:
        query: Dict with parameters for cloning procedure. It should have
            following structure:
            {
              "sourceObjectIds": [1, 2],
              "destination": {"type": "Audit", "id": 2},  # optional
              "mappedObjects":[]  # optional
            }.

    Returns:
        Response with status code 200 in case of success and 400 if provided
        parameters are invalid.
    """
    source_objs, destination, mapped_types = cls._parse_query(query)

    clonned_objs = {}
    for source_obj in source_objs:
      if (
          not permissions.is_allowed_read_for(source_obj) or
          not permissions.is_allowed_create(
              source_obj.type, source_obj.id, destination.context_id
          )
      ):
        raise exceptions.Forbidden()
      clonned_objs[source_obj] = cls._copy_obj(source_obj, destination)

    for target, mapped_obj in cls._collect_mapped(source_objs, mapped_types):
      clonned_objs[mapped_obj] = cls._copy_obj(mapped_obj, target)

    cls._set_parent_context(clonned_objs.values(), destination)
    db.session.flush()

    for source, clonned in clonned_objs.items():
      cls._clone_cads(source, clonned)

    if clonned_objs:
      db.session.add(log_event(db.session, flush=False))
    db.session.commit()

    from ggrc.query import views
    collections = []
    if cls.RETURN_OBJ_JSON:
      for obj in clonned_objs:
        collections.append(
            views.build_collection_representation(cls, obj.log_json())
        )
    return views.json_success_response(collections, datetime.datetime.utcnow())
Ejemplo n.º 8
0
 def related_objects(self, id):
   """Get data for assessment related_objects page."""
   # id name is used as a kw argument and can't be changed here
   # pylint: disable=invalid-name,redefined-builtin
   with benchmark("check assessment permissions"):
     assessment = models.Assessment.query.options(
         orm.undefer_group("Assessment_complete")
     ).get(id)
     if not permissions.is_allowed_read_for(assessment):
       raise Forbidden()
   with benchmark("Get assessment related_objects data"):
     data = self._get_related_data(assessment)
   with benchmark("Make response"):
     return self.json_success_response(data, )
Ejemplo n.º 9
0
 def summary_query(self, id):
     """Get data for audit summary page."""
     # id name is used as a kw argument and can't be changed here
     # pylint: disable=invalid-name,redefined-builtin
     with benchmark("check audit permissions"):
         audit = models.Audit.query.get(id)
         if not permissions.is_allowed_read_for(audit):
             raise Forbidden()
     with benchmark("Get audit summary data"):
         data = db.session.query(
             models.Assessment.status,
             models.Assessment.verified,
         ).filter(models.Assessment.audit_id == id).all()
     with benchmark("Make response"):
         response_object = list(data)
         return self.json_success_response(response_object, )
Ejemplo n.º 10
0
 def summary_query(self, id):
   """Get data for audit summary page."""
   # id name is used as a kw argument and can't be changed here
   # pylint: disable=invalid-name,redefined-builtin
   with benchmark("check audit permissions"):
     audit = models.Audit.query.get(id)
     if not permissions.is_allowed_read_for(audit):
       raise Forbidden()
   with benchmark("Get audit summary data"):
     data = db.session.query(
         models.Assessment.status,
         models.Assessment.verified,
     ).filter(
         models.Assessment.audit_id == id
     ).all()
   with benchmark("Make response"):
     response_object = list(data)
     return self.json_success_response(response_object, )
Ejemplo n.º 11
0
  def summary_query(self, id):
    """Get data for audit summary page."""
    # id name is used as a kw argument and can't be changed here
    # pylint: disable=invalid-name,redefined-builtin,too-many-locals
    with benchmark("check audit permissions"):
      audit = models.Audit.query.get(id)
      if not permissions.is_allowed_read_for(audit):
        raise Forbidden()
    with benchmark("Get audit summary data"):
      #  evidence_relationship => evidence destination
      evidence_relationship_ds = db.session.query(
          models.Relationship.source_id.label("cp_id"),
          models.Relationship.source_type.label("cp_type"),
          models.Evidence.id.label("evidence_id"),
      ).join(
          models.Evidence,
          sa.and_(
              models.Relationship.destination_id == models.Evidence.id,
              models.Relationship.destination_type == "Evidence"
          )
      ).subquery()
      #  evidence_relationship => evidence source
      evidence_relationship_sd = db.session.query(
          models.Relationship.destination_id.label("cp_id"),
          models.Relationship.destination_type.label("cp_type"),
          models.Evidence.id.label("evidence_id"),
      ).join(
          models.Evidence,
          sa.and_(
              models.Relationship.source_id == models.Evidence.id,
              models.Relationship.source_type == "Evidence"
          )
      ).subquery()

      assessment_evidences = db.session.query(
          models.Assessment.id.label("id"),
          models.Assessment.status.label("status"),
          models.Assessment.verified.label("verified"),
          evidence_relationship_ds.c.evidence_id,
      ).outerjoin(
          evidence_relationship_ds,
          sa.and_(
              evidence_relationship_ds.c.cp_id == models.Assessment.id,
              evidence_relationship_ds.c.cp_type == "Assessment",
          )
      ).filter(
          models.Assessment.audit_id == id,
      ).union_all(
          db.session.query(
              models.Assessment.id.label("id"),
              models.Assessment.status.label("status"),
              models.Assessment.verified.label("verified"),
              evidence_relationship_sd.c.evidence_id,
          ).outerjoin(
              evidence_relationship_sd,
              sa.and_(
                  evidence_relationship_sd.c.cp_id == models.Assessment.id,
                  evidence_relationship_sd.c.cp_type == "Assessment",
              )
          ).filter(models.Assessment.audit_id == id)
      )

      statuses_data = defaultdict(lambda: defaultdict(set))
      all_assessment_ids = set()
      all_evidence_ids = set()
      for id_, status, verified, evidence_id in assessment_evidences:
        if id_:
          statuses_data[(status, verified)]["assessments"].add(id_)
          all_assessment_ids.add(id_)
        if evidence_id:
          statuses_data[(status, verified)]["evidence"].add(evidence_id)
          all_evidence_ids.add(evidence_id)

    with benchmark("Make response"):
      statuses_json = []
      total = {"assessments": 0, "evidence": 0}
      for (status, verified), data in statuses_data.items():
        statuses_json.append({
            "name": status,
            "verified": verified,
            "assessments": len(data["assessments"]),
            "evidence": len(data["evidence"]),
        })
      total["assessments"] = len(all_assessment_ids)
      total["evidence"] = len(all_evidence_ids)

      statuses_json.sort(key=lambda k: (k["name"], k["verified"]))
      response_object = {"statuses": statuses_json, "total": total}
      return self.json_success_response(response_object, )
Ejemplo n.º 12
0
    def summary_query(self, id):
        """Get data for audit summary page."""
        # id name is used as a kw argument and can't be changed here
        # pylint: disable=invalid-name,redefined-builtin
        with benchmark("check audit permissions"):
            audit = models.Audit.query.get(id)
            if not permissions.is_allowed_read_for(audit):
                raise Forbidden()
        with benchmark("Get audit summary data"):
            #  evidence_relationship => evidence destination
            evidence_relationship_ds = db.session.query(
                models.Relationship.source_id.label("cp_id"),
                models.Relationship.source_type.label("cp_type"),
                models.Evidence.id.label("evidence_id"),
            ).join(
                models.Evidence,
                sa.and_(
                    models.Relationship.destination_id == models.Evidence.id,
                    models.Relationship.destination_type ==
                    "Evidence")).subquery()
            #  evidence_relationship => evidence source
            evidence_relationship_sd = db.session.query(
                models.Relationship.destination_id.label("cp_id"),
                models.Relationship.destination_type.label("cp_type"),
                models.Evidence.id.label("evidence_id"),
            ).join(
                models.Evidence,
                sa.and_(
                    models.Relationship.source_id == models.Evidence.id,
                    models.Relationship.source_type == "Evidence")).subquery()

            assessment_evidences = db.session.query(
                models.Assessment.id.label("id"),
                models.Assessment.status.label("status"),
                models.Assessment.verified.label("verified"),
                evidence_relationship_ds.c.evidence_id,
            ).outerjoin(
                evidence_relationship_ds,
                sa.and_(
                    evidence_relationship_ds.c.cp_id == models.Assessment.id,
                    evidence_relationship_ds.c.cp_type == "Assessment",
                )).filter(models.Assessment.audit_id == id, ).union_all(
                    db.session.query(
                        models.Assessment.id.label("id"),
                        models.Assessment.status.label("status"),
                        models.Assessment.verified.label("verified"),
                        evidence_relationship_sd.c.evidence_id,
                    ).outerjoin(
                        evidence_relationship_sd,
                        sa.and_(
                            evidence_relationship_sd.c.cp_id ==
                            models.Assessment.id,
                            evidence_relationship_sd.c.cp_type == "Assessment",
                        )).filter(models.Assessment.audit_id == id))

            statuses_data = defaultdict(lambda: defaultdict(set))
            all_assessment_ids = set()
            all_evidence_ids = set()
            for id_, status, verified, evidence_id in assessment_evidences:
                if id_:
                    statuses_data[(status, verified)]["assessments"].add(id_)
                    all_assessment_ids.add(id_)
                if evidence_id:
                    statuses_data[(status,
                                   verified)]["evidence"].add(evidence_id)
                    all_evidence_ids.add(evidence_id)

        with benchmark("Make response"):
            statuses_json = []
            total = {"assessments": 0, "evidence": 0}
            for (status, verified), data in statuses_data.items():
                statuses_json.append({
                    "name": status,
                    "verified": verified,
                    "assessments": len(data["assessments"]),
                    "evidence": len(data["evidence"]),
                })
            total["assessments"] = len(all_assessment_ids)
            total["evidence"] = len(all_evidence_ids)

            statuses_json.sort(key=lambda k: (k["name"], k["verified"]))
            response_object = {"statuses": statuses_json, "total": total}
            return self.json_success_response(response_object, )