def post(self): # Obtem o body da request xml = self.request.body # Transforma em etree raiz = etree.parse(StringIO(xml)) # Extrai a tag do método da request tag = extrair_tag(raiz.getroot().getchildren()[0].getchildren()[0]) # Chama o método respectivo para a tag print 'Metodo:', tag getattr(self, tag)(raiz)
def assinar_etree(self, raiz, retorna_xml=False): # Extrai a tag do elemento raiz tipo = extrair_tag(raiz.getroot()) # doctype compatível com o tipo da tag raiz if tipo == u'NFe': doctype = u'<!DOCTYPE NFe [<!ATTLIST infNFe Id ID #IMPLIED>]>' elif tipo == u'inutNFe': doctype = u'<!DOCTYPE inutNFe [<!ATTLIST infInut Id ID #IMPLIED>]>' elif tipo == u'cancNFe': doctype = u'<!DOCTYPE cancNFe [<!ATTLIST infCanc Id ID #IMPLIED>]>' elif tipo == u'DPEC': doctype = u'<!DOCTYPE DPEC [<!ATTLIST infDPEC Id ID #IMPLIED>]>' # Tag de assinatura if raiz.getroot().find('Signature') is None: signature = etree.Element( '{%s}Signature' % NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id'], nsmap={'sig': NAMESPACE_SIG}, ) signed_info = etree.SubElement(signature, '{%s}SignedInfo' % NAMESPACE_SIG) etree.SubElement( signed_info, 'CanonicalizationMethod', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement( signed_info, 'SignatureMethod', Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1") reference = etree.SubElement( signed_info, '{%s}Reference' % NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id']) transforms = etree.SubElement( reference, 'Transforms', URI=raiz.getroot().getchildren()[0].attrib['Id']) etree.SubElement( transforms, 'Transform', Algorithm= "http://www.w3.org/2000/09/xmldsig#enveloped-signature") etree.SubElement( transforms, 'Transform', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement( reference, '{%s}DigestMethod' % NAMESPACE_SIG, Algorithm="http://www.w3.org/2000/09/xmldsig#sha1") digest_value = etree.SubElement(reference, '{%s}DigestValue' % NAMESPACE_SIG) signature_value = etree.SubElement( signature, '{%s}SignatureValue' % NAMESPACE_SIG) key_info = etree.SubElement(signature, '{%s}KeyInfo' % NAMESPACE_SIG) x509_data = etree.SubElement(key_info, '{%s}X509Data' % NAMESPACE_SIG) x509_certificate = etree.SubElement( x509_data, '{%s}X509Certificate' % NAMESPACE_SIG) raiz.getroot().insert(0, signature) # Acrescenta a tag de doctype (como o lxml nao suporta alteracao do doctype, # converte para string para faze-lo) xml = etree.tostring(raiz, xml_declaration=True, encoding='utf-8') if xml.find('<!DOCTYPE ') == -1: pos = xml.find('>') + 1 xml = xml[:pos] + doctype + xml[pos:] #raiz = etree.parse(StringIO(xml)) doc_xml, ctxt, noh_assinatura, assinador = self._antes_de_assinar_ou_verificar( raiz) # Realiza a assinatura assinador.sign(noh_assinatura) # Coloca na instância Signature os valores calculados digest_value.text = ctxt.xpathEval( u'//sig:DigestValue')[0].content.replace(u'\n', u'') signature_value.text = ctxt.xpathEval( u'//sig:SignatureValue')[0].content.replace(u'\n', u'') # Provavelmente retornarão vários certificados, já que o xmlsec inclui a cadeia inteira certificados = ctxt.xpathEval(u'//sig:X509Data/sig:X509Certificate') x509_certificate.text = certificados[len(certificados) - 1].content.replace(u'\n', u'') resultado = assinador.status == xmlsec.DSigStatusSucceeded # Gera o XML para retornar xml = doc_xml.serialize() # Limpa objetos da memoria e desativa funções criptográficas self._depois_de_assinar_ou_verificar(doc_xml, ctxt, assinador) if retorna_xml: return xml else: return etree.parse(StringIO(xml))
def assinar_etree(self, raiz, retorna_xml=False): # Extrai a tag do elemento raiz tipo = extrair_tag(raiz.getroot()) # doctype compatível com o tipo da tag raiz if tipo == u'NFe': doctype = u'<!DOCTYPE NFe [<!ATTLIST infNFe Id ID #IMPLIED>]>' elif tipo == u'inutNFe': doctype = u'<!DOCTYPE inutNFe [<!ATTLIST infInut Id ID #IMPLIED>]>' elif tipo == u'cancNFe': doctype = u'<!DOCTYPE cancNFe [<!ATTLIST infCanc Id ID #IMPLIED>]>' elif tipo == u'DPEC': doctype = u'<!DOCTYPE DPEC [<!ATTLIST infDPEC Id ID #IMPLIED>]>' # Tag de assinatura if raiz.getroot().find('Signature') is None: signature = etree.Element( '{%s}Signature'%NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id'], nsmap={'sig': NAMESPACE_SIG}, ) signed_info = etree.SubElement(signature, '{%s}SignedInfo'%NAMESPACE_SIG) etree.SubElement(signed_info, 'CanonicalizationMethod', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement(signed_info, 'SignatureMethod', Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1") reference = etree.SubElement(signed_info, '{%s}Reference'%NAMESPACE_SIG, URI=raiz.getroot().getchildren()[0].attrib['Id']) transforms = etree.SubElement(reference, 'Transforms', URI=raiz.getroot().getchildren()[0].attrib['Id']) etree.SubElement(transforms, 'Transform', Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature") etree.SubElement(transforms, 'Transform', Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315") etree.SubElement(reference, '{%s}DigestMethod'%NAMESPACE_SIG, Algorithm="http://www.w3.org/2000/09/xmldsig#sha1") digest_value = etree.SubElement(reference, '{%s}DigestValue'%NAMESPACE_SIG) signature_value = etree.SubElement(signature, '{%s}SignatureValue'%NAMESPACE_SIG) key_info = etree.SubElement(signature, '{%s}KeyInfo'%NAMESPACE_SIG) x509_data = etree.SubElement(key_info, '{%s}X509Data'%NAMESPACE_SIG) x509_certificate = etree.SubElement(x509_data, '{%s}X509Certificate'%NAMESPACE_SIG) raiz.getroot().insert(0, signature) # Acrescenta a tag de doctype (como o lxml nao suporta alteracao do doctype, # converte para string para faze-lo) xml = etree.tostring(raiz, xml_declaration=True, encoding='utf-8') if xml.find('<!DOCTYPE ') == -1: pos = xml.find('>') + 1 xml = xml[:pos] + doctype + xml[pos:] #raiz = etree.parse(StringIO(xml)) doc_xml, ctxt, noh_assinatura, assinador = self._antes_de_assinar_ou_verificar(raiz) # Realiza a assinatura assinador.sign(noh_assinatura) # Coloca na instância Signature os valores calculados digest_value.text = ctxt.xpathEval(u'//sig:DigestValue')[0].content.replace(u'\n', u'') signature_value.text = ctxt.xpathEval(u'//sig:SignatureValue')[0].content.replace(u'\n', u'') # Provavelmente retornarão vários certificados, já que o xmlsec inclui a cadeia inteira certificados = ctxt.xpathEval(u'//sig:X509Data/sig:X509Certificate') x509_certificate.text = certificados[len(certificados)-1].content.replace(u'\n', u'') resultado = assinador.status == xmlsec.DSigStatusSucceeded # Gera o XML para retornar xml = doc_xml.serialize() # Limpa objetos da memoria e desativa funções criptográficas self._depois_de_assinar_ou_verificar(doc_xml, ctxt, assinador) if retorna_xml: return xml else: return etree.parse(StringIO(xml))