Files
MBS/WEBSERVICES/test/efactura.4gl
T

307 lines
9.5 KiB
Plaintext

IMPORT util
IMPORT com
IMPORT os
IMPORT security
IMPORT XML
IMPORT FGL recepcion
IMPORT FGL aprobacion
CONSTANT dpy_verb=TRUE -- send messages to standard output
DEFINE doc xml.DomDocument
DEFINE req com.HTTPServiceRequest
DEFINE url,msg,method,headers,mensaje,filexml,tipoecf,rnc_e,rnc_c,e_ncf,fileacuse,resp,
ruta_firmados,fileafirmar_f STRING,
tout, n, x,rcode INTEGER,
start_time DATETIME YEAR TO SECOND
DEFINE d0 DATETIME YEAR TO SECOND
DEFINE a om.SaxAttributes
DEFINE out om.SaxDocumentHandler,
i INT,
fechaFirma DATETIME YEAR TO SECOND
DEFINE result INTEGER
MAIN
LET filexml = ".\\ArchRecibidos\\"
LET fileacuse = ".\\Acuses\\"
LET ruta_firmados = fgl_getenv("RUTA_XML_FIRMADOS")
CALL check_utf8() RETURNING x, msg
IF x != 0 THEN
DISPLAY "ERROR: ", msg
EXIT PROGRAM 1
END IF
CALL show_verb("Inicio Api server: ...")
CALL com.WebServiceEngine.RegisterRestService("recepcion","aprobacion")
CALL com.WebServiceEngine.Start()
WHILE TRUE
LET result = com.WebServiceEngine.ProcessServices(-1)
-- handling of result found here
-- http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_gws_restful_high_level_publish_module.html
CASE result
WHEN 0
DISPLAY "Request processed."
WHEN -1
DISPLAY "Timeout reached."
WHEN -2
DISPLAY "Disconnected from application server."
EXIT PROGRAM # The Application server has closed the connection
WHEN -3
DISPLAY "Client Connection lost."
WHEN -4
DISPLAY "Server interrupted with Ctrl-C."
WHEN -9
DISPLAY "Unsupported operation."
WHEN -10
DISPLAY "Internal server error."
WHEN -23
DISPLAY "Deserialization error."
WHEN -35
DISPLAY "No such REST operation found."
WHEN -36
DISPLAY "Missing REST parameter."
OTHERWISE
DISPLAY "Unexpected server error " || result || "."
EXIT WHILE
END CASE
IF int_flag<>0 THEN
LET int_flag=0
EXIT WHILE
END IF
END WHILE
END MAIN
FUNCTION check_utf8()
IF ORD("€") == 8364 AND LENGTH("€") == 1 THEN
RETURN 0, NULL
ELSE
RETURN -1, "Application locale must be UTF-8, with char length semantics"
END IF
END FUNCTION
FUNCTION show_verb(msg)
DEFINE msg STRING
IF dpy_verb THEN
DISPLAY msg
END IF
# IF log_verb THEN
# CALL errorlog(msg CLIPPED)
# END IF
END FUNCTION
FUNCTION read_request(req,tipooperacion)
# DEFINE doc xml.DomDocument
DEFINE req com.HttpServiceRequest
DEFINE cmd,recibido,tmpfile,pfechafirmadigital,tipooperacion STRING,
p RECORD
oper STRING,
data RECORD
usuario STRING,
clave STRING,
codigo STRING
END RECORD
END RECORD
INITIALIZE cmd TO NULL
LET cmd = req.readFileRequest()
DISPLAY "request: ",cmd
# LET cmd = "cp ",cmd CLIPPED," /home/fourjs/gas/appdata/services/mbs/bin/tmp/recibido.xml"
LET cmd = "copy ",cmd CLIPPED, " C:\\ProgramData\\FourJs\\gas\\3.20.06-201906131721\\services\\ecf\\tmp\\recibido.xml"
RUN cmd
# LET tmpfile = "/home/fourjs/gas/appdata/services/mbs/bin/tmp/recibido.xml"
LET tmpfile = ".\\tmp\\recibido.xml"
LET recibido = filexml CLIPPED,"recibido.xml"
LET filexml = recibido
# TRY
LET doc = xml.DomDocument.Create()
CALL doc.setFeature("whitespace-in-element-content",FALSE)
IF os.Path.exists(tmpfile) THEN
CALL doc.load(tmpfile)
CALL doc.save(recibido)
CALL getxmldata(filexml) RETURNING tipoecf,pfechafirmadigital,rnc_e,e_ncf,rnc_c
LET filexml = filexml CLIPPED,rnc_e CLIPPED,e_ncf CLIPPED,".xml"
CALL doc.save(filexml)
LET fileafirmar_f = filexml
IF tipooperacion = "recepcion" THEN
CALL formaracuse() RETURNING filexml
CALL firmadocumento(filexml)
END IF
CALL doc.load(fileafirmar_f)
LET cmd = doc.saveToString()
RETURN 200,cmd
ELSE
RETURN 401,"Falla en el proceso del file"
END IF
END FUNCTION
FUNCTION show_err(msg)
DEFINE msg STRING
DISPLAY "ERROR:",msg
# CALL errorlog(msg CLIPPED)
END FUNCTION
FUNCTION formaracuse()
DEFINE chFechaFirma STRING
LET fileacuse = fileacuse CLIPPED,"acuse",rnc_c CLIPPED,".xml"
LET out=om.XmlWriter.createFileWriter(fileacuse)
LET a=om.SaxAttributes.create()
CALL out.startDocument()
CALL a.addAttribute("xmlns:xs","http://www.w3.org/2001/XMLSchema")
CALL out.startElement("ARECF",a)
CALL a.clear()
CALL out.startElement("DetalleAcusedeRecibo",a)
CALL out.startElement("Version",a)
CALL out.characters("1.0")
CALL out.endElement("Version")
CALL out.startElement("RNCEmisor",a)
CALL out.characters(rnc_e)
CALL out.endElement("RNCEmisor")
CALL out.startElement("RNCComprador",a)
CALL out.characters(rnc_c)
CALL out.endElement("RNCComprador")
CALL out.startElement("eNCF",a)
CALL out.characters(e_ncf)
CALL out.endElement("eNCF")
CALL out.startElement("Estado",a)
CALL out.characters("0")
CALL out.endElement("Estado")
LET chFechaFirma = util.Datetime.format(CURRENT, "%d-%m-%Y %H:%M:%S" )
DISPLAY "FECHA ",chFechaFirma
CALL out.startElement("FechaHoraAcuseRecibo",a)
CALL out.characters(chFechaFirma)
CALL out.endElement("FechaHoraAcuseRecibo")
CALL out.endElement("DetalleAcusedeRecibo")
CALL out.endElement("ARECF")
CALL out.endDocument()
RETURN fileacuse
END FUNCTION
FUNCTION limpiatmp()
DISPLAY "BORRANDO XML FILES..."
RUN 'rm /tmp/*.xml'
END FUNCTION
FUNCTION firmadocumento(fileafirmar)
DEFINE doc xml.DomDocument
DEFINE doc2 xml.DomDocument
DEFINE root xml.DomNode
DEFINE node xml.DomNode
DEFINE signNode xml.DomNode
DEFINE sig xml.Signature
DEFINE key xml.CryptoKey
DEFINE cert xml.CryptoX509
DEFINE index INTEGER,
fileafirmar STRING,
codsecure VARCHAR(6)
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
#DISPLAY "file ",fileafirmar
LET filexml = fileafirmar
CALL doc.load(fileafirmar)
TRY
# Create rsa key
LET key = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
CALL key.loadPEM("onlyRSA.pem")
# Create an X509 certificate with the constructor of the CryptoX509 class.
LET cert = xml.CryptoX509.Create()
CALL cert.setFeature("X509Certificate",TRUE)
# Load the X509 certificate associated to the RSA or DSA private key into the CryptoKey object.
# CALL cert.loadPEM("cert509.crt")
CALL cert.loadPEM("onlyCert.pem")
# Create signature object with the key to use
LET sig = xml.Signature.Create()
# Assign the CryptoKey object to the Signature object.
CALL sig.setKey(KEY)
# Assign the CryptoX509 object to the Signature object.
CALL sig.setCertificate(cert)
# Set XML node to be signed. In our case, the entire document
# LET index = sig.createReference("",
# "http://www.w3.org/2001/04/xmlenc#sha256")
LET index = sig.createReference('""',
"http://www.w3.org/2001/04/xmlenc#sha256")
# Add enveloped method to not take the XML signature node into account
# when computing the entire document.
CALL sig.appendReferenceTransformation(index,
"http://www.w3.org/2000/09/xmldsig#enveloped-signature",doc.getDocumentElement())
# Set canonicalization method on the XML fragment to be signed.
# Compute enveloped signature
CALL sig.compute(doc)
# Retrieve signature document
LET doc2=sig.getDocument()
# Append the signature node to the original document to get
# a valid enveloped signature
# Notice that the enveloped signature can be added anywhere in the
# original document
LET signNode = doc2.getDocumentElement() # Get Signature node
# Import it into the original document
LET node = doc.importNode(signNode,true)
# Retrieve the original document root node
LET root = doc.getDocumentElement()
# Append the signature node as last child of the original document
CALL root.appendChild(node)
# Save document with enveloped signature back to disk
CALL doc.setFeature("format-pretty-print",TRUE)
LET fileafirmar = ruta_firmados CLIPPED,"\\",os.Path.baseName(fileafirmar)
CALL doc.save(fileafirmar)
LET fileafirmar_f = fileafirmar
CATCH
DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm
END TRY
END FUNCTION