Skip to content

Commit

Permalink
Added the reverse operation in the PROPPATCH method to fit the RFC (1…
Browse files Browse the repository at this point in the history
… error => reverse changes)
  • Loading branch information
AdrienCastex committed Jun 29, 2017
1 parent a209249 commit f14cde3
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 29 deletions.
98 changes: 84 additions & 14 deletions lib/server/v2/commands/Proppatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var WebDAVRequest_1 = require("../WebDAVRequest");
var http_1 = require("http");
var Workflow_1 = require("../../../helper/Workflow");
var XML_1 = require("../../../helper/XML");
var Errors_1 = require("../../../Errors");
var default_1 = (function () {
function default_1() {
}
Expand All @@ -19,18 +20,47 @@ var default_1 = (function () {
try {
var xml = XML_1.XML.parse(data);
var root_1 = xml.find('DAV:propertyupdate');
var notifications_1 = {};
var reverse_1 = [];
var finalize_1 = function () {
finalize_1 = function () {
ctx.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
ctx.writeBody(multistatus);
callback();
var next = function () {
var codes = Object.keys(notifications_1);
codes.forEach(function (code) {
var propstat = response.ele('D:propstat');
var prop = propstat.ele('D:prop');
notifications_1[code].forEach(function (name) { return prop.ele(name); });
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + http_1.STATUS_CODES[code]);
});
ctx.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
ctx.writeBody(multistatus);
callback();
};
if (Object.keys(notifications_1).length > 1) {
new Workflow_1.Workflow()
.each(reverse_1, function (action, cb) { return action(cb); })
.error(function (e) {
if (!ctx.setCodeFromError(e))
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
callback();
})
.done(function () {
if (notifications_1[WebDAVRequest_1.HTTPCodes.OK]) {
notifications_1[WebDAVRequest_1.HTTPCodes.FailedDependency] = notifications_1[WebDAVRequest_1.HTTPCodes.OK];
delete notifications_1[WebDAVRequest_1.HTTPCodes.OK];
}
next();
});
}
else
next();
};
};
var notify_1 = function (el, error) {
var code = error ? WebDAVRequest_1.HTTPCodes.Forbidden : WebDAVRequest_1.HTTPCodes.OK;
var propstat = response.ele('D:propstat');
propstat.ele('D:prop').ele(el.name);
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + http_1.STATUS_CODES[code]);
if (!notifications_1[code])
notifications_1[code] = [];
notifications_1[code].push(el.name);
};
var execute_1 = function (name, eventName, fnProp) {
var list = root_1.findMany(name);
Expand All @@ -41,11 +71,16 @@ var default_1 = (function () {
list.forEach(function (el) {
var els = el.find('DAV:prop').elements;
new Workflow_1.Workflow(false)
.each(els, fnProp)
.each(els, function (x, cb) {
if (x.type !== 'element')
return cb();
fnProp(x, cb);
})
.intermediate(function (el, e) {
/*if(!e)
ctx.invokeEvent(eventName, r, el)*/
notify_1(el, e);
if (el.type === 'element')
notify_1(el, e);
})
.done(function () { return finalize_1(); });
});
Expand All @@ -66,12 +101,47 @@ var default_1 = (function () {
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
return callback();
}
execute_1('DAV:set', 'setProperty', function (el, callback) {
pm.setProperty(el.name, el.elements, callback);
});
execute_1('DAV:remove', 'removeProperty', function (el, callback) {
pm.removeProperty(el.name, callback);
});
pm.getProperties(function (e, props) {
if (e) {
if (!ctx.setCodeFromError(e))
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
return callback();
}
var properties = JSON.parse(JSON.stringify(props));
var pushSetReverseAction = function (el) {
var prop = properties[el.name];
if (prop)
reverse_1.push(function (cb) { return pm.setProperty(el.name, prop.value, prop.attributes, cb); });
else
reverse_1.push(function (cb) { return pm.removeProperty(el.name, cb); });
};
var pushRemoveReverseAction = function (el) {
var prop = properties[el.name];
reverse_1.push(function (cb) { return pm.setProperty(el.name, prop.value, prop.attributes, cb); });
};
execute_1('DAV:set', 'setProperty', function (el, callback) {
if (el.name.indexOf('DAV:') === 0) {
pushSetReverseAction(el);
return callback(Errors_1.Errors.Forbidden);
}
pm.setProperty(el.name, el.elements, el.attributes, function (e) {
if (!e)
pushSetReverseAction(el);
callback(e);
});
});
execute_1('DAV:remove', 'removeProperty', function (el, callback) {
if (el.name.indexOf('DAV:') === 0) {
pushRemoveReverseAction(el);
return callback(Errors_1.Errors.Forbidden);
}
pm.removeProperty(el.name, function (e) {
if (!e)
pushRemoveReverseAction(el);
callback(e);
});
});
}, false);
});
});
}
Expand Down
112 changes: 97 additions & 15 deletions src/server/v2/commands/Proppatch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HTTPCodes, HTTPMethod, RequestContext } from '../WebDAVRequest'
import { ResourceType } from '../../../manager/v2/fileSystem/CommonTypes'
import { IPropertyManager } from '../../../manager/v2/fileSystem/PropertyManager'
import { STATUS_CODES } from 'http'
import { Workflow } from '../../../helper/Workflow'
import { XML } from '../../../helper/XML'
import { XML, XMLElement } from '../../../helper/XML'
import { Errors } from '../../../Errors'

export default class implements HTTPMethod
Expand All @@ -22,23 +23,57 @@ export default class implements HTTPMethod
{
const xml = XML.parse(data);
const root = xml.find('DAV:propertyupdate');
const notifications : any = { }
const reverse = [];

let finalize = function()
{
finalize = function()
{
ctx.setCode(HTTPCodes.MultiStatus);
ctx.writeBody(multistatus);
callback();
const next = () => {
const codes = Object.keys(notifications);

codes.forEach((code) => {
const propstat = response.ele('D:propstat');
const prop = propstat.ele('D:prop');
notifications[code].forEach((name) => prop.ele(name));
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + STATUS_CODES[code]);
})

ctx.setCode(HTTPCodes.MultiStatus);
ctx.writeBody(multistatus);
callback();
}

if(Object.keys(notifications).length > 1)
{
new Workflow()
.each(reverse, (action, cb) => action(cb))
.error((e) => {
if(!ctx.setCodeFromError(e))
ctx.setCode(HTTPCodes.InternalServerError)
callback();
})
.done(() => {
if(notifications[HTTPCodes.OK])
{
notifications[HTTPCodes.FailedDependency] = notifications[HTTPCodes.OK];
delete notifications[HTTPCodes.OK];
}
next();
})
}
else
next();
}
}

const notify = function(el : any, error : any)
{
const code = error ? HTTPCodes.Forbidden : HTTPCodes.OK;
const propstat = response.ele('D:propstat');
propstat.ele('D:prop').ele(el.name);
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + STATUS_CODES[code]);
if(!notifications[code])
notifications[code] = [];
notifications[code].push(el.name);
}

