예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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
예제 #10
0
    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