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 solicitar_autenticacion(self, identificacion, id_funcionalidad=-1): """Solicita al BCCR la autenticación de la identificacion, recuerde, la política del BCCR es: *no nos llame, nosotros lo llamamos*, por lo que los valores devueltos corresponden al estado de la petición y no al resultado de la firma :param identificacion: número de identificación de la persona ver `Formato identificacion <formatos.html#formato-de-identificacion>`_. :param id_funcionalidad: Identificación de la funcionalidad del programa externo, se usa para dar seguimiento a la operación, * No obligatorio 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, 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': "Autenticador: Solicitar_autenticacion", 'data': identificacion, 'location': __file__ }) request = SolicitudDeAutenticacion.create(self.negocio, self.get_now(), id_funcionalidad, self.entidad, identificacion) logger.debug({ 'message': "Autenticador: Solicitar_autenticacion Fin", 'data': { 'negocio': self.negocio, 'hora': self.get_now().isoformat(), 'entidad': self.entidad, 'identificacion': identificacion }, 'location': __file__ }) try: dev = self._solicitar_autenticacion(request) except: dev = self.DEFAULT_ERROR logger.debug({ "message": "Autenticador: Solicitar_autenticacion", 'data': dev, 'location': __file__ }) 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_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 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 validar_servicio(self, servicio): """Valida si el servicio está disponible. :param servicio: tipo de servicio a validar, puede ser 'certificado' o 'documento' :returns: True si lo está o False si ocurrió algún error contactando al BCCR o el servicio no está disponible """ dev = False if servicio.lower() == 'certificado': dev = self._validar_servicio_certificado() elif servicio.lower() == 'documento': dev = self._validar_servicio_documento() logger.info({ 'message': "Validador: Validar servicio", 'data': { 'servicio': servicio, '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