Solicitud de descarga correcta
This commit is contained in:
parent
48155488c3
commit
82033da207
|
@ -37,6 +37,10 @@ def _process_command_line_arguments():
|
||||||
help = "Día de la descarga, de forma predeterminada no se usa"
|
help = "Día de la descarga, de forma predeterminada no se usa"
|
||||||
parser.add_argument('-d', '--dia', help=help, dest='day', default=0, type=int, choices=range(32))
|
parser.add_argument('-d', '--dia', help=help, dest='day', default=0, type=int, choices=range(32))
|
||||||
|
|
||||||
|
help = 'Verificar estatus de descarga'
|
||||||
|
parser.add_argument('-ve', '--fiel-validar', help=help,
|
||||||
|
action='store_true', default=False, required=False)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@ -44,3 +48,10 @@ def _process_command_line_arguments():
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = _process_command_line_arguments()
|
args = _process_command_line_arguments()
|
||||||
main(args)
|
main(args)
|
||||||
|
|
||||||
|
|
||||||
|
# ~ {
|
||||||
|
# ~ 'IdSolicitud': '307a22f0-1259-479c-96b1-2852f9072c58',
|
||||||
|
# ~ 'CodEstatus': '5000',
|
||||||
|
# ~ 'Mensaje': 'Solicitud Aceptada'
|
||||||
|
# ~ }
|
||||||
|
|
|
@ -28,6 +28,7 @@ class SATCertificate(object):
|
||||||
def _init_values(self):
|
def _init_values(self):
|
||||||
self._rfc = ''
|
self._rfc = ''
|
||||||
self._serial_number = ''
|
self._serial_number = ''
|
||||||
|
self._serial_number2 = ''
|
||||||
self._not_before = None
|
self._not_before = None
|
||||||
self._not_after = None
|
self._not_after = None
|
||||||
self._is_fiel = False
|
self._is_fiel = False
|
||||||
|
@ -66,6 +67,7 @@ class SATCertificate(object):
|
||||||
obj = x509.load_der_x509_certificate(cer, default_backend())
|
obj = x509.load_der_x509_certificate(cer, default_backend())
|
||||||
self._rfc = obj.subject.get_attributes_for_oid(
|
self._rfc = obj.subject.get_attributes_for_oid(
|
||||||
NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0]
|
NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0]
|
||||||
|
self._serial_number2 = obj.serial_number
|
||||||
self._serial_number = '{0:x}'.format(obj.serial_number)[1::2]
|
self._serial_number = '{0:x}'.format(obj.serial_number)[1::2]
|
||||||
self._not_before = obj.not_valid_before
|
self._not_before = obj.not_valid_before
|
||||||
self._not_after = obj.not_valid_after
|
self._not_after = obj.not_valid_after
|
||||||
|
@ -167,6 +169,10 @@ class SATCertificate(object):
|
||||||
def serial_number(self):
|
def serial_number(self):
|
||||||
return self._serial_number
|
return self._serial_number
|
||||||
|
|
||||||
|
@property
|
||||||
|
def serial_number2(self):
|
||||||
|
return self._serial_number2
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def not_before(self):
|
def not_before(self):
|
||||||
return self._not_before
|
return self._not_before
|
||||||
|
|
|
@ -16,9 +16,10 @@ class SATWebService():
|
||||||
'REQ': f'{BASE}/SolicitaDescargaService.svc',
|
'REQ': f'{BASE}/SolicitaDescargaService.svc',
|
||||||
}
|
}
|
||||||
XMLNS = 'http://DescargaMasivaTerceros.gob.mx'
|
XMLNS = 'http://DescargaMasivaTerceros.gob.mx'
|
||||||
|
XMLNS2 = 'http://DescargaMasivaTerceros.sat.gob.mx'
|
||||||
ACTIONS = {
|
ACTIONS = {
|
||||||
'AUTH': f'{XMLNS}/IAutenticacion/Autentica',
|
'AUTH': f'{XMLNS}/IAutenticacion/Autentica',
|
||||||
'REQ': f'{XMLNS}/ISolicitaDescargaService/SolicitaDescarga',
|
'REQ': f'{XMLNS2}/ISolicitaDescargaService/SolicitaDescarga',
|
||||||
}
|
}
|
||||||
HEADERS = {
|
HEADERS = {
|
||||||
'Content-type': 'text/xml;charset="utf-8"',
|
'Content-type': 'text/xml;charset="utf-8"',
|
||||||
|
@ -33,6 +34,7 @@ class SATWebService():
|
||||||
'xd': 'http://www.w3.org/2000/09/xmldsig#',
|
'xd': 'http://www.w3.org/2000/09/xmldsig#',
|
||||||
}
|
}
|
||||||
NS_RESULT = {'s': NS['s'], None: XMLNS}
|
NS_RESULT = {'s': NS['s'], None: XMLNS}
|
||||||
|
NS_RESULT2 = {'s': NS['s'], None: XMLNS2}
|
||||||
|
|
||||||
def __init__(self, cert):
|
def __init__(self, cert):
|
||||||
self._cert = cert
|
self._cert = cert
|
||||||
|
@ -169,7 +171,8 @@ class SATWebService():
|
||||||
'RfcSolicitante': self._cert.rfc,
|
'RfcSolicitante': self._cert.rfc,
|
||||||
'FechaFinal': date_end.strftime(FORMAT),
|
'FechaFinal': date_end.strftime(FORMAT),
|
||||||
'FechaInicial': date_start.strftime(FORMAT),
|
'FechaInicial': date_start.strftime(FORMAT),
|
||||||
'TipoSolicitud': 'cfdi',
|
'TipoSolicitud': 'CFDI',
|
||||||
|
'RfcEmisor': self._cert.rfc,
|
||||||
}
|
}
|
||||||
request = ET.SubElement(request_down, node_name, attr)
|
request = ET.SubElement(request_down, node_name, attr)
|
||||||
# ~ if rfc_emisor is not None:
|
# ~ if rfc_emisor is not None:
|
||||||
|
@ -183,7 +186,7 @@ class SATWebService():
|
||||||
|
|
||||||
node_name = 'CanonicalizationMethod'
|
node_name = 'CanonicalizationMethod'
|
||||||
attr1 = {'Algorithm': 'http://www.w3.org/2001/10/xml-exc-c14n#'}
|
attr1 = {'Algorithm': 'http://www.w3.org/2001/10/xml-exc-c14n#'}
|
||||||
canonicalization = ET.SubElement(signed_info, node_name, attr)
|
canonicalization = ET.SubElement(signed_info, node_name, attr1)
|
||||||
|
|
||||||
node_name = 'SignatureMethod'
|
node_name = 'SignatureMethod'
|
||||||
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'}
|
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'}
|
||||||
|
@ -192,24 +195,30 @@ class SATWebService():
|
||||||
attr = {'URI': '#_0'}
|
attr = {'URI': '#_0'}
|
||||||
reference = ET.SubElement(signed_info, 'Reference', attr)
|
reference = ET.SubElement(signed_info, 'Reference', attr)
|
||||||
transforms = ET.SubElement(reference, 'Transforms')
|
transforms = ET.SubElement(reference, 'Transforms')
|
||||||
ET.SubElement(transforms, 'Transform')
|
ET.SubElement(transforms, 'Transform', attr1)
|
||||||
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#sha1'}
|
attr = {'Algorithm': 'http://www.w3.org/2000/09/xmldsig#sha1'}
|
||||||
ET.SubElement(reference, 'DigestMethod', attr)
|
ET.SubElement(reference, 'DigestMethod', attr)
|
||||||
|
digest_value = ET.SubElement(reference, 'DigestValue')
|
||||||
dvalue = ET.tostring(request_down, method='c14n', exclusive=1)
|
signature_value = ET.SubElement(signature, 'SignatureValue')
|
||||||
dvalue = base64.b64encode(hashlib.new('sha1', dvalue).digest())
|
|
||||||
ET.SubElement(reference, 'DigestValue').text = dvalue
|
|
||||||
|
|
||||||
signature_value = ET.tostring(signed_info, method='c14n', exclusive=1)
|
|
||||||
signature_value = self._cert.sign_sha1(signature_value)
|
|
||||||
ET.SubElement(signature, 'SignatureValue').text = signature_value
|
|
||||||
|
|
||||||
key_info = ET.SubElement(signature, 'KeyInfo')
|
key_info = ET.SubElement(signature, 'KeyInfo')
|
||||||
x_data = ET.SubElement(key_info, 'X509Data')
|
x_data = ET.SubElement(key_info, 'X509Data')
|
||||||
x_issuer_serial = ET.SubElement(x_data, 'X509IssuerSerial')
|
x_issuer_serial = ET.SubElement(x_data, 'X509IssuerSerial')
|
||||||
ET.SubElement(x_issuer_serial, 'X509IssuerName').text = self._cert.issuer
|
x_issuer = ET.SubElement(x_issuer_serial, 'X509IssuerName')
|
||||||
ET.SubElement(x_issuer_serial, 'X509SerialNumber').text = self._cert.serial_number
|
x_serial_number = ET.SubElement(x_issuer_serial, 'X509SerialNumber')
|
||||||
ET.SubElement(x_data, 'X509Certificate').text = self._cert.cer_txt
|
x_cert = ET.SubElement(x_data, 'X509Certificate')
|
||||||
|
|
||||||
|
dvalue = ET.tostring(request_down, method='c14n', exclusive=1)
|
||||||
|
dvalue = base64.b64encode(hashlib.new('sha1', dvalue).digest())
|
||||||
|
digest_value.text = dvalue
|
||||||
|
|
||||||
|
sign = ET.tostring(signed_info, method='c14n', exclusive=1)
|
||||||
|
sign = self._cert.sign_sha1(sign)
|
||||||
|
signature_value.text = sign
|
||||||
|
|
||||||
|
x_issuer.text = self._cert.issuer
|
||||||
|
x_serial_number.text = str(self._cert.serial_number2)
|
||||||
|
x_cert.text = self._cert.cer_txt
|
||||||
|
|
||||||
# ~ soap = ET.tostring(root, pretty_print=True, encoding='utf-8')
|
# ~ soap = ET.tostring(root, pretty_print=True, encoding='utf-8')
|
||||||
soap = ET.tostring(root)
|
soap = ET.tostring(root)
|
||||||
|
@ -229,7 +238,7 @@ class SATWebService():
|
||||||
|
|
||||||
result = ET.fromstring(response.text)
|
result = ET.fromstring(response.text)
|
||||||
node_name = 's:Body/SolicitaDescargaResponse/SolicitaDescargaResult'
|
node_name = 's:Body/SolicitaDescargaResponse/SolicitaDescargaResult'
|
||||||
node = result.find(node_name, namespaces=self.NS_RESULT)
|
node = result.find(node_name, namespaces=self.NS_RESULT2)
|
||||||
data = dict(node.attrib)
|
data = dict(node.attrib)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
|
@ -100,6 +100,7 @@ def fiel_validar(args):
|
||||||
log.info(f'\n{cert}')
|
log.info(f'\n{cert}')
|
||||||
msg = 'Ya puedes descargar del SAT'
|
msg = 'Ya puedes descargar del SAT'
|
||||||
log.info(msg)
|
log.info(msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue