facho/cli.py: nuevo atribute --use-cache-policy para firmar
FossilOrigin-Name: 7126044e6cfb596ad025ed1b18d6dc951a358d56d6d9778b3223f3b8a9ce2bc8
This commit is contained in:
parent
a917258cee
commit
e369ad2069
13
facho/cli.py
13
facho/cli.py
@ -213,13 +213,17 @@ def validate_invoice(invoice_path):
|
|||||||
@click.option('--private-key', type=click.Path(exists=True))
|
@click.option('--private-key', type=click.Path(exists=True))
|
||||||
@click.option('--passphrase')
|
@click.option('--passphrase')
|
||||||
@click.option('--ssl/--no-ssl', default=False)
|
@click.option('--ssl/--no-ssl', default=False)
|
||||||
|
@click.option('--use-cache-policy/--no-use-cache-policy', default=False)
|
||||||
@click.argument('xmlfile', type=click.Path(exists=True), required=True)
|
@click.argument('xmlfile', type=click.Path(exists=True), required=True)
|
||||||
def sign_xml(private_key, passphrase, xmlfile, ssl=True):
|
def sign_xml(private_key, passphrase, xmlfile, ssl=True, use_cache_policy=False):
|
||||||
if not ssl:
|
if not ssl:
|
||||||
disable_ssl()
|
disable_ssl()
|
||||||
|
|
||||||
from facho import fe
|
from facho import fe
|
||||||
signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase)
|
if use_cache_policy:
|
||||||
|
warnings.warn("xades using cache policy")
|
||||||
|
print(use_cache_policy)
|
||||||
|
signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy)
|
||||||
document = open(xmlfile, 'r').read().encode('utf-8')
|
document = open(xmlfile, 'r').read().encode('utf-8')
|
||||||
print(signer.sign_xml_string(document))
|
print(signer.sign_xml_string(document))
|
||||||
|
|
||||||
@ -229,8 +233,9 @@ def sign_xml(private_key, passphrase, xmlfile, ssl=True):
|
|||||||
@click.option('--passphrase')
|
@click.option('--passphrase')
|
||||||
@click.option('--ssl/--no-ssl', default=False)
|
@click.option('--ssl/--no-ssl', default=False)
|
||||||
@click.option('--sign/--no-sign', default=False)
|
@click.option('--sign/--no-sign', default=False)
|
||||||
|
@click.option('--use-cache-policy/--no-use-cache-policy', default=False)
|
||||||
@click.argument('scriptname', type=click.Path(exists=True), required=True)
|
@click.argument('scriptname', type=click.Path(exists=True), required=True)
|
||||||
def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=True, sign=False):
|
def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=True, sign=False, use_cache_policy=False):
|
||||||
"""
|
"""
|
||||||
imprime xml en pantalla.
|
imprime xml en pantalla.
|
||||||
SCRIPTNAME espera
|
SCRIPTNAME espera
|
||||||
@ -265,7 +270,7 @@ def generate_invoice(private_key, passphrase, scriptname, generate=False, ssl=Tr
|
|||||||
xml.add_extension(extension)
|
xml.add_extension(extension)
|
||||||
|
|
||||||
if sign:
|
if sign:
|
||||||
signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase)
|
signer = fe.DianXMLExtensionSigner(private_key, passphrase=passphrase, mockpolicy=use_cache_policy)
|
||||||
xml.add_extension(signer)
|
xml.add_extension(signer)
|
||||||
|
|
||||||
print(xml.tostring(xml_declaration=True))
|
print(xml.tostring(xml_declaration=True))
|
||||||
|
BIN
facho/fe/data/dian/politicadefirmav2.pdf
Normal file
BIN
facho/fe/data/dian/politicadefirmav2.pdf
Normal file
Binary file not shown.
@ -181,9 +181,10 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf'
|
POLICY_ID = 'https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf'
|
||||||
POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.'
|
POLICY_NAME = u'Política de firma para facturas electrónicas de la República de Colombia.'
|
||||||
|
|
||||||
def __init__(self, pkcs12_path, passphrase=None):
|
def __init__(self, pkcs12_path, passphrase=None, mockpolicy=False):
|
||||||
self._pkcs12_path = pkcs12_path
|
self._pkcs12_path = pkcs12_path
|
||||||
self._passphrase = None
|
self._passphrase = None
|
||||||
|
self._mockpolicy = mockpolicy
|
||||||
if passphrase:
|
if passphrase:
|
||||||
self._passphrase = passphrase.encode('utf-8')
|
self._passphrase = passphrase.encode('utf-8')
|
||||||
|
|
||||||
@ -216,7 +217,7 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
)
|
)
|
||||||
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
|
xmlsig.template.add_transform(ref, xmlsig.constants.TransformEnveloped)
|
||||||
|
|
||||||
id_keyinfo = "%s-KeyInfo" % (id_uuid)
|
id_keyinfo = "xmldsig-%s-KeyInfo" % (id_uuid)
|
||||||
xmlsig.template.add_reference(
|
xmlsig.template.add_reference(
|
||||||
signature, xmlsig.constants.TransformSha256, uri="#%s" % (id_keyinfo),
|
signature, xmlsig.constants.TransformSha256, uri="#%s" % (id_keyinfo),
|
||||||
)
|
)
|
||||||
@ -255,8 +256,24 @@ class DianXMLExtensionSigner(FachoXMLExtension):
|
|||||||
ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(open(self._pkcs12_path, 'rb').read(),
|
ctx.load_pkcs12(OpenSSL.crypto.load_pkcs12(open(self._pkcs12_path, 'rb').read(),
|
||||||
self._passphrase))
|
self._passphrase))
|
||||||
|
|
||||||
ctx.sign(signature)
|
if self._mockpolicy:
|
||||||
ctx.verify(signature)
|
from mock import patch
|
||||||
|
import os.path
|
||||||
|
with patch('xades.policy.urllib.urlopen') as mock:
|
||||||
|
class UrllibPolicyMock:
|
||||||
|
def read(self):
|
||||||
|
cur_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
data_dir = os.path.join(cur_dir, 'data', 'dian')
|
||||||
|
policy_file = os.path.join(data_dir, 'politicadefirmav2.pdf')
|
||||||
|
with open(policy_file, 'rb') as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
mock.return_value = UrllibPolicyMock()
|
||||||
|
ctx.sign(signature)
|
||||||
|
ctx.verify(signature)
|
||||||
|
else:
|
||||||
|
ctx.sign(signature)
|
||||||
|
ctx.verify(signature)
|
||||||
#xmlsig take parent root
|
#xmlsig take parent root
|
||||||
xml.remove(signature)
|
xml.remove(signature)
|
||||||
return signature
|
return signature
|
||||||
|
3
setup.py
3
setup.py
@ -18,6 +18,7 @@ requirements = ['Click>=6.0',
|
|||||||
'pyOpenSSL>=19.1.0',
|
'pyOpenSSL>=19.1.0',
|
||||||
'xmlsig>=0.1.3',
|
'xmlsig>=0.1.3',
|
||||||
'xades>=0.2.1',
|
'xades>=0.2.1',
|
||||||
|
'mock==2.0.0',
|
||||||
'xmlsec>=1.3.8']
|
'xmlsec>=1.3.8']
|
||||||
|
|
||||||
setup_requirements = ['pytest-runner', ]
|
setup_requirements = ['pytest-runner', ]
|
||||||
@ -52,7 +53,7 @@ setup(
|
|||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
package_data = {
|
package_data = {
|
||||||
# If any package contains *.txt or *.rst files, include them:
|
# If any package contains *.txt or *.rst files, include them:
|
||||||
'': ['*.gc', '*.xsd']
|
'': ['*.gc', '*.xsd', 'politicadefirmav2.pdf']
|
||||||
},
|
},
|
||||||
keywords='facho',
|
keywords='facho',
|
||||||
name='facho',
|
name='facho',
|
||||||
|
Loading…
Reference in New Issue
Block a user