|
|
@ -64,20 +64,20 @@ class AssinaturaA1(Assinatura): |
|
|
except Exception as e: |
|
|
except Exception as e: |
|
|
raise e |
|
|
raise e |
|
|
|
|
|
|
|
|
def assinarNfse(self, xml, xpath='/GerarNfseEnvio/ns1:Rps', retorna_string=False): |
|
|
|
|
|
|
|
|
def assinarNfse(self, xml, xpath='.//ns1:InfDeclaracaoPrestacaoServico', |
|
|
|
|
|
tag='InfDeclaracaoPrestacaoServico', retorna_string=False, |
|
|
|
|
|
namespaces=None): |
|
|
try: |
|
|
try: |
|
|
xml = etree.fromstring(xml) |
|
|
xml = etree.fromstring(xml) |
|
|
|
|
|
namespaces = xml.nsmap if namespaces is None else namespaces |
|
|
# No raiz do XML de saida |
|
|
# No raiz do XML de saida |
|
|
tag = 'InfDeclaracaoPrestacaoServico' # tag que será assinada |
|
|
|
|
|
raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') |
|
|
raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') |
|
|
siginfo = etree.SubElement(raiz, 'SignedInfo') |
|
|
siginfo = etree.SubElement(raiz, 'SignedInfo') |
|
|
etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') |
|
|
etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') |
|
|
# Tenta achar a tag infNFe |
|
|
|
|
|
# TODO a proxima linha nao eh encontrada pq precisa colocar o namespace, GerarNfseEnvio. |
|
|
|
|
|
|
|
|
# Tenta achar a tag |
|
|
ref = etree.SubElement(siginfo, 'Reference', URI='#' + |
|
|
ref = etree.SubElement(siginfo, 'Reference', URI='#' + |
|
|
xml.xpath(xpath + '/ns1:InfDeclaracaoPrestacaoServico', namespaces={'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws'})[0].attrib['Id']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xml.xpath(xpath, namespaces=namespaces)[0].attrib['Id']) |
|
|
trans = etree.SubElement(ref, 'Transforms') |
|
|
trans = etree.SubElement(ref, 'Transforms') |
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') |
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') |
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
@ -87,59 +87,26 @@ class AssinaturaA1(Assinatura): |
|
|
keyinfo = etree.SubElement(raiz, 'KeyInfo') |
|
|
keyinfo = etree.SubElement(raiz, 'KeyInfo') |
|
|
etree.SubElement(keyinfo, 'X509Data') |
|
|
etree.SubElement(keyinfo, 'X509Data') |
|
|
|
|
|
|
|
|
rps = xml.xpath(xpath, namespaces={'ns1': 'http://www.betha.com.br/e-nota-contribuinte-ws'})[0] |
|
|
|
|
|
|
|
|
rps = xml.xpath(xpath+'/..', namespaces=namespaces)[0] |
|
|
rps.append(raiz) |
|
|
rps.append(raiz) |
|
|
|
|
|
|
|
|
# Escreve no arquivo depois de remover caracteres especiais e parse string |
|
|
# Escreve no arquivo depois de remover caracteres especiais e parse string |
|
|
with open('nfse.xml', 'w') as arquivo: |
|
|
with open('nfse.xml', 'w') as arquivo: |
|
|
arquivo.write(remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False).replace('ns1:', '').replace(':ns1', ''))) |
|
|
|
|
|
|
|
|
texto = remover_acentos(etree.tostring(xml, encoding="unicode", pretty_print=False)) |
|
|
|
|
|
# se for tag do Betha |
|
|
|
|
|
if tag == 'InfDeclaracaoPrestacaoServico': |
|
|
|
|
|
texto = texto.replace('ns1:', '').replace(':ns1', '') |
|
|
|
|
|
arquivo.write(texto) |
|
|
|
|
|
|
|
|
subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'funfa.xml', '--id-attr:Id', tag, 'nfse.xml']) |
|
|
|
|
|
xml = etree.parse('funfa.xml').getroot() |
|
|
|
|
|
|
|
|
|
|
|
if retorna_string: |
|
|
|
|
|
return etree.tostring(xml, encoding="unicode", pretty_print=False) |
|
|
|
|
|
else: |
|
|
|
|
|
return xml |
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
|
|
|
def assinarLoteNfse(self, lote, retorna_string=False): |
|
|
|
|
|
try: |
|
|
|
|
|
# Assina a nota |
|
|
|
|
|
lote = self.assinarNfse(xml=lote, xpath='/EnviarLoteRpsSincronoEnvio/ns1:LoteRps/ns1:ListaRps/ns1:Rps', retorna_string=True) |
|
|
|
|
|
# Assina o lote |
|
|
|
|
|
lote = etree.fromstring(lote) |
|
|
|
|
|
# No raiz do XML de saida |
|
|
|
|
|
tag = 'LoteRps' # tag que será assinada |
|
|
|
|
|
raiz = etree.Element('Signature', xmlns='http://www.w3.org/2000/09/xmldsig#') |
|
|
|
|
|
siginfo = etree.SubElement(raiz, 'SignedInfo') |
|
|
|
|
|
etree.SubElement(siginfo, 'CanonicalizationMethod', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
|
|
|
etree.SubElement(siginfo, 'SignatureMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1') |
|
|
|
|
|
# Tenta achar a tag LoteRps |
|
|
|
|
|
ref = etree.SubElement(siginfo, 'Reference', URI='#' + lote[0].attrib['Id']) |
|
|
|
|
|
trans = etree.SubElement(ref, 'Transforms') |
|
|
|
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/2000/09/xmldsig#enveloped-signature') |
|
|
|
|
|
etree.SubElement(trans, 'Transform', Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315') |
|
|
|
|
|
etree.SubElement(ref, 'DigestMethod', Algorithm='http://www.w3.org/2000/09/xmldsig#sha1') |
|
|
|
|
|
etree.SubElement(ref, 'DigestValue') |
|
|
|
|
|
etree.SubElement(raiz, 'SignatureValue') |
|
|
|
|
|
keyinfo = etree.SubElement(raiz, 'KeyInfo') |
|
|
|
|
|
etree.SubElement(keyinfo, 'X509Data') |
|
|
|
|
|
|
|
|
|
|
|
lote.append(raiz) |
|
|
|
|
|
|
|
|
|
|
|
# Escreve no arquivo depois de remover caracteres especiais e parse string |
|
|
|
|
|
with open('nfse.xml', 'w') as arquivo: |
|
|
|
|
|
arquivo.write(remover_acentos(etree.tostring(lote, encoding="unicode", pretty_print=False).replace('ns1:', '').replace(':ns1', ''))) |
|
|
|
|
|
|
|
|
|
|
|
subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, '--pwd', self.senha, '--crypto', 'openssl', '--output', 'lote.xml', '--id-attr:Id', tag, 'nfse.xml']) |
|
|
|
|
|
xml = etree.parse('lote.xml').getroot() |
|
|
|
|
|
|
|
|
subprocess.call(['xmlsec1', '--sign', '--pkcs12', self.certificado, |
|
|
|
|
|
'--pwd', self.senha, '--crypto', 'openssl', '--output', |
|
|
|
|
|
'nfse.xml', '--id-attr:Id', tag, '--trusted-pem', 'cert.pem', 'nfse.xml']) |
|
|
|
|
|
|
|
|
if retorna_string: |
|
|
if retorna_string: |
|
|
return etree.tostring(xml, encoding="unicode", pretty_print=False) |
|
|
|
|
|
|
|
|
return open('nfse.xml', 'r').read() |
|
|
else: |
|
|
else: |
|
|
return xml |
|
|
|
|
|
|
|
|
return etree.parse('nfse.xml').getroot() |
|
|
except Exception as e: |
|
|
except Exception as e: |
|
|
raise e |
|
|
raise e |
|
|
|
|
|
|
|
|
|