def extrae_resultado(self, solicitud, resultado): """Convierte la infromación obtenida del servicio SOAP a python :param solicitud: Objeto de solicitud del tipo *pyfva.soap.firmador.SolicitudDeFirma* :param resultado: Objeto de respuesta del tipo *pyfva.soap.firmador.RecibaLaSolicitudDeSelladoElectronicoXmlEnvelopedCoFirmaResult* Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_ERROR**. :returns: **codigo_error:** Número con el código de error 1 es éxito **texto_codigo_error:** Descripción del error **fue_exitosa:** Verdadero si se pudo sellar, falso si hay un error **documento:** Documento en base64 si fue_exitosa True **hash_documento:** hash del documento en base64 si fue_exitosa True **id_algoritmo_hash:** algoritmo con el que se calculó la suma hash opciones: sha256, sha384, sha512 """ try: data = self._extrae_resultado(solicitud, resultado) except Exception as e: logger.error({'message': "Sellador: extrayendo resultados %r", 'data': e, 'location': __file__}) data = self.DEFAULT_ERROR return data
def extrae_resultado(self, solicitud, resultado): """Convierte la infromación obtenida del servicio SOAP a python :param solicitud: Objeto de solicitud del tipo *pyfva.soap.firmador.SolicitudDeFirma* :param resultado: Objeto de respuesta del tipo *pyfva.soap.firmador.RecibaLaSolicitudDeFirmaXmlEnvelopedCoFirmaResult* Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_ERROR**. :returns: **codigo_error:** Número con el código de error 0 es éxito **texto_codigo_error:** Descripción del error **codigo_verificacion:** str con el código de verificación de la trasacción **tiempo_maximo:** Tiempo máximo de duración de la solicitud en segundos **id_solicitud:** Número de identificación de la solicitud """ try: data = self._extrae_resultado(solicitud, resultado) except Exception as e: logger.error({ 'message': "Firmador: extrayendo resultados %r", 'data': e, 'location': __file__ }) data = self.DEFAULT_ERROR return data
def firme_xml(self, identidad, documento, algoritmo_hash='Sha512', hash_doc=None, resumen='', id_funcionalidad=-1, _type='cofirma'): """ Firma un documento XML, .. note:: Los parámetros exceptuando formato (no existe en este método) son idénticos que los de firme, además los resultados retornados son también idénticos. """ logger.info({ 'message': "Firmador: firme_xml", 'data': { 'type': _type, 'identity': identidad, 'hash_doc': hash_doc }, 'location': __file__ }) logger.debug({ 'message': "Firmador: firme_xml", 'data': repr(locals()), 'location': __file__ }) request = self._construya_solicitud(identidad, documento, algoritmo_hash, hash_doc, resumen, id_funcionalidad) try: dev = self._firme_xml(request, _type) except Exception as e: logger.error({ 'message': "Firmador: firmando en xml", 'data': { 'type': _type, 'data': e }, 'location': __file__ }) dev = self.DEFAULT_ERROR logger.debug({ 'message': "Firmador: firme_xml result", 'data': { 'type': _type, 'data': dev }, 'location': __file__ }) return dev
def _validar_servicio(self): stub = SelladorElectronicoConControlDeLlaveSoapServiceStub() option = ElServicioEstaDisponible() try: status = stub.ElServicioEstaDisponible(option) dev = status.soap_body.ElServicioEstaDisponibleResult except Exception as e: logger.error({'message': "Sellador: Servicio de firmado fallando", 'data': e, 'location': __file__}) dev = False return dev
def firme_pdf(self, identidad, documento, algoritmo_hash='Sha512', hash_doc=None, resumen='', id_funcionalidad=-1, lugar=None, razon=None): """ Firma un documento del tipo PDF. .. note:: Los parámetros exceptuando formato (no existe en este método) son idénticos que los de firme, además los resultados retornados son también idénticos. """ logger.info({ 'message': "Firmador: firme_pdf", 'data': { 'identity': identidad, 'hash_doc': hash_doc }, 'location': __file__ }) logger.debug({ 'message': "Firmador: firme_pdf", 'data': repr(locals()), 'location': __file__ }) request = self._construya_solicitud_pdf(identidad, documento, algoritmo_hash, hash_doc, resumen, id_funcionalidad, lugar, razon) try: dev = self._firme_pdf(request) except Exception as e: logger.error({ 'message': "Firmador: firmando en pdf", 'data': e, 'location': __file__ }) dev = self.DEFAULT_ERROR logger.debug({ 'message': "Firmador: firme_pdf result", 'data': dev, 'location': __file__ }) return dev
def firme(self, documento, formato, algoritmo_hash='Sha512', hash_doc=None, id_funcionalidad=-1, lugar=None, razon=None): """ Firma con sello electrónico cualquier documento enviado distinguiendo por el parámtetro formato cual método de firma llamar :param documento: Documento a firmar en base64 :param formato: Formato del documento, puede ser *xml_cofirma*, *xml_contrafirma*, *odf*, *msoffice*, *pdf* :param algoritmo_hash: Algoritmo utilizado para calcular el hash_doc, puede ser *sha256*, *sha384*, *sha512* :param hash_doc: hash del documento aplicando el algoritmo hash :param id_funcionalidad: Identificación de la funcionalidad del programa externo, se usa para dar seguimiento a la operación, * No obligatorio :param lugar: Lugar donde se realizó la firma (solo PDF) :param razon: Razon de firma para PDF (solo PDF) Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_ERROR**. :returns: **codigo_error:** Número con el código de error 1 es éxito **texto_codigo_error:** Descripción del error **fue_exitosa:** Verdadero si se pudo sellar, falso si hay un error **documento:** Documento en base64 si fue_exitosa True **hash_documento:** hash del documento en base64 si fue_exitosa True **id_algoritmo_hash:** algoritmo con el que se calculó la suma hash opciones: sha256, sha384, sha512 """ logger.info({'message': "Sellador: firme ", 'data': {'format': formato, 'hash_doc': hash_doc}, 'location': __file__}) logger.debug({'message': "Sellador: firme", 'data': repr(locals()), 'location': __file__}) algoritmo_hash = algoritmo_hash.title() if formato in ['xml_cofirma', 'xml_contrafirma']: _type = formato.replace('xml_', '') dev = self.firme_xml(documento, algoritmo_hash, hash_doc, id_funcionalidad, _type) elif formato == 'odf': dev = self.firme_odf(documento, algoritmo_hash, hash_doc, id_funcionalidad) elif formato == 'msoffice': dev = self.firme_msoffice(documento, algoritmo_hash, hash_doc, id_funcionalidad) elif formato == 'pdf': dev = self.firme_pdf(documento, algoritmo_hash=algoritmo_hash, hash_doc=hash_doc, id_funcionalidad=id_funcionalidad, lugar=lugar, razon=razon) else: logger.error({'message': "Formato de documento inválido", 'data': formato, 'location': __file__}) dev = self.DEFAULT_ERROR logger.debug({'message': "Sellador: firme result", 'data': dev, 'location': __file__}) return dev
def _validar_servicio(self): stub = FirmadorSoapServiceStub() option = ValideElServicio() try: status = stub.ValideElServicio(option) dev = status.soap_body.ValideElServicioResult except Exception as e: logger.error({ 'message': "Firmador: Servicio de firmado fallando", 'data': e, 'location': __file__ }) dev = False return dev
def _suscriptor_conectado(self, identificacion): stub = FirmadorSoapServiceStub() options = ElSuscriptorEstaConectado() options.laIdentificacion = identificacion try: status = stub.ElSuscriptorEstaConectado(options) dev = status.soap_body.ElSuscriptorEstaConectadoResult except Exception as e: logger.error({ 'message': "Firmador: Servicio de firmado fallando en usuario conectado", 'data': e, 'location': __file__ }) dev = False return dev
def validar_certificado_autenticacion(self, certificado): """Valida si el certificado de autenticación es válido y no está revocado. :param certificado: Certificado en base64 Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_CERTIFICATE_ERROR**. :returns: **codigo_error:** Número con el código de error 0 es éxito **texto_codigo_error:** Descripción del error **exitosa:** True si fue exitosa, False si no lo fue **certificado:** Si la operación no fue exitosa retorna None, si lo fue retorna un diccionario con: **identificacion:** Número de identificación del suscriptor dueño del certificado **nombre:** Nombre completo del suscriptor dueño del certificado **inicio_vigencia:** Fecha de inicio del vigencia del certificado **fin_vigencia:** Fecha de finalización de la vigencia del certificado """ logger.debug({ 'message': "Validador: validar_certificado_autenticacion", 'data': repr(locals()), 'location': __file__ }) try: dev = self._validar_certificado_autenticacion(certificado) except Exception as e: logger.error({ 'message': "Validador: validando certificado", 'data': e, 'location': __file__ }) dev = self.DEFAULT_CERTIFICATE_ERROR logger.info({ 'message': "Validador: validar_certificado_autenticacion result ", 'data': dev, 'location': __file__ }) return dev
def _validar_documento_pdf(self, documento): stub = ValidadorDeDocumentoSoapServiceStub() options = ValideElDocumentoPdf() options.elDocumentoPdf = documento try: status = stub.ValideElDocumentoPdf(options) dev = self._extract_documento_xml( status.soap_body.ValideElDocumentoPdfResult, ERRORES_VALIDAR_PDF) except Exception as e: logger.error({ 'message': "Validador: validando PDF", 'data': e, 'location': __file__ }) dev = self.DEFAULT_DOCUMENT_ERROR(ERRORES_VALIDAR_PDF) return dev
def _validar_documento_cofirma(self, documento): stub = ValidadorDeDocumentoSoapServiceStub() options = ValideElDocumentoXmlEnvelopedCoFirma() options.elDocumentoXml = documento try: status = stub.ValideElDocumentoXmlEnvelopedCoFirma(options) dev = self._extract_documento_xml( status.soap_body.ValideElDocumentoXmlEnvelopedCoFirmaResult, ERRORES_VALIDAR_XMLCOFIRMA) except Exception as e: logger.error({ 'message': "Validador: validando cofirma", 'data': e, 'location': __file__ }) dev = self.DEFAULT_DOCUMENT_ERROR(ERRORES_VALIDAR_XMLCOFIRMA) return dev
def existe_solicitud_de_firma_completa(self, identificacion): """Verifica si una solicitud de firma ha sida completada por el usuario en el sistema del BCCR :param identificacion: número de identificación de la persona Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_ERROR**. :returns: **codigo_error:** Número con el código de error 0 es éxito **texto_codigo_error:** Descripción del error **exitosa:** True si fue exitosa, False si no lo fue **existe_firma:** Retorna True si hay un proceso de firma activo o False si no. """ logger.info({ 'message': "Verificador: existe solicitud de firma completa", 'data': identificacion, 'location': __file__ }) try: dev = self._existe_solicitud_de_firma_completa(identificacion) except Exception as e: logger.error({ 'message': "Verificador: existe_solicitud_de_firma_completa", 'data': e, 'location': __file__ }) dev = self.DEFAULT_ERROR logger.debug({ 'message': "Verificador: existe solicitud de firma completa", 'data': { 'identification': identificacion, 'result': dev }, 'location': __file__ }) return dev
def firme_msoffice(self, documento, algoritmo_hash='Sha512', hash_doc=None, id_funcionalidad=-1): """ Firma un documento del tipo Microsoft office. .. note:: Los parámetros exceptuando formato (no existe en este método) son idénticos que los de firme, además los resultados retornados son también idénticos. """ logger.info({'message': "Sellador: firme_msoffice", 'data': {'hash_doc': hash_doc}, 'location': __file__}) logger.debug({'message': "Sellador: firme_msoffice", 'data': repr(locals()), 'location': __file__}) request = self._construya_solicitud(documento, algoritmo_hash, hash_doc, id_funcionalidad) try: dev = self._firme_msoffice(request) except Exception as e: logger.error({'message': "Sellador: firmando en msoffice", 'data': e, 'location': __file__}) dev = self.DEFAULT_ERROR logger.debug({'message': "Sellador: firme_msoffice result", 'data': dev, 'location': __file__}) return dev
def firme(self, identidad, documento, formato, algoritmo_hash='Sha512', hash_doc=None, resumen='', id_funcionalidad=-1, lugar=None, razon=None): """ Firma cualquier documento enviado distinguiendo por el parámtetro formato cual método de firma llamar :param identidad: Identidad del suscriptor a firmar :param documento: Documento a firmar en base64 :param formato: Formato del documento, puede ser *xml_cofirma*, *xml_contrafirma*, *odf*, *msoffice*, *pdf* :param algoritmo_hash: Algoritmo utilizado para calcular el hash_doc, puede ser *sha256*, *sha384*, *sha512* :param hash_doc: hash del documento aplicando el algoritmo hash :param resumen: Información resumida para mostar al suscriptor que describe el documento :param id_funcionalidad: Identificación de la funcionalidad del programa externo, se usa para dar seguimiento a la operación, * No obligatorio :param lugar: Lugar donde se realizó la firma (solo PDF) :param razon: Razon de firma para PDF (solo PDF) Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_ERROR**. :returns: **codigo_error:** Número con el código de error 1 es éxito **texto_codigo_error:** Descripción del error **codigo_verificacion:** str con el código de verificación de la trasacción, se muestra al usuario **tiempo_maximo:** Tiempo máximo de duración de la solicitud en segundos **id_solicitud:** Número de identificación de la solicitud """ logger.info({ 'message': "Firmador: firme ", 'data': { 'identity': identidad, 'format': formato, 'hash_doc': hash_doc }, 'location': __file__ }) logger.debug({ 'message': "Firmador: firme", 'data': repr(locals()), 'location': __file__ }) algoritmo_hash = algoritmo_hash.title() if formato in ['xml_cofirma', 'xml_contrafirma']: _type = formato.replace('xml_', '') dev = self.firme_xml(identidad, documento, algoritmo_hash, hash_doc, resumen, id_funcionalidad, _type) elif formato == 'odf': dev = self.firme_odf(identidad, documento, algoritmo_hash, hash_doc, resumen, id_funcionalidad) elif formato == 'msoffice': dev = self.firme_msoffice(identidad, documento, algoritmo_hash, hash_doc, resumen, id_funcionalidad) elif formato == 'pdf': dev = self.firme_pdf(identidad, documento, algoritmo_hash=algoritmo_hash, hash_doc=hash_doc, resumen=resumen, id_funcionalidad=id_funcionalidad, lugar=lugar, razon=razon) else: logger.error({ 'message': "Formato de documento inválido", 'data': formato, 'location': __file__ }) dev = self.DEFAULT_ERROR logger.debug({ 'message': "Firmador: firme result", 'data': dev, 'location': __file__ }) return dev
def validar_documento(self, documento, formato): """Valida si el documento está firmado correctamente. :param documento: documento xml en base64 :param formato: tipo de documento a validar (cofirma, contrafirma, msoffice, odf). Retorna una diccionario con los siguientes elementos, en caso de error retorna **DEFAULT_DOCUMENT_ERROR**. .. note:: Observe que en caso de no ser exitosa la operación los atributos 'advertencias', 'errores_encontrados' y 'firmantes' retornarán None :returns: **codigo_error:** Número con el código de error 0 es éxito **texto_codigo_error:** Descripción del error **exitosa:** True si fue exitoso el verificado del documento, False si no lo fue **advertencias:** Lista de advertencias encontradas durante el proceso de validadación, algo como: ["adv1", "adv2"] **errores_encontrados:** Lista de errores encontrados y su respectivo detalle, ej [("código de error", "Detalle del error"), ...] **firmantes:** Lista de información del los firmantes, ej [ {'identificacion': "8-0888-0888", 'fecha_firma': datetime.now(), 'nombre': "Juanito Mora Porras"}, ... ] """ logger.debug({ 'message': "Validador: validar_documento", 'data': { 'format': formato, 'data': repr(locals()) }, 'location': __file__ }) try: if formato == 'cofirma': dev = self._validar_documento_cofirma(documento) elif formato == 'contrafirma': dev = self._validar_documento_contrafirma(documento) elif formato == 'msoffice': dev = self._validar_documento_msoffice(documento) elif formato == 'odf': dev = self._validar_documento_odf(documento) elif formato == 'pdf': dev = self._validar_documento_pdf(documento) else: logger.error({ 'message': "Validador: validando documento", 'data': { 'format': formato, 'message': "No existe formato especificado" }, 'location': __file__ }) dev = self.DEFAULT_DOCUMENT_ERROR(ERRORES_VALIDAR_XMLCOFIRMA) except Exception as e: logger.error({ 'message': "Validador: validando documento", 'data': { 'format': formato, 'message': e }, 'location': __file__ }) dev = self.DEFAULT_DOCUMENT_ERROR(ERRORES_VALIDAR_XMLCOFIRMA) logger.info({ 'message': "Validador: validar_documento", 'data': { 'format': formato, 'result': dev }, 'location': __file__ }) return dev