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()
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
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, )
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, )
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))
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, )
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())
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, )
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, )
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, )
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, )
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, )