236 lines
7.4 KiB
C++
236 lines
7.4 KiB
C++
<% /*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: api.inc
|
|
Description: Functies voor API's
|
|
Notes:
|
|
|
|
*/
|
|
|
|
function API_func(APIname)
|
|
{
|
|
this.APIname = APIname || getQParam("API");
|
|
var sql = "SELECT *"
|
|
+ " FROM fac_api"
|
|
+ " WHERE fac_api_name = " + safe.quoted_sql(this.APIname);
|
|
var oRs = Oracle.Execute(sql);
|
|
if (oRs.Eof)
|
|
{
|
|
this.error("Invalid API: " + this.APIname);
|
|
oRs.Close();
|
|
Response.End;
|
|
}
|
|
|
|
if (user_key < 0)
|
|
{
|
|
this.APIKEY = getQParam("APIKEY", "");
|
|
if (!this.APIKEY && S("basic_auth_realm"))
|
|
{
|
|
Response.Status = "401 Unauthorized";
|
|
Response.AddHeader("WWW-Authenticate", "Basic realm=\"" + S("basic_auth_realm") + "\"");
|
|
Response.End;
|
|
}
|
|
else
|
|
{
|
|
var sql2 = "SELECT prs_perslid_key, prs_perslid_naam"
|
|
+ " FROM prs_perslid"
|
|
+ " WHERE prs_perslid_apikey = " + safe.quoted_sql(this.APIKEY)
|
|
+ " AND prs_perslid_verwijder IS NULL"; // Eigenlijk zou de trigger APIKEY moeten wissen bij verwijderen
|
|
var oRs2 = Oracle.Execute(sql2);
|
|
if (oRs2.Eof)
|
|
{
|
|
this.error("Invalid APIKEY: " + this.APIKEY);
|
|
oRs2.Close();
|
|
Response.End;
|
|
};
|
|
__Log("API User is: " + oRs2("prs_perslid_naam").Value);
|
|
// JGL: komen we hier ooit? Gebeurt nu ooit dit: /* global */ user = new Perslid(user_key);
|
|
user_key = oRs2("prs_perslid_key").Value;
|
|
oRs2.Close();
|
|
}
|
|
}
|
|
|
|
this.apidata =
|
|
{
|
|
APIname: this.APIname,
|
|
APIKEY: this.APIKEY,
|
|
file: oRs("fac_api_filepath").Value,
|
|
prs_perslid_key: user_key,
|
|
loglevel: oRs("fac_api_loglevel").Value,
|
|
errorhandling: oRs("fac_api_errorhandling").Value,
|
|
usrrap_key: oRs("fac_usrrap_key").Value,
|
|
stylesheet: oRs("fac_api_stylesheet").Value,
|
|
stylesheet_out: oRs("fac_api_stylesheet_out").Value
|
|
};
|
|
|
|
if (this.apidata.loglevel > 1) // Zet maar op 3 als je HTML logging wilt
|
|
{
|
|
__Logging = this.apidata.loglevel || __Logging || 0; // Voor de rest van dit bestand
|
|
__Log("Logging for this API ({0}) is forced on".format(this.APIname), '#f00');
|
|
}
|
|
|
|
try
|
|
{
|
|
if (oRs("fac_api_options_json").Value)
|
|
this.apidata.options = JSON.parse(oRs("fac_api_options_json").Value);
|
|
}
|
|
catch (e)
|
|
{
|
|
__DoLog(e);
|
|
this.error("Invalid api 'options': " + e.description);
|
|
}
|
|
try
|
|
{
|
|
if (oRs("fac_api_viewmapping_json").Value)
|
|
this.apidata.viewmapping = JSON.parse(oRs("fac_api_viewmapping_json").Value);
|
|
}
|
|
catch (e)
|
|
{
|
|
this.error("Invalid api 'viewmapping': " + e.description);
|
|
}
|
|
|
|
oRs.Close();
|
|
// Wij doen niets met eventuele prs_perslid_key; dat doet loginTry.asp maar voor ons
|
|
}
|
|
|
|
API_func.prototype.error = function (msg)
|
|
{
|
|
if (JSON_Result && JSON) // Merk op dat 'invalid APIKEY' al door /default.asp
|
|
{ // is onderschept en dus niet hier komt.
|
|
Response.Write(JSON.stringify({ success: false, message: msg }));
|
|
}
|
|
else
|
|
{
|
|
Response.Status = "500 Internal server error"; // 500_error.asp blijkt hier niet op in te grijpen
|
|
Response.Write(safe.html(msg));
|
|
// Op productie zie je bovenstaande Response.Write ook niet terug in Fiddler omdat
|
|
// 'detailed error messages' uit staat. Daarom ook maar loggen voor het gemak.
|
|
__DoLog(safe.html(msg), "#ff0000");
|
|
}
|
|
Response.End;
|
|
}
|
|
|
|
// LET OP: Verwacht wordt dat de JSON-code in de body utf-8 encoded is, niet windows-1252!
|
|
// (in de praktijk moet je *moeite* doen om windows-1252 te krijgen dus dit is handiger)
|
|
function RequestJSON(loglevel)
|
|
{
|
|
var jvraag;
|
|
if(Request.TotalBytes == 0)
|
|
{
|
|
return { error: "Empty body posted" }
|
|
}
|
|
|
|
var lngBytesCount = Request.TotalBytes;
|
|
jvraag = BytesToStr(Request.BinaryRead(lngBytesCount));
|
|
__Log("Vraag: " + jvraag);
|
|
try
|
|
{
|
|
var vraag = myJSON.parse(jvraag);
|
|
if (loglevel)
|
|
__Log2File(JSON.stringify(vraag, null, 2), API.APIname + "_IN", ".json");
|
|
}
|
|
catch (e)
|
|
{
|
|
__DoLog("eval faalt met: {0}<br>{1}".format(e.description, jvraag), "ffff00");
|
|
return null;
|
|
}
|
|
return vraag;
|
|
}
|
|
|
|
function RequestXML(API)
|
|
{
|
|
var xvraag;
|
|
if(Request.TotalBytes == 0)
|
|
{
|
|
return { error: "Empty body posted" }
|
|
}
|
|
|
|
var lngBytesCount = Request.TotalBytes;
|
|
xvraag = BytesToStr(Request.BinaryRead(lngBytesCount));
|
|
if (API.apidata.loglevel)
|
|
__Log2File(xvraag, API.APIname + "_IN");
|
|
|
|
__Log("Request body: " + xvraag);
|
|
try
|
|
{
|
|
var inputXML = Server.CreateObject("MSXML2.DOMDocument.6.0");
|
|
inputXML.loadXML(xvraag); // inputXML.load(Request) zou nog niet vertalen naar Windows-1252
|
|
}
|
|
catch (e)
|
|
{
|
|
return { error: e.description };
|
|
}
|
|
if (inputXML.parseError.errorCode)
|
|
{
|
|
return { error: inputXML.parseError.reason + " @ " + inputXML.parseError.line + "." + inputXML.parseError.linepos };
|
|
}
|
|
return { xml: inputXML };
|
|
}
|
|
|
|
// Eventuele input stylesheet is er overheen
|
|
function styledRequestXML(API)
|
|
{
|
|
var xmlReq = Server.CreateObject("MSXML2.DOMDocument.6.0");
|
|
var parsed = RequestXML(API);
|
|
if (parsed.error)
|
|
{
|
|
var method = String(Request.ServerVariables("REQUEST_METHOD"));
|
|
if (method != "POST") // gebeurt nog wel eens
|
|
{
|
|
__DoLog( "Weird: expected method POST, got " + method);
|
|
}
|
|
API.error("Error loading XML: " + parsed.error);
|
|
}
|
|
|
|
if (API.apidata.stylesheet)
|
|
{
|
|
var iXsl = Server.CreateObject("MSXML2.DOMDocument.6.0");
|
|
iXsl.resolveExternals = true; // XSL kan includes hebben (MARX#51709)
|
|
if( ! iXsl.load(Server.MapPath(API.apidata.stylesheet)) )
|
|
{
|
|
API.error("Could not load XSL " + API.apidata.stylesheet + "\n" + iXsl.parseError.reason);
|
|
}
|
|
var inputXML = Server.CreateObject("MSXML2.DOMDocument.6.0");
|
|
inputXML = parsed.xml;
|
|
inputXML.transformNodeToObject(iXsl, xmlReq);
|
|
if (API.apidata.loglevel) __Log2File(xmlReq.xml, API.APIname + "_TUSSEN");
|
|
}
|
|
else
|
|
var xmlReq = parsed.xml;
|
|
|
|
return xmlReq;
|
|
}
|
|
|
|
function BytesToStr(bytes)
|
|
{
|
|
var stream = Server.CreateObject("ADODB.STREAM");
|
|
stream.type = 1;
|
|
stream.open;
|
|
stream.write(bytes);
|
|
stream.position = 0;
|
|
stream.type = 2; // Text
|
|
stream.charset = "utf-8";
|
|
|
|
// Mogelijk was het nog utf-8. Dat is riskant met unicode quotes (FCLT#60591)
|
|
// Daarom expliciete conversie
|
|
var win1252Stream = new ActiveXObject("ADODB.Stream");
|
|
win1252Stream.Open();
|
|
win1252Stream.CharSet = "Windows-1252"; // het doel
|
|
stream.copyTo(win1252Stream);
|
|
stream.close;
|
|
|
|
win1252Stream.position = 0;
|
|
|
|
var ReadBytes = 131072; // optimaal volgens https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/readtext-method?view=sql-server-ver15
|
|
var sOut = "";
|
|
while (!win1252Stream.EOS)
|
|
{
|
|
sOut = sOut + win1252Stream.ReadText(ReadBytes);
|
|
}
|
|
win1252Stream.close;
|
|
|
|
return sOut;
|
|
}
|
|
|
|
%> |