FSN#33339 API2 ook bijlagen ondersteunen *zonder* hmac

svn path=/Website/trunk/; revision=25690
This commit is contained in:
Jos Groot Lipman
2015-07-22 20:03:16 +00:00
parent b3ffda4fa5
commit 776b50974a
9 changed files with 131 additions and 83 deletions

View File

@@ -350,6 +350,7 @@ api2 = {
var selects = [];
var tables = [ model.tablesql || model.table ];
var wheres = [];
var orderbys = [];
var name_cnt = 0;
for (var fld in model.fields)
@@ -461,6 +462,10 @@ api2 = {
}
else
{
// In orderbys worden de include primary keys verzameld om te sorteren
// We bieden daar geen garantie op maar tijdens testen is deterministisch
// gedrag wel fijn.
orderbys.push(inc.model.aliasprefix + inc.model.primary);
// simpel op joinfield
wheres.push ( model.table + "." + model.primary + "=" + inc.model.table + "." + inc.joinfield + "(+)");
}
@@ -470,7 +475,7 @@ api2 = {
__Log("Unknown include '{0}' requested".format(params.include[i]));
}
}
return { selects: selects, tables: tables, wheres: wheres };
return { selects: selects, tables: tables, wheres: wheres, orderbys: orderbys };
},
// TODO the_key *moet* bestaan. Andere filtervelden negeren we

View File

@@ -54,8 +54,6 @@ api2_rest = {
oRs.Close();
}
/* global */ user = new Perslid(user_key);
CheckForLogging(Request.QueryString("logging")); // Nu pas kan autorisatie via user gecontrolerd worden
// Impersonate?
var IMPERS;
@@ -91,6 +89,9 @@ api2_rest = {
Response.End;
}
}
/* global */ user = new Perslid(user_key);
CheckForLogging(Request.QueryString("logging")); // Nu pas kan autorisatie via user gecontroleerd worden
},
process: function _process(model)
{
@@ -194,6 +195,14 @@ api2_rest = {
{
var result = model["REST_" + method]( requestparams, key );
}
else if (method == "GET" && filter.mode == "attachment" && "custom_fields" in model.includes)
{
requestparams.filter.id = key; // Die kan er maar beter wel zijn!
requestparams.include = ["custom_fields"];
var data = model.REST_GET(requestparams);
model.includes["custom_fields"].model.streamattachment(filter, data[0].custom_fields);
Response.End;
}
else if (method == "GET" || model.record_name in jsondata)
{
var result = model["REST_" + method]( requestparams, jsondata, key );
@@ -388,7 +397,6 @@ api2_rest = {
Response.End;
}
// if (API.apidata.loglevel) __Log2File(str_antwoord, APIname + "_OUT");
Response.write(str_antwoord);
},

View File

@@ -45,5 +45,5 @@
params = flexProps(pModule, pKey, String(pKenmerk_key), pNiveau);
StreamFile(params.AttachPath + "/" + safe.filename(pFileName), "application/octet-stream");
StreamFile(params.AttachPath, pFileName, "application/octet-stream");
%>

View File

@@ -17,7 +17,7 @@
<!-- #include file="../Shared/flexfiles.inc"-->
<%
function model_custom_fields(flexModule, flexId, flexParams)
function model_custom_fields(formodel, flexModule, flexParams)
{
flexParams = flexParams || {};
this.module = flexModule;
@@ -28,7 +28,7 @@ function model_custom_fields(flexModule, flexId, flexParams)
// this.records_title = L("lcl_orders");
// this.record_title = L("lcl_opdr_info");
var theSqlFlex = getSqlFlex(flexModule, flexId, flexParams);
var theSqlFlex = getSqlFlex(flexModule, formodel.primary, flexParams);
this.tablesql = "(" + theSqlFlex + ") flex"
this.fields =
@@ -45,7 +45,7 @@ function model_custom_fields(flexModule, flexId, flexParams)
{
if (record.type == 'F' || record.type == 'M')
{
var flexparam = flexProps(flexModule, record.pid, String(record.id), flexParams.pNiveau, { getFiles: true });
var flexparam = flexProps(flexModule, record.pid, String(record.id), flexParams.pNiveau, { getFiles: true, api2name: formodel.records_name });
record.attachments = [];
for (var f in flexparam.files)
{
@@ -53,11 +53,38 @@ function model_custom_fields(flexModule, flexId, flexParams)
record.attachments.push({ name: file.name,
date: file.date,
size: file.size,
temp_url: file.api2url,
content_url: file.deepurl,
digest: file.digest })
};
}
}
this.streamattachment = function(filter, flexfields)
{
for (var fid in flexfields)
{
if (flexfields[fid].id == filter.subfolder && flexfields[fid].attachments)
{
for (var i = 0; i < flexfields[fid].attachments.length; i++)
{
var att = flexfields[fid].attachments[i];
if (att.name == filter.filename) // Gevonden!!!!
{
params = flexProps(this.module, filter.id, filter.subfolder, flexParams.pNiveau);
var eTag = '"' + att.digest + '"';
Response.AddHeader("ETag", eTag);
if (Request.ServerVariables("HTTP_IF_NONE_MATCH") == eTag)
{ // We hebben een match!
Response.Clear();
Response.Status = "304 Not modified";
Response.End;
}
StreamFile(params.AttachPath, att.name, "application/octet-stream");
}
}
}
}
}
}
function set_custom_field(jsondata, kenmerk_key, val)

View File

@@ -87,7 +87,7 @@ function model_issues(mld_key, params)
return " mld_melding.mld_melding_key = mld_opdr.mld_melding_key(+) ";
}
},
"custom_fields" : { model: new model_custom_fields("MLD", "mld_melding_key", { pNiveau: "M", readman: true, readuse: true }),
"custom_fields" : { model: new model_custom_fields(this, "MLD", { pNiveau: "M", readman: true, readuse: true }),
joinfield: "flexparentkey"
}
};

