def _parse_values(values): """ Parse list of (ac_role, user) in form of: e.g [{ "ac_role_id": admin_role_id, "person": { "id": user_id } }] or [{ "ac_role": AccessControlRole(), "person": Person() }] Return set of tuples(AccessControlRole, Person)""" result = set() for value in values: if ("ac_role_id" in value and "person" in value and "id" in value["person"]): result.add((get("AccessControlRole", value["ac_role_id"]), get("Person", value["person"]["id"]))) elif "ac_role" in value and "person" in value: result.add((value["ac_role"], value["person"])) else: raise ValueError("Unknown values format") return result
def _validate_readonly_access(obj, src): """Ensure that relationship is allowed for read-only objects""" if not isinstance(obj, relationship.Relationship): # skip Snapshot objects return obj1 = referenced_objects.get(obj.source_type, obj.source_id) obj2 = referenced_objects.get(obj.destination_type, obj.destination_id) if isinstance(obj1, WithReadOnlyAccess): RelationshipResource._validate_readonly_relationship(obj1, obj2) if isinstance(obj2, WithReadOnlyAccess): RelationshipResource._validate_readonly_relationship(obj2, obj1)
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 access_control_list(self, values): """Setter function for access control list. Args: values: List of access control roles or dicts containing json representation of custom attribute values. """ if values is None: return from ggrc.models import person for value in values: referenced_objects.mark_to_cache(person.Person, value["person"]["id"]) referenced_objects.rewarm_cache( rewarm_type=person.Person, skip_cad=True, undefer=True, ) persons_by_acl = defaultdict(set) for value in values: if value["ac_role_id"] not in self.acr_id_acl_map: raise BadRequest(errors.BAD_PARAMS) person = referenced_objects.get("Person", value["person"]["id"]) acl = self.acr_id_acl_map[value["ac_role_id"]] persons_by_acl[acl].add(person) for acl in self._access_control_list: acl.update_people(persons_by_acl[acl])
def map_objects(src, dst): """Creates a relationship between an src and dst. This also generates automappings. Fails silently if dst dict does not have id and type keys. Args: src (model): The src model dst (dict): A dict with `id` and `type`. Returns: None """ if not dst: return if 'id' not in dst or 'type' not in dst: return destination = referenced_objects.get(dst["type"], dst["id"]) if not destination: raise ValueError("No {} with id {} found." .format(dst["type"], dst["id"])) db.session.add(all_models.Relationship( source=src, destination=destination, context=src.context or destination.context, ))
def test_get_table_not_exists(self, get_model): """Tests getting object for deleted table.""" from ggrc.utils.referenced_objects import get get_model.return_value = None with patch('flask.g', {}): result = get(self.type_, self.id_) self.assertIsNone(result)
def _get_assessment_template(obj_src): """Get asmt template object which is referenced by current row if exists""" tmpl_info = obj_src.get('template') if not tmpl_info or not isinstance(tmpl_info, dict): return None return referenced_objects.get(tmpl_info.get('type'), tmpl_info.get('id'))
def lazy_loader(): """Lazy load diff for revisions.""" referenced_objects.rewarm_cache() revisions_diff.rewarm_latest_content() instance = referenced_objects.get(self.resource_type, self.resource_id) if instance: return revisions_diff.prepare(instance, self.content) # return empty diff object has already been removed return {}
def lazy_loader(): """Lazy load diff for revisions.""" referenced_objects.rewarm_cache() instance = referenced_objects.get(self.resource_type, self.resource_id) meta_dict = {} if instance: instance_meta_info = meta_info.MetaInfo(instance) meta_dict["mandatory"] = instance_meta_info.mandatory return meta_dict
def __call__(self, obj, json_obj): for field_name, prop_instance in obj.__class__.__dict__.iteritems(): if prop_instance is self: instance = referenced_objects.get(json_obj[field_name]["type"], json_obj[field_name]["id"]) if self.INSTANCE_TYPE: assert isinstance(instance, self.INSTANCE_TYPE) return instance return None
def _get_object_from_src(src, id_getter, obj_type, current=None): # type: (dict, function, str, Optional[db.Model]) -> Optional[db.Model] """Get object from source.""" obj = current id_ = id_getter(src) if id_ is None: return None if current is None or current.id != id_: obj = referenced_objects.get(obj_type, id_, raise_exception=True) return obj
def prepare(self, data): data = super(FullInstanceContentFased, self).prepare(data) content = builder.prepare( referenced_objects.get(data["instance"]["type"], data["instance"]["id"]), data["full_instance_content"]) # pop out unused object_people field out of mapping_list_fields if 'mapping_list_fields' in content: content['mapping_list_fields'].pop('object_people', None) return content
def prepare(self, data): data = super(FullInstanceContentFased, self).prepare(data) content = builder.prepare( referenced_objects.get(data["instance"]["type"], data["instance"]["id"]), data["full_instance_content"]) # pop out unused object_people field out of mapping_list_fields if 'mapping_list_fields' in content: content['mapping_list_fields'].pop('object_people', None) content['mapping_list_fields'].pop('task_group_objects', None) return content
def access_control_list(self, values): """Setter function for access control list. Args: value: List of access control roles or dicts containing json representation of custom attribute values. """ if values is None: return new_values = { (get("AccessControlRole", value['ac_role_id']), get("Person", value['person']['id'])) for value in values if value.get('ac_role_id') is not None } | {(value['ac_role'], value['person']) for value in values if value.get('ac_role') is not None and value.get('person') is not None} old_values = {(acl.ac_role, acl.person) for acl in self.access_control_list} self._remove_values(old_values - new_values) self._add_values(new_values - old_values)
def _handle_if_empty(self): """Check if revision is empty and update is_empty flag if true.""" # Check if new revision contains any changes in resource state. Revisions # created with "created" or "deleted" action are not considered empty. if self in db.session.new and self.action == u"modified": obj = referenced_objects.get(self.resource_type, self.resource_id) # Content serialization and deserialization is needed since content of # prev revision stored in DB was serialized before storing and due to # this couldn't be correctly compared to content of revision in hands. content = json.loads(utils.as_json(self.content)) self.is_empty = bool( obj and not revisions_diff.changes_present(obj, content))
def _handle_assessment(assessment, src): """Handles auto calculated properties for Assessment model.""" snapshot_dict = src.get('object') or {} common.map_objects(assessment, snapshot_dict) common.map_objects(assessment, src.get('audit')) snapshot = referenced_objects.get("Snapshot", snapshot_dict.get('id')) template = referenced_objects.get( src.get('template', {}).get('type'), src.get('template', {}).get('id'), ) if template: relate_ca(assessment, template) if not src.get('_generated') and not snapshot: return audit = referenced_objects.get( src['audit']['type'], src['audit']['id'], ) relate_assignees(assessment, snapshot, template, audit) assessment.title = u'{} assessment for {}'.format( snapshot.revision.content['title'], audit.title, ) if not template: # Assessment test plan should inherit test plan of snapshot assessment.test_plan = snapshot.revision.content.get("test_plan") return assessment.test_plan_procedure = template.test_plan_procedure assessment.test_plan = template.procedure_description if template.test_plan_procedure: copy_snapshot_plan(assessment, snapshot) if template.template_object_type: assessment.assessment_type = template.template_object_type
def handle_assessment_create(assessment, src): """Handles issue tracker related data.""" # Get issue tracker data from request. info = src.get('issue_tracker') or {} if not info: # Check assessment template for issue tracker data. template = referenced_objects.get( src.get('template', {}).get('type'), src.get('template', {}).get('id'), ) if template: info = template.issue_tracker if not info: # Check audit for issue tracker data. audit = referenced_objects.get( src.get('audit', {}).get('type'), src.get('audit', {}).get('id'), ) if audit: info = audit.issue_tracker _create_issuetracker_info(assessment, info)
def _handle_assessment(assessment, src): """Handles auto calculated properties for Assessment model.""" snapshot_dict = src.get('object') or {} common.map_objects(assessment, snapshot_dict) common.map_objects(assessment, src.get('audit')) snapshot = referenced_objects.get("Snapshot", snapshot_dict.get('id')) if not src.get('_generated') and not snapshot: return template = referenced_objects.get( src.get('template', {}).get('type'), src.get('template', {}).get('id'), ) audit = referenced_objects.get( src['audit']['type'], src['audit']['id'], ) relate_assignees(assessment, snapshot, template, audit) relate_ca(assessment, template) assessment.title = u'{} assessment for {}'.format( snapshot.revision.content['title'], audit.title, ) if not template: # Assessment test plan should inherit test plan of snapshot assessment.test_plan = snapshot.revision.content.get("test_plan") return assessment.test_plan_procedure = template.test_plan_procedure assessment.test_plan = template.procedure_description if template.test_plan_procedure: copy_snapshot_plan(assessment, snapshot) if template.template_object_type: assessment.assessment_type = template.template_object_type
def _add_ca_value_dicts(self, values): """Add CA dict representations to _custom_attributes_values property. This adds or updates the _custom_attribute_values with the values in the custom attribute values serialized dictionary. Args: values: List of dictionaries that represent custom attribute values. """ from ggrc.utils import referenced_objects from ggrc.models.external_custom_attribute_value \ import ExternalCustomAttributeValue for value in values: # TODO: decompose to smaller methods # TODO: remove complicated nested conditions, better to use # instant exception raising attr = self._values_map.get(value.get("custom_attribute_id")) if attr: attr.attributable = self attr.attribute_value = value.get("attribute_value") elif "custom_attribute_id" in value: # this is automatically appended to self._custom_attribute_values # on attributable=self custom_attribute_id = value.get("custom_attribute_id") custom_attribute = referenced_objects.get( "ExternalCustomAttributeDefinition", custom_attribute_id ) _id = value.get("id") _external_id = value.get("external_id") ExternalCustomAttributeValue( id=_id, external_id=_external_id, attributable=self, custom_attribute=custom_attribute, custom_attribute_id=custom_attribute_id, attribute_value=value.get("attribute_value"), ) elif "href" in value: # Ignore setting of custom attribute stubs. Getting here means that the # front-end is not using the API correctly and needs to be updated. logger.info("Ignoring post/put of custom attribute stubs.") else: raise BadRequest("Bad custom attribute value inserted")
def _get_parent_obj(self): """Get parent object specified""" if 'id' not in self._parent_obj: raise exceptions.ValidationError( '"id" is mandatory for parent_obj') if 'type' not in self._parent_obj: raise exceptions.ValidationError( '"type" is mandatory for parent_obj') if self._parent_obj['type'] not in self._allowed_parents: raise exceptions.ValidationError('Allowed types are: {}.'.format( ', '.join(self._allowed_parents))) parent_type = self._parent_obj['type'] parent_id = self._parent_obj['id'] obj = referenced_objects.get(parent_type, parent_id) if not obj: raise ValueError('Parent object not found: {type} {id}'.format( type=parent_type, id=parent_id)) return obj
def _get_parent_obj(self): """Get parent object specified""" if "id" not in self._parent_obj: raise exceptions.ValidationError( "'id' is mandatory for parent_obj") if "type" not in self._parent_obj: raise exceptions.ValidationError( "'type' is mandatory for parent_obj") if self._parent_obj["type"] not in self._allowed_parents: raise exceptions.ValidationError("Allowed types are: {}.".format( ", ".join(self._allowed_parents))) parent_type = self._parent_obj["type"] parent_id = self._parent_obj["id"] obj = referenced_objects.get(parent_type, parent_id) if not obj: raise ValueError("Parent object not found: {type} {id}".format( type=parent_type, id=parent_id)) return obj
def access_control_list(self, values): """Setter function for access control list. Args: values: List of access control roles or dicts containing json representation of custom attribute values. """ if values is None: return new_acl_people_map = defaultdict(set) for value in values: if value["ac_role_id"] not in self.acr_id_acl_map: raise BadRequest(errors.BAD_PARAMS) person = referenced_objects.get("Person", value["person"]["id"]) acl = self.acr_id_acl_map[value["ac_role_id"]] new_acl_people_map[acl].add(person) for acl in self._access_control_list: acl.update_people(new_acl_people_map[acl])
def query_for(cls, rel_class, json_obj, attr_name, uselist): """Resolve the model object instance referred to by the JSON value.""" if uselist: # The value is a collection of links, resolve the collection of objects value = json_obj.get(attr_name) rel_ids = [o[u'id'] for o in value] if value else [] if rel_ids: return db.session.query(rel_class).filter( rel_class.id.in_(rel_ids)).all() else: return [] else: rel_obj = json_obj.get(attr_name) if rel_obj: try: return referenced_objects.get(rel_class, rel_obj["id"]) except TypeError: raise TypeError(''.join(['Failed to convert attribute ', attr_name])) return None
def _get_parent_obj(self): """Get parent object specified""" if 'id' not in self._parent_obj: raise exceptions.ValidationError('"id" is mandatory for parent_obj') if 'type' not in self._parent_obj: raise exceptions.ValidationError( '"type" is mandatory for parent_obj') if self._parent_obj['type'] not in self._allowed_parents: raise exceptions.ValidationError( 'Allowed types are: {}.'.format(', '.join(self._allowed_parents))) parent_type = self._parent_obj['type'] parent_id = self._parent_obj['id'] obj = referenced_objects.get(parent_type, parent_id) if not obj: raise ValueError( 'Parent object not found: {type} {id}'.format(type=parent_type, id=parent_id)) return obj
def _get_documentable_obj(self): """Get documentable object specified""" if 'id' not in self._documentable_obj: raise exceptions.ValidationError('"id" is mandatory' ' for documentable_obj') if 'type' not in self._documentable_obj: raise exceptions.ValidationError( '"type" is mandatory for documentable_obj') if self._documentable_obj['type'] not in self._allowed_documentables: raise exceptions.ValidationError('Allowed types are: {}.'.format( ', '.join(self._allowed_documentables))) doc_type = self._documentable_obj['type'] doc_id = self._documentable_obj['id'] obj = referenced_objects.get(doc_type, doc_id) if not obj: raise ValueError( 'Documentable object not found: {type} {id}'.format( type=doc_type, id=doc_id)) return obj
def __call__(self, obj, json_obj): for field_name, prop_instance in obj.__class__.__dict__.iteritems(): if prop_instance is self: instance = referenced_objects.get(json_obj[field_name]["type"], json_obj[field_name]["id"]) return instance
def prepare(self, data): data = super(FullInstanceContentFased, self).prepare(data) return builder.prepare( referenced_objects.get(data["instance"]["type"], data["instance"]["id"]), data["full_instance_content"])
def test_no_result_in_cache_acp(self, flask_g): """Test case when no result in cache.""" from ggrc.access_control.people import AccessControlPerson from ggrc.utils.referenced_objects import get with patch.object(flask_g, 'referenced_objects', {}): get(AccessControlPerson, self.id_)
def is_identical_revision(self): """Flag if the snapshot has the identical revision.""" instance = referenced_objects.get(self.child_type, self.child_id) return self.revisions and revisions_diff.is_identical_revision( instance, self.revision.content, self.revisions[-1].content)
def _add_ca_value_dicts(self, values): """Add CA dict representations to _custom_attributes_values property. This adds or updates the _custom_attribute_values with the values in the custom attribute values serialized dictionary. Args: values: List of dictionaries that represent custom attribute values. """ from ggrc.utils import referenced_objects from ggrc.models.custom_attribute_value import CustomAttributeValue for value in values: if not value.get("attribute_object_id"): # value.get("attribute_object", {}).get("id") won't help because # value["attribute_object"] can be None value["attribute_object_id"] = (value["attribute_object"].get("id") if value.get("attribute_object") else None) attr = self._values_map.get(value.get("custom_attribute_id")) if attr: attr.attributable = self attr.attribute_value = value.get("attribute_value") attr.attribute_object_id = value.get("attribute_object_id") elif "custom_attribute_id" in value: # this is automatically appended to self._custom_attribute_values # on attributable=self custom_attribute_id = value.get("custom_attribute_id") custom_attribute = referenced_objects.get( "CustomAttributeDefinition", custom_attribute_id ) attribute_object = value.get("attribute_object") if attribute_object is None: CustomAttributeValue( attributable=self, custom_attribute=custom_attribute, custom_attribute_id=custom_attribute_id, attribute_value=value.get("attribute_value"), attribute_object_id=value.get("attribute_object_id"), ) elif isinstance(attribute_object, dict): attribute_object_type = attribute_object.get("type") attribute_object_id = attribute_object.get("id") attribute_object = referenced_objects.get( attribute_object_type, attribute_object_id ) cav = CustomAttributeValue( attributable=self, custom_attribute=custom_attribute, custom_attribute_id=custom_attribute_id, attribute_value=value.get("attribute_value") ) cav.attribute_object = attribute_object else: raise BadRequest("Bad custom attribute value inserted") elif "href" in value: # Ignore setting of custom attribute stubs. Getting here means that the # front-end is not using the API correctly and needs to be updated. logger.info("Ignoring post/put of custom attribute stubs.") else: raise BadRequest("Bad custom attribute value inserted")
def foo(): referenced_objects.rewarm_cache() revisions_diff.rewarm_latest_content() instance = referenced_objects.get(self.resource_type, self.resource_id) if instance: return revisions_diff.prepare(instance, self.content)
def _add_ca_value_dicts(self, values): """Add CA dict representations to _custom_attributes_values property. This adds or updates the _custom_attribute_values with the values in the custom attribute values serialized dictionary. Args: values: List of dictionaries that represent custom attribute values. """ from ggrc.utils import referenced_objects from ggrc.models.custom_attribute_value import CustomAttributeValue for value in values: # TODO: decompose to smaller methods # TODO: remove complicated nested conditions, better to use # instant exception raising if not value.get("attribute_object_id"): # value.get("attribute_object", {}).get("id") won't help because # value["attribute_object"] can be None value["attribute_object_id"] = ( value["attribute_object"].get("id") if value.get("attribute_object") else None) attr = self._values_map.get(value.get("custom_attribute_id")) if attr: attr.attributable = self attr.attribute_value = value.get("attribute_value") attr.attribute_object_id = value.get("attribute_object_id") elif "custom_attribute_id" in value: # this is automatically appended to self._custom_attribute_values # on attributable=self custom_attribute_id = value.get("custom_attribute_id") custom_attribute = referenced_objects.get( "CustomAttributeDefinition", custom_attribute_id) attribute_object = value.get("attribute_object") if attribute_object is None: CustomAttributeValue( attributable=self, custom_attribute=custom_attribute, custom_attribute_id=custom_attribute_id, attribute_value=value.get("attribute_value"), attribute_object_id=value.get("attribute_object_id"), ) elif isinstance(attribute_object, dict): attribute_object_type = attribute_object.get("type") attribute_object_id = attribute_object.get("id") attribute_object = referenced_objects.get( attribute_object_type, attribute_object_id) cav = CustomAttributeValue( attributable=self, custom_attribute=custom_attribute, custom_attribute_id=custom_attribute_id, attribute_value=value.get("attribute_value"), attribute_object_id=value.get("attribute_object_id"), ) cav.attribute_object = attribute_object else: raise BadRequest("Bad custom attribute value inserted") elif "href" in value: # Ignore setting of custom attribute stubs. Getting here means that the # front-end is not using the API correctly and needs to be updated. logger.info("Ignoring post/put of custom attribute stubs.") else: raise BadRequest("Bad custom attribute value inserted")