Commit inicial: fuentes MBS ERP (Genero 6) + .gitignore + docs/SETUP_PC_MBS.md
This commit is contained in:
@@ -0,0 +1,501 @@
|
||||
IMPORT util
|
||||
IMPORT com
|
||||
IMPORT os
|
||||
IMPORT security
|
||||
IMPORT XML
|
||||
|
||||
|
||||
CONSTANT dpy_verb=TRUE -- send messages to standard output
|
||||
TYPE reqInfoTyp RECORD
|
||||
method STRING,
|
||||
ctype STRING, # check the Content-Type
|
||||
informat STRING, # short word for Content Type
|
||||
caccept STRING, # check which format the client accepts
|
||||
outformat STRING, # short word for Accept
|
||||
path STRING,
|
||||
query STRING, # the query string
|
||||
items DYNAMIC ARRAY OF RECORD
|
||||
name STRING,
|
||||
value STRING
|
||||
END RECORD
|
||||
END RECORD
|
||||
DEFINE m_reqInfo reqInfoTyp
|
||||
DEFINE doc xml.DomDocument
|
||||
|
||||
|
||||
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
|
||||
|
||||
MAIN
|
||||
DEFINE ret INTEGER,
|
||||
mensaje STRING
|
||||
|
||||
DEFINE req com.HTTPServiceRequest,
|
||||
err RECORD
|
||||
code INT,
|
||||
DESC STRING
|
||||
END RECORD
|
||||
|
||||
DEFER INTERRUPT
|
||||
LET filexml = ".\\ArchRecibidos\\"
|
||||
LET fileacuse = ".\\Acuses\\"
|
||||
LET ruta_firmados = fgl_getenv("RUTA_XML_FIRMADOS")
|
||||
|
||||
# iNICIO SERVICIO SERVER
|
||||
DISPLAY "Iniciando server..."
|
||||
|
||||
CALL com.WebServiceEngine.Start()
|
||||
DISPLAY "The server is listening."
|
||||
|
||||
# Creacion del servidor
|
||||
WHILE TRUE
|
||||
TRY
|
||||
LET req = com.WebServiceEngine.getHTTPServiceRequest(30)
|
||||
# ... parse and process the request ...
|
||||
|
||||
CALL getReqInfo(req) RETURNING method,url
|
||||
|
||||
DISPLAY "metodo2 ",method," url ",url
|
||||
CASE method
|
||||
WHEN "GET"
|
||||
CALL req.sendTextResponse(200,"","API SERVER para los e-NCF")
|
||||
EXIT WHILE
|
||||
WHEN "POST"
|
||||
IF url = "http://ecf.fulldetord.com/gas/ws/r/fe/aprobacioncomercial/api/ecf" OR
|
||||
url = "https://ecf.fulldetord.com/gas/ws/r/fe/aprobacioncomercial/api/ecf" THEN
|
||||
LET ret = NULL
|
||||
DISPLAY "metodo2 ",method," ",url
|
||||
|
||||
CALL aprobacion(req) RETURNING ret,mensaje
|
||||
|
||||
|
||||
IF ret <> 200 THEN
|
||||
LET ret = 400
|
||||
# LET mensaje = "Invalido"
|
||||
CALL req.sendTextResponse(ret,"",mensaje)
|
||||
DISPLAY "enviar respuesta ",ret," ",url
|
||||
ELSE
|
||||
LET ret = 200
|
||||
# LET mensaje="Valido"
|
||||
CALL req.sendTextResponse(ret,"",mensaje)
|
||||
END IF
|
||||
END IF
|
||||
EXIT CASE
|
||||
OTHERWISE
|
||||
|
||||
LET err.code = -3
|
||||
LET err.desc = mensaje
|
||||
CALL req.sendTextResponse(400,"OK","Unknown request:\n" || url || "\n" || method)
|
||||
END CASE
|
||||
{ CATCH
|
||||
LET ret = status
|
||||
CASE ret
|
||||
WHEN -15565
|
||||
DISPLAY "Server process has been stopped by Ctrl-C"
|
||||
WHEN -15575
|
||||
DISPLAY "Server process has been disconnected by the GAS"
|
||||
OTHERWISE
|
||||
DISPLAY "[ERROR] " || ret
|
||||
EXIT WHILE
|
||||
END CASE
|
||||
IF int_flag<>0 THEN
|
||||
LET int_flag = 0
|
||||
EXIT WHILE
|
||||
END IF
|
||||
}
|
||||
END TRY
|
||||
|
||||
END WHILE
|
||||
|
||||
END MAIN
|
||||
FUNCTION getReqInfo(req)
|
||||
DEFINE req com.HTTPServiceRequest
|
||||
DEFINE str, val base.StringTokenizer
|
||||
DEFINE token,mensaje STRING
|
||||
DEFINE i,rcode INT
|
||||
|
||||
INITIALIZE m_reqInfo TO NULL
|
||||
|
||||
LET m_reqInfo.ctype = getHeaderByName(req,"Content-Type")
|
||||
IF m_reqInfo.ctype.getIndexOf("/xml",1) THEN
|
||||
LET m_reqInfo.informat = "XML"
|
||||
ELSE
|
||||
LET m_reqInfo.informat = "JSON"
|
||||
END IF
|
||||
LET m_reqInfo.caccept = getHeaderByName(req,"accept")
|
||||
IF m_reqInfo.caccept.getIndexOf("/xml",1) THEN
|
||||
LET m_reqInfo.outformat = "XML"
|
||||
ELSE
|
||||
LET m_reqInfo.outformat = "JSON"
|
||||
END IF
|
||||
LET m_reqInfo.method = req.getMethod()
|
||||
|
||||
CALL parseUrl(req.getUrl()) RETURNING m_reqInfo.path, m_reqInfo.query
|
||||
LET str = base.StringTokenizer.create(m_reqInfo.query,"&")
|
||||
|
||||
LET i=1
|
||||
CALL m_reqInfo.items.clear()
|
||||
WHILE str.hasMoreTokens()
|
||||
LET token = str.nextToken()
|
||||
LET val = base.StringTokenizer.create(token,"=")
|
||||
IF val.hasMoreTokens() THEN LET m_reqInfo.items[i].name = val.nextToken() END IF
|
||||
IF val.hasMoreTokens() THEN LET m_reqInfo.items[i].value = val.nextToken() END IF
|
||||
LET i=i+1
|
||||
END WHILE
|
||||
RETURN m_reqInfo.method,m_reqInfo.path
|
||||
END FUNCTION
|
||||
FUNCTION parseUrl(url)
|
||||
DEFINE url STRING
|
||||
DEFINE i INT
|
||||
|
||||
LET i = url.getIndexOf("?",1)
|
||||
IF i = 0 THEN
|
||||
RETURN url, NULL
|
||||
ELSE
|
||||
RETURN url.subString(1,i), url.subString(i+1,url.getLength())
|
||||
END IF
|
||||
END FUNCTION
|
||||
FUNCTION getHeaderByName(areq,hname)
|
||||
DEFINE areq com.HTTPServiceRequest
|
||||
DEFINE hname STRING
|
||||
|
||||
DEFINE aname STRING
|
||||
DEFINE iname STRING
|
||||
DEFINE i INT
|
||||
DEFINE n INT
|
||||
|
||||
LET aname = hname.toLowerCase()
|
||||
LET n = areq.getRequestHeaderCount()
|
||||
FOR i=1 TO n
|
||||
LET iname = areq.getRequestHeaderName(i)
|
||||
|
||||
IF aname.equals(iname.toLowerCase()) THEN
|
||||
|
||||
RETURN areq.getRequestHeaderValue(i)
|
||||
END IF
|
||||
END FOR
|
||||
|
||||
RETURN NULL
|
||||
END FUNCTION
|
||||
|
||||
PUBLIC FUNCTION recepcion()
|
||||
|
||||
DEFINE req com.HttpServiceRequest
|
||||
|
||||
CALL read_request(req) RETURNING rcode,resp
|
||||
|
||||
IF rcode <> "200" THEN
|
||||
|
||||
CALL req.sendTextResponse(501,NULL,"No pudimos procesar el file")
|
||||
|
||||
ELSE
|
||||
LET doc = xml.DomDocument.Create()
|
||||
CALL doc.setFeature("format-pretty-print",TRUE)
|
||||
CALL doc.load(fileafirmar_f)
|
||||
CALL req.sendXmlResponse(200,NULL,doc)
|
||||
# CALL req.sendTextResponse(200,NULL,resp)
|
||||
END IF
|
||||
|
||||
|
||||
|
||||
END FUNCTION
|
||||
|
||||
|
||||
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 getxmldata()
|
||||
DEFINE i, l INTEGER
|
||||
DEFINE r om.XmlReader
|
||||
DEFINE e,tok STRING,
|
||||
pfechafirmadigital VARCHAR(50),
|
||||
facturainterna INT
|
||||
DEFINE a om.SaxAttributes
|
||||
DISPLAY "filexml: ",filexml
|
||||
LET r = om.XmlReader.createFileReader(filexml)
|
||||
LET l = 0
|
||||
LET e = r.read()
|
||||
|
||||
WHILE e IS NOT NULL
|
||||
CASE e
|
||||
WHEN "StartDocument"
|
||||
# DISPLAY "StartDocument:"
|
||||
WHEN "StartElement"
|
||||
LET l=l+1
|
||||
#DISPLAY l SPACES, "StartElement:", r.getTagName()
|
||||
LET a = r.getAttributes()
|
||||
FOR i=1 to a.getLength()
|
||||
IF a.getName(i) = "SignatureValue" THEN
|
||||
# DISPLAY l SPACES," ",
|
||||
# a.getName(i)," = ",
|
||||
# a.getValueByIndex(i)
|
||||
END IF
|
||||
END FOR
|
||||
WHEN "Characters"
|
||||
|
||||
|
||||
IF r.getTagName() = "TipoeCF" THEN
|
||||
LET tipoecf = r.getCharacters()
|
||||
EXIT CASE
|
||||
END IF
|
||||
IF r.getTagName() = "FechaHoraFirma" THEN
|
||||
LET pfechafirmadigital = r.getCharacters()
|
||||
EXIT CASE
|
||||
END IF
|
||||
IF r.getTagName() = "RNCEmisor" THEN
|
||||
LET rnc_e = r.getCharacters()
|
||||
EXIT CASE
|
||||
END IF
|
||||
IF r.getTagName() = "eNCF" THEN
|
||||
LET e_ncf = r.getCharacters()
|
||||
EXIT CASE
|
||||
END IF
|
||||
IF r.getTagName() = "RNCComprador" THEN
|
||||
LET rnc_c = r.getCharacters()
|
||||
EXIT CASE
|
||||
END IF
|
||||
|
||||
WHEN "SkippedEntity"
|
||||
# DISPLAY "Entity:'",r.skippedEntity(),"'"
|
||||
WHEN "EndElement"
|
||||
# DISPLAY l SPACES, "EndElement:", r.getTagName()
|
||||
LET l=l-1
|
||||
WHEN "EndDocument"
|
||||
# DISPLAY "EndDocument:"
|
||||
OTHERWISE
|
||||
# DISPLAY "Invalid event: ",e
|
||||
END CASE
|
||||
LET e=r.read()
|
||||
END WHILE
|
||||
# RETURN phash,pfechafirmadigital,facturainterna
|
||||
END FUNCTION
|
||||
FUNCTION read_request(req)
|
||||
# DEFINE doc xml.DomDocument
|
||||
DEFINE req com.HttpServiceRequest
|
||||
DEFINE cmd,recibido,tmpfile 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()
|
||||
LET filexml = filexml CLIPPED,rnc_e CLIPPED,e_ncf CLIPPED,".xml"
|
||||
CALL doc.save(filexml)
|
||||
CALL formaracuse() RETURNING filexml
|
||||
CALL firmadocumento(filexml)
|
||||
CALL doc.load(fileafirmar_f)
|
||||
LET cmd = doc.saveToString()
|
||||
|
||||
RETURN 200,cmd
|
||||
|
||||
ELSE
|
||||
RETURN 401,"Falla en el proceso del file"
|
||||
|
||||
END IF
|
||||
# CATCH
|
||||
|
||||
# CALL show_err(SFMT("Unexpected HTTP request read exception: %1", STATUS))
|
||||
# RETURN FALSE
|
||||
# END TRY
|
||||
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user