def add_iso_md_element(xml_obj: _Element, new_link: str): """ Adds a new MetadataURL element to the parent xml_obj Args: xml_obj (_Element): The parent xml object which holds all MetadataURL elements new_link (str): The link of the new metadata resource Returns: nothing """ iso_elem = etree.Element("MetadataURL", {"type": "ISO19115:2003"}, nsmap={"xlink": "http://www.w3.org/1999/xlink"}) iso_elem_format = etree.SubElement(iso_elem, "Format") iso_elem_format.text = "text/xml" iso_elem_resource = etree.SubElement( iso_elem, "OnlineResource", { "{http://www.w3.org/1999/xlink}type": "simple", "{http://www.w3.org/1999/xlink}href": new_link }) # try to append where other metadaURL elements might already exist # if there are no other elements -> just append it at the end other_iso_md_elements = try_get_element_from_xml("./MetadataURL", xml_obj) if len(other_iso_md_elements): index = 0 for other_iso in other_iso_md_elements: i = xml_obj.index(other_iso) if i > index: index = i index += 1 xml_obj.insert(index, iso_elem) else: xml_obj.append(iso_elem)
def sign( *, element: Element, private_key: RSAPrivateKey, certificate: Certificate, config: SigningConfig = SigningConfig.default(), index: int = 0, ) -> bytes: try: element_id = element.attrib["ID"] except KeyError: raise NoIDAttribute(element) # Generate the digest value of the element/content to be signed content_digest_value = utils.ascii_b64( utils.hash_digest(config.digest_method, utils.serialize_xml(element))) # Build the SignedInfo tag, referencing the element we got passed, # including the digest value we just created. signed_info = ds.SignedInfo( ds.CanonicalizationMethod(Algorithm=XML_EXC_C14N), ds.SignatureMethod(Algorithm=utils.signature_method_algorithm( config.signature_method)), ds.Reference( ds.Transforms( ds.Transform(Algorithm=XMLDSIG_ENVELOPED_SIGNATURE), ds.Transform(Algorithm=XML_EXC_C14N), ), ds.DigestMethod( Algorithm=utils.digest_method_algorithm(config.digest_method)), ds.DigestValue(content_digest_value), # Embed the digest value URI="#" + element_id, # Reference the element to sign ), ) # Sign the digest of the SignedInfo element signature = utils.sign(utils.serialize_xml(signed_info), private_key, config.signature_method) signature_value = utils.ascii_b64(signature) # Encode the certificate to embed into the signature. cert_data = utils.ascii_b64(certificate.public_bytes(Encoding.DER)) signature_element = ds.Signature( signed_info, ds.SignatureValue(signature_value), ds.KeyInfo(ds.X509Data(ds.X509Certificate(cert_data))), ) element.insert(index, signature_element) root = utils.get_root(element) result = utils.serialize_xml(root) element.remove(signature_element) return result
def create_subelement(xml_elem: _Element, tag_name, after: str = None, attrib: dict = None, nsmap: dict = {}): """ Creates a new xml element as a child of xml_elem with the name tag_name Args: xml_elem: The xml element tag_name: The tag name for the new element after (str): The tag name of the element after which the new one should be inserted attrib: The attribute dict for the new element Returns: A new subelement of xml_elem """ ret_element = etree.Element(tag_name, attrib=attrib, nsmap=nsmap) if after is not None: after_element = try_get_single_element_from_xml("./{}".format(after), xml_elem) after_element_index = xml_elem.index(after_element) + 1 xml_elem.insert(after_element_index, ret_element) else: xml_elem.append(ret_element) return ret_element
def add_subelement(parent_elem: _Element, sub_element: _Element, after: str = None): """ Adds an existing xml element after Args: parent_elem: The parent xml element sub_element: The sub xml element Returns: parent_elem: The modified xml element, holding the subelement as a child """ if after is not None: after_element = try_get_single_element_from_xml("./{}".format(after), parent_elem) if after_element is None: # If this element could not be found, we append this element at the end after_element_index = -1 else: after_element_index = parent_elem.index(after_element) + 1 parent_elem.insert(after_element_index, sub_element) else: parent_elem.append(sub_element) return parent_elem
def arrange_feed_top_level_element(self, dom: etree._Element, rss_url_prefix: str, parameters: Dict[str, str], favicon_url:str): icons = xpath(dom, "./icon") icon_node: etree._Element if len(icons) == 0: icon_node = etree.Element("icon") dom.insert(0, icon_node) else: icon_node = icons[0] icon_node.text = favicon_url icon = etree.Element("{%s}icon" % NAMESPACES["atom"], nsmap=NAMESPACES) icon.text = favicon_url dom.insert(0, icon) # arrange links in channel other_link_nodes = xpath( dom, "./*[local-name()='link' and @type='application/atom+xml']") for link_node in other_link_nodes: if "href" in link_node.attrib: link_node.attrib["href"] = self._generated_complete_url( rss_url_prefix, parameters) else: link_node.text = self._generated_complete_url( rss_url_prefix, parameters)