const execute = function(name : string, eventName : /*EventsName*/string, fnProp)
Expand All @@ -54,11 +89,16 @@ export default class implements HTTPMethod
const els = el.find('DAV:prop').elements;

new Workflow(false)
.each(els, fnProp)
.each(els, (x, cb) => {
if(x.type !== 'element')
return cb();
fnProp(x, cb);
})
.intermediate((el, e) => {
/*if(!e)
ctx.invokeEvent(eventName, r, el)*/
notify(el, e)
if(el.type === 'element')
notify(el, e)
})
.done(() => finalize())
})
Expand All @@ -85,12 +125,54 @@ export default class implements HTTPMethod
return callback();
}

execute('DAV:set', 'setProperty', (el, callback) => {
pm.setProperty(el.name, el.elements, callback)
})
execute('DAV:remove', 'removeProperty', (el, callback) => {
pm.removeProperty(el.name, callback)
})
pm.getProperties((e, props) => {
if(e)
{
if(!ctx.setCodeFromError(e))
ctx.setCode(HTTPCodes.InternalServerError)
return callback();
}

const properties = JSON.parse(JSON.stringify(props));

const pushSetReverseAction = (el : XMLElement) => {
const prop = properties[el.name];
if(prop)
reverse.push((cb) => pm.setProperty(el.name, prop.value, prop.attributes, cb));
else
reverse.push((cb) => pm.removeProperty(el.name, cb));
}
const pushRemoveReverseAction = (el : XMLElement) => {
const prop = properties[el.name];
reverse.push((cb) => pm.setProperty(el.name, prop.value, prop.attributes, cb));
}
execute('DAV:set', 'setProperty', (el : XMLElement, callback) => {
if(el.name.indexOf('DAV:') === 0)
{
pushSetReverseAction(el);
return callback(Errors.Forbidden);
}

pm.setProperty(el.name, el.elements, el.attributes, (e) => {
if(!e)
pushSetReverseAction(el);
callback(e);
})
})
execute('DAV:remove', 'removeProperty', (el : XMLElement, callback) => {
if(el.name.indexOf('DAV:') === 0)
{
pushRemoveReverseAction(el);
return callback(Errors.Forbidden);
}

pm.removeProperty(el.name, (e) => {
if(!e)
pushRemoveReverseAction(el);
callback(e);
})
})
}, false)
})
})
}
Expand Down

0 comments on commit f14cde3

Please sign in to comment.