View File

@@ -87,7 +87,7 @@ function model_orders(opdr_key, params)
return "(module='ORD' OR module IS NULL) AND fac_v_notes.parent_key(+) = mld_opdr.mld_opdr_key";
}
},
"custom_fields" : { model: new model_custom_fields("OPDR", "mld_opdr_key", { pNiveau: "O", readman: true, readuse: true }),
"custom_fields" : { model: new model_custom_fields(this, "OPDR", { pNiveau: "O", readman: true, readuse: true }),
joinfield: "flexparentkey"
}
};
@@ -352,12 +352,12 @@ function model_orders(opdr_key, params)
//
this._pre_analyze_fields(params, jsondata);
params.mld_opdr.opdr_key = opdr_key;
var fields = api2.update_fields(params, this, jsondata); // Build updater
if ("status" in fields)
fields["status"].savewhen = false; // Die gaan we handmatig doen
var dbfields = api2.update_fields(params, this, jsondata); // Build updater
if ("status" in dbfields)
dbfields["status"].savewhen = false; // Die gaan we handmatig doen
this._analyze_fields(fields, params, jsondata);
this._validate_fields(fields, params, jsondata);
this._analyze_fields(dbfields, params, jsondata);
this._validate_fields(dbfields, params, jsondata);
var upd_params = {};
upd_params.opdrkeyArray = [];
@@ -368,7 +368,7 @@ function model_orders(opdr_key, params)
upd_params.ter_fiattering = false;
upd_params.approver_key = -1;
upd_params.requestApproval = false;
var mldUpd = this._wijzig_opdracht(opdr_key, fields, params, jsondata, upd_params);
var mldUpd = this._wijzig_opdracht(opdr_key, dbfields, params, jsondata, upd_params);
this._materials(params);
this._set_autoorder_properties(params);
@@ -413,15 +413,15 @@ function model_orders(opdr_key, params)
//
this._pre_analyze_fields(params, jsondata);
params.mld_opdr.mld_key = mld_key;
var fields = api2.update_fields(params, this, jsondata); // Build updater
var dbfields = api2.update_fields(params, this, jsondata); // Build updater
this._analyze_fields(fields, params, jsondata);
this._validate_fields(fields, params, jsondata);
this._analyze_fields(dbfields, params, jsondata);
this._validate_fields(dbfields, params, jsondata);
var new_params = {};
new_params.requestApproval = false;
new_params.voluntaryApproval = params.filter.has_fiat && params.filter.fiat; // Vrijwillig fiatteren.
var mldNew = this._nieuwe_opdracht(mld_key, fields, params, jsondata, new_params);
var mldNew = this._nieuwe_opdracht(mld_key, dbfields, params, jsondata, new_params);
var opdr_key = mldNew.sequences["mld_opdr_key"];
this._materials(params);
@@ -437,7 +437,7 @@ function model_orders(opdr_key, params)
// Opdrachten zijn niet te verwijderen.
};
this._nieuwe_opdracht = function (mld_key, fields, params, jsondata, new_params)
this._nieuwe_opdracht = function (mld_key, dbfields, params, jsondata, new_params)
{ // nieuwe opdracht
// Persoonlijk Gebonden Budget (PGB) en/of Afdeling Gebonden Budget (AGB) controle
// mld_disc_info.disc_params_pgb: 0 = Geen van beiden
@@ -551,14 +551,14 @@ function model_orders(opdr_key, params)
// Deze velden staan niet in het model, maar moeten wel opgeslagen worden.
var volgsql = "mld.bepaalopdrmeldingvolgnr(" + mld_key +")";
fields["xx1"] = { dbs: "mld_opdr_bedrijfopdr_volgnr", typ: "sql", val: volgsql };
fields["xx2"] = { dbs: "mld_opdr_handfiat", typ: "check", val: (voluntaryApproval? 1 : 0) };
fields["xx3"] = { dbs: "mld_opdr_module", typ: "varchar", val: "MLD" };
fields["xx4"] = { dbs: "mld_melding_key", typ: "key", val: mld_key };
dbfields["xx1"] = { dbs: "mld_opdr_bedrijfopdr_volgnr", typ: "sql", val: volgsql };
dbfields["xx2"] = { dbs: "mld_opdr_handfiat", typ: "check", val: (voluntaryApproval? 1 : 0) };
dbfields["xx3"] = { dbs: "mld_opdr_module", typ: "varchar", val: "MLD" };
dbfields["xx4"] = { dbs: "mld_melding_key", typ: "key", val: mld_key };
//
// Velden die in het model staan, maar een defaultwaarde moeten krijgen.
uurloon = (uurloon > 0 ? uurloon : 0) // I.v.m. de bon moet het uurloon i.i.g. een waarde hebben zodat niet NaN wordt weergegeven.
api2.field_alter(fields, "hourrate", uurloon, this.fields);
api2.field_alter(dbfields, "hourrate", uurloon, this.fields);
//
// Vanuit het model_orders zullen de volgende velden worden opgeslagen (indien waarden via jsondata meegegeven)
// mld_uitvoerende_keys
@@ -571,7 +571,7 @@ function model_orders(opdr_key, params)
// mld_opdr_plandatum
//
// Deze velden niet opslaan.
delete fields["status"]; // status wordt later gedaan
delete dbfields["status"]; // status wordt later gedaan
// Startdatum is vandaag: starttijd is huidige tijd.
// Startdatum is niet vandaag: 1) Uitvoertijd is in uren => starttijd is begin werkdag (bijv. 7:00).
@@ -593,7 +593,7 @@ function model_orders(opdr_key, params)
startdate = (uitvoertijdInUren? startdatebegin : startdate.midnight()); //.getTime());
}
api2.field_alter(fields, "orderdate", startdate, this.fields);
api2.field_alter(dbfields, "orderdate", startdate, this.fields);
if (autoorder)
{
@@ -605,28 +605,28 @@ function model_orders(opdr_key, params)
var oms = mld_info.mld_omschr || "";
if (S("mld_ord_flexsummary") == 1)
oms += mld.getFlexSummary(mld_key);
api2.field_alter(fields, "enddate", einddatum, this.fields);
api2.field_alter(fields, "ordertype", t_opdr, this.fields);
api2.field_alter(dbfields, "enddate", einddatum, this.fields);
api2.field_alter(dbfields, "ordertype", t_opdr, this.fields);
// Ben ik zelf een geldige behandelaar? Dan invullen, anders leeg laten
mresult = user.func_enabled2("MLD", { ins_discipline_key: mld_info.disc });
if (mresult.canWrite("WEB_MLDBOF") || mresult.canWrite("WEB_MLDBO3"))
api2.field_alter(fields, "contact", user_key, this.fields);
api2.field_alter(dbfields, "contact", user_key, this.fields);
api2.field_alter(fields, "description", oms, this.fields);
api2.field_alter(fields, "hours", 0, this.fields);
delete fields["mld_opdr_opmerking"];
api2.field_alter(dbfields, "description", oms, this.fields);
api2.field_alter(dbfields, "hours", 0, this.fields);
delete dbfields["mld_opdr_opmerking"];
}
else
{
// waarden die in fields staan zijn goed.
// waarden die in dbfields staan zijn goed.
}
if (act_key > 0)
fields["act"] = { dbs: "fac_activiteit_key", typ: "key", val: act_key };
dbfields["act"] = { dbs: "fac_activiteit_key", typ: "key", val: act_key };
fields["id"] = { dbs: "mld_opdr_key", typ: "key", seq: "mld_s_mld_opdr_key" };
var mldIns = buildInsert("mld_opdr", fields, { noValidateToken: true });
dbfields["id"] = { dbs: "mld_opdr_key", typ: "key", seq: "mld_s_mld_opdr_key" };
var mldIns = buildInsert("mld_opdr", dbfields, { noValidateToken: true });
var opdr_key = mldIns.sequences["mld_opdr_key"];
sql = mldIns.sql;
var err = Oracle.Execute(sql, true);
@@ -716,7 +716,7 @@ function model_orders(opdr_key, params)
}; // Nieuwe opdracht
this._wijzig_opdracht = function (opdr_key, fields, params, jsondata, upd_params)
this._wijzig_opdracht = function (opdr_key, dbfields, params, jsondata, upd_params)
{ // Bestaande opdracht
// Hardness controle schrijfrechten
var this_opdr = mld.func_enabled_opdracht(opdr_key); // wat mag ik zoal op deze opdracht
@@ -815,25 +815,25 @@ function model_orders(opdr_key, params)
upd_params.checkteverzenden = checkTeVerzenden;
if (checkTeVerzenden)
{
fields["mustsend"] = { dbs: "mld_opdr_teverzenden", typ: "check", val: "" };
dbfields["mustsend"] = { dbs: "mld_opdr_teverzenden", typ: "check", val: "" };
}
if (!params.auth.ORDBOF)
{
// verwijder het veld mld_uitvoerende_keys
delete fields["supplier"];
delete dbfields["supplier"];
}
if (!this_opdr.canKostChange || S("mld_ord_show_kostenplaats") == 2)
{ // Bij bestaande melding kostenplaats opslaan als kostenplaats wijzigbaar en zichtbaar was,
// Als dit niet is: het veld verwidjeren
delete fields["account"];
delete dbfields["account"];
}
if (!StatusTV) // Alleen als status geen TV is zijn de kalenders niet readonly. authparamsORDFIN en kostentechnisch afmelden (ORDAFR) hebben geen invloed.
{
var ddfrom = "orderdate" in fields?fields["orderdate"].val:null;
var ddto = "enddate" in fields?fields["enddate"].val:null;
var ddfrom = "orderdate" in dbfields?dbfields["orderdate"].val:null;
var ddto = "enddate" in dbfields?dbfields["enddate"].val:null;
if (ddfrom && ddto) // (zijn ze soms toch nog readonly?)
{
var ddsql = "SELECT MIN (mld_opdr_uren_datum) ddmin, MAX (mld_opdr_uren_datum) ddmax"
@@ -884,39 +884,39 @@ function model_orders(opdr_key, params)
// else startdatum niet aanpassen.
oRs.Close();
// Waarde van "mld_opdr_datumbegin" aanpassen.
api2.field_alter(fields, "orderdate", startdate, this.fields);
api2.field_alter(dbfields, "orderdate", startdate, this.fields);
// Als uitvoertijd in uren is er een tijdsveld aanwezig geweest en dan wordt de tijd automatisch opgeslagen.
// : staat al in fields.
// : staat al in dbfields.
}
else
{
delete fields["orderdate"];
delete fields["enddate"];
delete dbfields["orderdate"];
delete dbfields["enddate"];
}
if (reapprove || refiat)
{ // Zet de refiat waarden. Het hergoedkeurings- en/of herfiatteringstraject wordt opnieuw ingegaan. // Tracking hiervan is niet nodig.
if (opdr_info.hours > 0)
fields["hoursrefiat"] = { dbs: "mld_opdr_uren_refiat", typ: "float", val: opdr_info.hours };
dbfields["hoursrefiat"] = { dbs: "mld_opdr_uren_refiat", typ: "float", val: opdr_info.hours };
if (opdr_info.h_rate > 0)
fields["raterefiat"] = { dbs: "mld_opdr_uurloon_refiat", typ: "float", val: opdr_info.h_rate };
dbfields["raterefiat"] = { dbs: "mld_opdr_uurloon_refiat", typ: "float", val: opdr_info.h_rate };
if (opdr_info.m_cost > 0)
fields["matrerialfiat"] = { dbs: "mld_opdr_materiaal_refiat", typ: "float", val: opdr_info.m_cost };
dbfields["matrerialfiat"] = { dbs: "mld_opdr_materiaal_refiat", typ: "float", val: opdr_info.m_cost };
if (opdr_info.t_cost > 0)
fields["costrefiat"] = { dbs: "mld_opdr_kosten_refiat", typ: "float", val: opdr_info.t_cost };
dbfields["costrefiat"] = { dbs: "mld_opdr_kosten_refiat", typ: "float", val: opdr_info.t_cost };
// Ook voor status 5 wordt refiatstatus gezet zodat bekend is dat het om een herfiattering gaat. De fiatteringsvoorwaarde is dan iets anders.
fields["statusrefiat"] = { dbs: "mld_statusopdr_key_refiat", typ: "number", val: opdr_info.opdr_status };
dbfields["statusrefiat"] = { dbs: "mld_statusopdr_key_refiat", typ: "number", val: opdr_info.opdr_status };
// Goedkeuring opnieuw ingaan kan alleen als het approved bedrag leeg is.
fields["approvedrefiat"] = { dbs: "mld_opdr_approved_refiat", typ: "float", val: opdr_info.approved };
fields["approved"] = { dbs: "mld_opdr_approved", typ: "float", val: null };
dbfields["approvedrefiat"] = { dbs: "mld_opdr_approved_refiat", typ: "float", val: opdr_info.approved };
dbfields["approved"] = { dbs: "mld_opdr_approved", typ: "float", val: null };
}
// Met FSN#20132 kan bij bestaande opdrachten via deze weg niet meer het opdrachttype wijzigen
// Documentfolders hernoemen (RenameFlexFolders) is dus niet meer nodig
var mldUpd = buildTrackingUpdate("mld_opdr", "mld_opdr_key = " + opdr_key, fields, { noValidateToken: true });
var mldUpd = buildTrackingUpdate("mld_opdr", "mld_opdr_key = " + opdr_key, dbfields, { noValidateToken: true });
var err = Oracle.Execute(mldUpd.sql, true);
if (err.friendlyMsg)

View File

@@ -1,8 +1,8 @@
<rules>
<!-- /api2/attachments/sample.doc?... /default.asp?api2=attachments&filename=sample.doc&... -->
<rule name="attachments" stopProcessing="true">
<match url="^api2/attachments/(.*)/?" />
<action type="Rewrite" url="default.asp?api2=attachments&amp;filename={R:1}" appendQueryString="true" />
<match url="^api2/([a-z0-9_]+)/(\d+)/attachments/(.*)/(.*)/?" />
<action type="Rewrite" url="default.asp?mode=attachment&amp;api2={R:1}&amp;id={R:2}&amp;subfolder={R:3}&amp;filename={R:4}" appendQueryString="true" />
</rule>
<!-- /api2/buildings/1234.xml?... /default.asp?api2=buildings&format=xml&id=1234&... -->
<rule name="api2SingleRecord" stopProcessing="true">

View File

@@ -68,6 +68,6 @@ DOCTYPE_Disable = 1; // ook al volgt straks een response.Clear
Response.End();
}
else
StreamFile(params.AttachPath + "/" + safe.filename(pFileName), "application/octet-stream")
StreamFile(params.AttachPath, pFileName, "application/octet-stream")
%>

View File

@@ -207,26 +207,34 @@ function flexProps(pModule, pKey, pSubpath, pNiveau, params)
for (; !fc.atEnd(); fc.moveNext())
{
var fsoFile = fc.item();
var sha_is = oCrypto.hex_sha1_file(result.AttachPath + "/" + fsoFile.Name);
var filedata = { name: fsoFile.Name,
date: new Date(fsoFile.DateLastModified),
size: fsoFile.Size,
digest: oCrypto.hex_sha1_file(result.AttachPath + "/" + fsoFile.Name)
}
var deepurl = HTTP.urlzelf() + "/appl/shared/BijlagenStream.asp"
+ "?module=" + pModule
+ "&key=" + pKey
+ (pNiveau? "&niveau=" + pNiveau : "")
+ "&kenmerk_key=" + pSubpath
+ "&filename=" + Server.URLencode(fsoFile.Name);
var api2url = HTTP.urlzelf() + "/api2/attachments/" + Server.URLencode(fsoFile.Name).replace(/\%2E/g, ".") // punten houden we graag
+ "?module=" + pModule
+ "&key=" + pKey
+ (pNiveau? "&niveau=" + pNiveau : "")
+ "&kenmerk_key=" + pSubpath;
result.files.push({ name: fsoFile.Name,
date: new Date(fsoFile.DateLastModified),
size: fsoFile.Size,
deepurl: protectQS.create(deepurl),
api2url: protectQS.create(api2url),
digest: sha_is
});
if (params.api2name)
{
var deepurl = HTTP.urlzelf() + "/api2/{0}/{1}/attachments/{2}/{3}".format(
params.api2name,
pKey,
pSubpath,
Server.URLencode(fsoFile.Name).replace(/\%2E/g, ".") // punten houden we graag
);
filedata.deepurl = deepurl;
}
else
{
var deepurl = HTTP.urlzelf() + "/appl/shared/BijlagenStream.asp"
+ "?module=" + pModule
+ "&key=" + pKey
+ (pNiveau? "&niveau=" + pNiveau : "")
+ "&kenmerk_key=" + pSubpath
+ "&filename=" + Server.URLencode(fsoFile.Name);
filedata.deepurl = protectQS.create(deepurl);
}
result.files.push(filedata);
}
}
}
@@ -364,7 +372,7 @@ function safeContentName(fname)
return safe.filename(fname).replace(/[\;\#]+/g, "_")
}
function StreamFile(filePath, mime)
function StreamFile(filePath, filename, mime)
{
try
{
@@ -372,13 +380,13 @@ function StreamFile(filePath, mime)
oStream.Open;
oStream.Type = 1; // adTypeBinary
oStream.LoadFromFile(filePath);
oStream.LoadFromFile(filePath + "/" + safe.filename(filename));
Response.clear;
Response.contenttype = mime;
// Known problems:
// "Plus+Quote'Spatie Rare<72>&amp.txt" non-ASCII karaketers in pFilename worden wel eens onbedoeld herkend als UTF8
Response.AddHeader("content-disposition", "attachment; filename= \"" + safeContentName(pFileName) + "\"");
Response.AddHeader("content-disposition", "attachment; filename= \"" + safeContentName(filename) + "\"");
Response.BinaryWrite(oStream.read(oStream.Size));
Response.End();
@@ -386,7 +394,7 @@ function StreamFile(filePath, mime)
catch(e)
{
Response.clear;
Response.Write(Server.HTMLEncode(pFileName) + "<P>" + e.description);
Response.Write(Server.HTMLEncode(filename) + "<P>" + e.description);
Response.Write("<P><xmp style='display:none'>" + Server.HTMLEncode(filePath) + "</xmp>");
}
oStream = null;