def copy_gebruiksrechten(self, source_object: Gebruiksrechten, destination_folder: Folder) -> Gebruiksrechten: """Copy a gebruiksrechten to a folder :param source_object: Gebruiksrechten, the gebruiksrechten to copy :param destination_folder: Folder, the folder in which to place the copied gebruiksrechten :return: the copied object """ # copy the properties from the source object properties = { property_name: property_details["value"] for property_name, property_details in source_object.properties.items() if "cmis:" not in property_name } file_name = get_random_string() properties.update( **{ "cmis:objectTypeId": source_object.objectTypeId, "cmis:name": file_name, mapper("kopie_van", type="gebruiksrechten"): source_object. objectId, # Keep tack of where this is copied from. mapper("uuid", type="gebruiksrechten"): str(uuid.uuid4()), }) data = create_json_request_body(destination_folder, properties) logger.debug("CMIS_ADAPTER: copy_gebruiksrechten: request data: %s", data) json_response = self.post_request(self.root_folder_url, data=data) logger.debug("CMIS_ADAPTER: copy_gebruiksrechten: response data: %s", json_response) return Gebruiksrechten(json_response)
def build_properties(cls, data: dict, new: bool = True) -> dict: props = {} for key, value in data.items(): prop_name = mapper(key, type="document") if not prop_name: logger.debug( "CMIS_ADAPTER: No property name found for key '%s'", key) continue props[prop_name] = value # For documents that are not new, the uuid shouldn't be written props.pop(mapper("uuid"), None) if new: # increase likelihood of uniqueness of title by appending a random string title, suffix = data.get("titel"), get_random_string() if title is not None: props["cmis:name"] = f"{title}-{suffix}" # For new documents, the uuid needs to be set new_uuid = str(uuid.uuid4()) props[mapper("uuid", type="document")] = new_uuid # The identification needs to be set ONLY for newly created documents. # identificatie is immutable once the document is created if not props.get(mapper("identificatie")): prop_name = mapper("identificatie") props[prop_name] = new_uuid return props
def _normalize_filters( self, filters: List[Tuple]) -> Tuple[List[str], List[str]]: """ Normalize the various flavours of ORM filters. Turn dict filters into something that looks like SQL 92 suitable for Alfresco CMIS query. Note that all filters are AND-ed together. Ideally, this would be an implementation of the as_sql for a custom database backend, returning lhs and rhs parts. """ _lhs = [] _rhs = [] # TODO: make this more declarative for key, value in filters: name = mapper(key, type="document") if key == "begin_registratie": # begin_registratie is a LTE filter, so define it as such: column = mapper("begin_registratie", type="document") _lhs.append(f"{column} <= '%s'") _rhs.append(value.isoformat().replace("+00:00", "Z")) continue elif key == "_va_order": continue elif key == "informatieobjecttype": if isinstance(value, list) and len(value) == 0: # In this case there are no authorised informatieobjecttypes _lhs.append("drc:document__informatieobjecttype = '%s'") _rhs.append("") continue else: # In this case there are multiple allowed informatieobjecttypes lhs, rhs = self._build_authorisation_filter(name, value) _lhs.append(lhs) _rhs += rhs continue elif key == "creatiedatum" and value == "": _lhs.append(f"{name} LIKE '%s'") _rhs.append("%-%-%") continue if name is None: raise NotImplementedError( f"Filter on '{key}' is not implemented yet") _rhs.append(value) _lhs.append(f"{name} = '%s'") return _lhs, _rhs
def unlock_document(self, drc_uuid: str, lock: str, force: bool = False) -> Document: """Unlock a document with given uuid :param drc_uuid: string, the value of drc:document__uuid :param lock: string, value of the lock :param force: bool, whether to force the unlocking :return: Document, the unlocked document """ cmis_doc = self.get_document(drc_uuid) if not cmis_doc.isVersionSeriesCheckedOut: raise DocumentNotLockedException( "Document is not checked out and/or locked.") if constant_time_compare(cmis_doc.lock, lock) or force: lock_property = { mapper("lock"): { "value": "", "type": get_cmis_type(EnkelvoudigInformatieObject, "lock"), } } cmis_doc.update_properties(lock_property) return cmis_doc.checkin("Updated via Documenten API") raise LockDidNotMatchException("Lock did not match", code="unlock-failed")
def _normalize_filters( self, filters: List[Tuple]) -> Tuple[List[str], List[str]]: """ Normalize the various flavours of ORM filters. Turn dict filters into something that looks like SQL 92 suitable for Alfresco CMIS query. Note that all filters are AND-ed together. Ideally, this would be an implementation of the as_sql for a custom database backend, returning lhs and rhs parts. """ _lhs = [] _rhs = [] for key, value in filters: name = mapper(key, type="gebruiksrechten") if name is None: raise NotImplementedError( f"Filter on '{key}' is not implemented yet") lhs_filter, rhs_filter = build_filter(name, value) _rhs += rhs_filter _lhs += lhs_filter return _lhs, _rhs
def lock_document(self, drc_uuid: str, lock: str): """Lock a EnkelvoudigInformatieObject with given drc:document__uuid :param drc_uuid: string, the value of drc:document__uuid :param lock: string, value of the lock """ cmis_doc = self.get_document(drc_uuid) already_locked = DocumentLockedException( "Document was already checked out", code="double_lock") try: pwc = cmis_doc.checkout() if pwc.lock: raise already_locked # store the lock value on the PWC so we can compare it later lock_property = { mapper("lock"): { "value": lock, "type": get_cmis_type(EnkelvoudigInformatieObject, "lock"), } } pwc.update_properties(lock_property) except CmisUpdateConflictException as exc: raise already_locked from exc
def check_document_exists(self, identification: Union[str, UUID], bronorganisatie: str) -> None: """Check if a document with the same (identificatie, bronorganisatie) already exists in the repository :param identification: string, document ``identificatie`` :param bronorganisatie: string, document ``bronorganisatie`` """ cmis_identificatie = mapper("identificatie", type="document") cmis_bronorganisatie = mapper("bronorganisatie", type="document") query = CMISQuery( f"SELECT * FROM drc:document WHERE {cmis_identificatie} = '%s' AND {cmis_bronorganisatie} = '%s'" ) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, statement=query(str(identification), bronorganisatie), cmis_action="query", ) logger.debug(soap_envelope.toprettyxml()) try: soap_response = self.request("DiscoveryService", soap_envelope=soap_envelope.toxml()) except CmisRuntimeException as exc: # Corsa raises an error if the query gives no results, while Alfresco a 200 if "objectNotFound" in exc.message: return else: raise exc xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "query") if len(extracted_data) > 0: raise DocumentExistsError( "Een document met dezelfde identificatie en bronorganisatie al bestaat." )
def build_query_filters( filters: dict, object_type: str = None, filter_string: str = "", strip_end: bool = False, ): """Build filters for SQL query""" from drc_cmis.utils.mapper import mapper if filters: for key, value in filters.items(): if object_type is None: if mapper(key): key = mapper(key) elif mapper(key, type="connection"): key = mapper(key, type="connection") elif mapper(key, type="gebruiksrechten"): key = mapper(key, type="gebruiksrechten") elif mapper(key, type="oio"): key = mapper(key, type="oio") else: key = mapper(key, type=object_type) if value and value in ["NULL", "NOT NULL"]: filter_string += f"{key} IS {value} AND " elif isinstance(value, Decimal): filter_string += f"{key} = {value} AND " elif isinstance(value, list): if len(value) == 0: continue filter_string += "( " for item in value: sub_filter_string = build_query_filters({key: item}, strip_end=True) filter_string += f"{sub_filter_string} OR " filter_string = filter_string[:-3] filter_string += " ) AND " elif value: filter_string += f"{key} = '{value}' AND " if strip_end and filter_string[-4:] == "AND ": filter_string = filter_string[:-4] return filter_string
def check_document_exists(self, identification: Union[str, UUID], bronorganisatie: str): """Check if a document with the same (identificatie, bronorganisatie) already exists in the repository""" cmis_identificatie = mapper("identificatie", type="document") cmis_bronorganisatie = mapper("bronorganisatie", type="document") query = CMISQuery( f"SELECT * FROM drc:document WHERE {cmis_identificatie} = '%s' AND {cmis_bronorganisatie} = '%s'" ) data = { "cmisaction": "query", "statement": query(str(identification), bronorganisatie), } logger.debug("CMIS_ADAPTER: check_document_exists: request data: %s", data) json_response = self.post_request(self.base_url, data) logger.debug("CMIS_ADAPTER: check_document_exists: response data: %s", json_response) if json_response["numItems"] > 0: raise DocumentExistsError( "Een document met dezelfde identificatie en bronorganisatie al bestaat." )
def unlock_document(self, drc_uuid: str, lock: str, force: bool = False) -> Document: """Unlock a document with objectId workspace://SpacesStore/<uuid>""" cmis_doc = self.get_document(drc_uuid) pwc = cmis_doc.get_private_working_copy() if constant_time_compare(pwc.lock, lock) or force: pwc.update_properties({mapper("lock"): ""}) new_doc = pwc.checkin("Updated via Documenten API") return new_doc raise LockDidNotMatchException("Lock did not match", code="unlock-failed")
def build_properties(cls, data: dict) -> dict: """Construct property dictionary.""" props = {} for key, value in data.items(): prop_name = mapper(key, type=cls.type_name) if not prop_name: logger.debug( "CMIS_ADAPTER: No property name found for key '%s'", key) continue if value is not None: if isinstance(value, datetime.date) or isinstance( value, datetime.date): value = value.strftime("%Y-%m-%dT%H:%M:%S.000Z") props[prop_name] = str(value) return props
def copy_document(self, document: Document, destination_folder: Folder) -> Document: """Copy document to a folder :param document: Document, the document to copy :param destination_folder: Folder, the folder in which to place the copied document :return: the copied document """ # copy the properties from the source document properties = { property_name: property_details["value"] for property_name, property_details in document.properties.items() if "cmis:" not in property_name } properties.update( **{ "cmis:objectTypeId": document.objectTypeId, mapper("titel", type="document"): f"{document.titel} - copy", "drc:kopie_van": document.uuid, # Keep tack of where this is copied from. "drc:document__uuid": str(uuid.uuid4()), }) # Update the cmis:name to make it more unique file_name = f"{document.titel}-{get_random_string()}" properties["cmis:name"] = file_name data = create_json_request_body(destination_folder, properties) logger.debug("CMIS_ADAPTER: copy_document: request data: %s", data) content = document.get_content_stream() json_response = self.post_request(self.root_folder_url, data=data) logger.debug("CMIS_ADAPTER: copy_document: response data: %s", json_response) cmis_doc = Document(json_response) content.seek(0) return cmis_doc.set_content_stream(content, filename=document.bestandsnaam)
def build_properties(cls, data: dict) -> dict: """Construct property dictionary. The structure of the dictionary is (where ``property_name``, ``property_value`` and ``property_type`` are the name, value and type of the property): .. code-block:: python properties = { "property_name": { "value": property_value, "type": property_type, } } """ config = CMISConfig.objects.get() props = {} for key, value in data.items(): prop_name = mapper(key, type=cls.type_name) if not prop_name: logger.debug("CMIS_ADAPTER: No property name found for key '%s'", key) continue if value is not None: prop_type = get_cmis_type(cls.type_class, key) if ( get_type(cls.type_class, key) == QueriableUrl and settings.CMIS_URL_MAPPING_ENABLED ): value = shrink_url(value) elif isinstance(value, datetime.datetime): value = value.astimezone(pytz.timezone(config.time_zone)).strftime( "%Y-%m-%dT%H:%M:%S.000Z" ) elif isinstance(value, datetime.date): # In CMIS, there is no propertyDate, only propertyDateTime. # So dates need to be in the datetime format value = value.strftime("%Y-%m-%dT00:00:00.000Z") props[prop_name] = {"value": str(value), "type": prop_type} return props
def lock_document(self, drc_uuid: str, lock: str): """ Check out the CMIS document and store the lock value for check in/unlock. """ cmis_doc = self.get_document(drc_uuid) already_locked = DocumentLockedException( "Document was already checked out", code="double_lock") try: pwc = cmis_doc.checkout() except CmisInvalidArgumentException: raise already_locked if pwc.lock: raise already_locked try: # store the lock value on the PWC so we can compare it later pwc.update_properties({mapper("lock"): lock}) except CmisUpdateConflictException as exc: raise already_locked from exc
def create_content_object( self, data: dict, object_type: str, destination_folder: Folder = None) -> CMISContentObject: """Create a Gebruiksrechten or a ObjectInformatieObject :param data: dict, properties of the object to create :param object_type: string, either "gebruiksrechten" or "oio" :param destination_folder: Folder, a folder where to create the object. If not provided, the object will be placed in a temporary folder. :return: Either a Gebruiksrechten or ObjectInformatieObject """ assert object_type in [ "gebruiksrechten", "oio", ], "'object_type' can be only 'gebruiksrechten' or 'oio'" if destination_folder is None: other_folder = self.get_or_create_other_folder() destination_folder = self.get_or_create_folder( "Related data", other_folder) properties = { mapper(key, type=object_type): value for key, value in data.items() if mapper(key, type=object_type) } json_data = { "objectId": destination_folder.objectId, "cmisaction": "createDocument", "propertyId[0]": "cmis:name", "propertyValue[0]": get_random_string(), "propertyId[1]": f"drc:{object_type}__uuid", "propertyValue[1]": str(uuid.uuid4()), } json_data["propertyId[2]"] = "cmis:objectTypeId" if "cmis:objectTypeId" in properties.keys(): json_data["propertyValue[2]"] = properties.pop("cmis:objectTypeId") else: json_data[ "propertyValue[2]"] = f"{self.get_object_type_id_prefix(object_type)}drc:{object_type}" prop_count = 3 for prop_key, prop_value in properties.items(): if isinstance(prop_value, datetime.date): prop_value = prop_value.strftime("%Y-%m-%dT%H:%M:%S.000Z") json_data[f"propertyId[{prop_count}]"] = prop_key json_data[f"propertyValue[{prop_count}]"] = prop_value prop_count += 1 logger.debug("CMIS_ADAPTER: create_content_object: request data: %s", json_data) json_response = self.post_request(self.root_folder_url, data=json_data) logger.debug("CMIS_ADAPTER: create_content_object: response data: %s", json_response) if object_type == "gebruiksrechten": return Gebruiksrechten(json_response) elif object_type == "oio": return ObjectInformatieObject(json_response)
def test_mapper_get_gebruiksrechten(self): self.assertIs(mapper("informatieobject"), None) self.assertEqual( mapper("informatieobject", "gebruiksrechten"), "drc:gebruiksrechten__informatieobject", )
def test_mapper_get_oio(self): self.assertIs(mapper("informatieobject"), None) self.assertEqual(mapper("informatieobject", "oio"), "drc:oio__informatieobject")
def test_mapper_get_unknown(self): self.assertIsNone(mapper("identificatie", "unknown"))
def create_content_object( self, data: dict, object_type: str, destination_folder: Folder = None) -> CMISContentObject: """Create a Gebruiksrechten or a ObjectInformatieObject :param data: dict, properties of the object to create :param object_type: string, either "gebruiksrechten" or "oio" :param destination_folder: Folder, the folder in which to place the object :return: Either a Gebruiksrechten or ObjectInformatieObject """ assert object_type in [ "gebruiksrechten", "oio", ], "'object_type' can be only 'gebruiksrechten' or 'oio'" if object_type == "oio": return_type = ObjectInformatieObject data_class = Oio elif object_type == "gebruiksrechten": return_type = Gebruiksrechten data_class = GebruiksRechtDoc if destination_folder is None: other_folder = self.get_or_create_other_folder() destination_folder = self.get_or_create_folder( "Related data", other_folder) properties = return_type.build_properties(data) properties.setdefault( "cmis:objectTypeId", { "value": f"{self.get_object_type_id_prefix(object_type)}drc:{object_type}", "type": "propertyId", }, ) properties.setdefault("cmis:name", { "value": get_random_string(), "type": "propertyString" }) properties.setdefault( mapper("uuid", type=object_type), { "value": str(uuid.uuid4()), "type": get_cmis_type(data_class, "uuid") }, ) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=properties, cmis_action="createDocument", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), ) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] new_object_id = extracted_data["properties"]["objectId"]["value"] # Request all the properties of the newly created object soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=new_object_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return return_type(extracted_data)
def copy_gebruiksrechten(self, source_object: Gebruiksrechten, destination_folder: Folder) -> Gebruiksrechten: """Copy a gebruiksrechten to a folder :param source_object: Gebruiksrechten, the gebruiksrechten to copy :param destination_folder: Folder, the folder in which to place the copied gebruiksrechten :return: the copied object """ # copy the properties from the source document drc_properties = {} drc_url_properties = {} for property_name, property_details in source_object.properties.items( ): if ("cmis:" not in property_name and property_details["value"] is not None) or property_name == "cmis:objectTypeId": drc_property_name = reverse_mapper(property_name, type="gebruiksrechten") # Urls are handled separately, because they are already in the 'short' form if get_type(GebruiksRechtDoc, drc_property_name) == QueriableUrl: drc_url_properties[property_name] = { "value": property_details["value"], "type": "propertyString", } else: drc_properties[drc_property_name] = property_details[ "value"] cmis_properties = Gebruiksrechten.build_properties(drc_properties) cmis_properties.update( **{ "cmis:objectTypeId": { "value": source_object.objectTypeId, "type": "propertyId", }, mapper("kopie_van", type="gebruiksrechten"): { "value": source_object.objectId, "type": "propertyString", # Keep tack of where this is copied from. }, "cmis:name": { "value": get_random_string(), "type": "propertyString" }, "drc:gebruiksrechten__uuid": { "value": str(uuid.uuid4()), "type": "propertyString", }, **drc_url_properties, }) # Create copy gebruiksrechten soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=cmis_properties, cmis_action="createDocument", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), ) # Creating the document only returns its ID xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] copy_gebruiksrechten_id = extracted_data["properties"]["objectId"][ "value"] # Request all the properties of the newly created object soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, object_id=copy_gebruiksrechten_id, cmis_action="getObject", ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request("ObjectService", soap_envelope=soap_envelope.toxml()) xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "getObject")[0] return Gebruiksrechten(extracted_data)
def test_mapper_get_document(self): self.assertEqual(mapper("identificatie"), "drc:document__identificatie") self.assertEqual(mapper("identificatie", "document"), "drc:document__identificatie")
def test_mapper_get_zaak(self): self.assertEqual(mapper("identificatie", "zaak"), "drc:zaak__identificatie")
def copy_document(self, document: Document, destination_folder: Folder) -> Document: """Copy document to a folder :param document: Document, the document to copy :param destination_folder: Folder, the folder in which to place the copied document :return: the copied document """ # copy the properties from the source document drc_properties = {} drc_url_properties = {} for property_name, property_details in document.properties.items(): if ("cmis:" not in property_name and property_details["value"] is not None) or property_name == "cmis:objectTypeId": drc_property_name = reverse_mapper(property_name, type="document") # Urls are handled separately, because they are already in the 'short' form if (get_type(EnkelvoudigInformatieObject, drc_property_name) == QueriableUrl): drc_url_properties[property_name] = { "value": property_details["value"], "type": "propertyString", } else: drc_properties[drc_property_name] = property_details[ "value"] cmis_properties = Document.build_properties(drc_properties, new=False) cmis_properties.update( **{ "cmis:objectTypeId": { "value": document.objectTypeId, "type": "propertyId", }, mapper("titel", type="document"): { "value": f"{document.titel} - copy", "type": "propertyString", }, "drc:kopie_van": { "value": document.uuid, "type": "propertyString", }, # Keep tack of where this is copied from. "drc:document__uuid": { "value": str(uuid.uuid4()), "type": "propertyString", }, **drc_url_properties, }) # Update the cmis:name to make it more unique file_name = f"{document.titel}-{get_random_string()}" cmis_properties["cmis:name"] = { "value": file_name, "type": "propertyString" } # Create copy document content_id = str(uuid.uuid4()) soap_envelope = make_soap_envelope( auth=(self.user, self.password), repository_id=self.main_repo_id, folder_id=destination_folder.objectId, properties=cmis_properties, cmis_action="createDocument", content_id=content_id, content_filename=drc_properties.get("bestandsnaam"), ) logger.debug(soap_envelope.toprettyxml()) soap_response = self.request( "ObjectService", soap_envelope=soap_envelope.toxml(), attachments=[(content_id, document.get_content_stream())], ) # Creating the document only returns its ID xml_response = extract_xml_from_soap(soap_response) logger.debug(pretty_xml(xml_response)) extracted_data = extract_object_properties_from_xml( xml_response, "createDocument")[0] copy_document_id = extracted_data["properties"]["objectId"]["value"] return document.get_document(copy_document_id)
def build_properties(cls, data: dict, new: bool = True) -> dict: """Construct property dictionary. The structure of the dictionary is (where ``property_name``, ``property_value`` and ``property_type`` are the name, value and type of the property): .. code-block:: python properties = { "property_name": { "value": property_value, "type": property_type, } } """ config = CMISConfig.objects.get() props = {} for key, value in data.items(): prop_name = mapper(key, type="document") if not prop_name: logger.debug("CMIS_ADAPTER: No property name found for key '%s'", key) continue if value is not None: prop_type = get_cmis_type(EnkelvoudigInformatieObject, key) if ( settings.CMIS_URL_MAPPING_ENABLED and get_type(EnkelvoudigInformatieObject, key) == QueriableUrl and value != "" ): value = shrink_url(value) elif isinstance(value, datetime.datetime): value = value.astimezone(pytz.timezone(config.time_zone)).strftime( "%Y-%m-%dT%H:%M:%S.000Z" ) elif isinstance(value, datetime.date): # In CMIS, there is no propertyDate, only propertyDateTime. # So dates need to be in the datetime format value = value.strftime("%Y-%m-%dT00:00:00.000Z") elif isinstance(value, bool): value = str(value).lower() props[prop_name] = {"value": str(value), "type": prop_type} # When a Gebruiksrechten object is deleted, the field in the Document needs to be None. elif key == "indicatie_gebruiksrecht": prop_type = get_cmis_type(EnkelvoudigInformatieObject, key) props[prop_name] = {"value": "", "type": prop_type} # For documents that are not new, the uuid shouldn't be written props.pop(mapper("uuid"), None) if new: # increase likelihood of uniqueness of title by appending a random string title, suffix = data.get("titel"), get_random_string() if title is not None: props["cmis:name"] = { "value": f"{title}-{suffix}", "type": get_cmis_type(EnkelvoudigInformatieObject, "name"), } # For new documents, the uuid needs to be set prop_name = mapper("uuid") prop_type = get_cmis_type(EnkelvoudigInformatieObject, "uuid") new_uuid = str(uuid.uuid4()) props[prop_name] = {"value": new_uuid, "type": prop_type} # The identification needs to be set ONLY for newly created documents. # identificatie is immutable once the document is created prop_name = mapper("identificatie") if not props.get(prop_name, {}).get("value"): prop_type = get_cmis_type(EnkelvoudigInformatieObject, "identificatie") props[prop_name] = {"value": new_uuid, "type": prop_type} return props