366 lines
17 KiB
JavaScript
366 lines
17 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var IResource_1 = require("../../../resource/v1/IResource");
|
|
var WebDAVRequest_1 = require("../WebDAVRequest");
|
|
var xml_js_builder_1 = require("xml-js-builder");
|
|
var Workflow_1 = require("../../../helper/Workflow");
|
|
var FSPath_1 = require("../../../manager/v1/FSPath");
|
|
var Errors_1 = require("../../../Errors");
|
|
var http = require("http");
|
|
function lockDiscovery(lockDiscoveryCache, arg, path, resource, callback) {
|
|
var cached = lockDiscoveryCache[path.toString()];
|
|
if (cached) {
|
|
callback(null, cached);
|
|
return;
|
|
}
|
|
var _Callback = callback;
|
|
callback = function (e, l) {
|
|
if (!e)
|
|
lockDiscoveryCache[path.toString()] = l;
|
|
_Callback(e, l);
|
|
};
|
|
arg.requireErPrivilege('canListLocks', resource, function (e, can) {
|
|
if (e || !can) {
|
|
callback(e, {});
|
|
return;
|
|
}
|
|
resource.getLocks(function (e, locks) {
|
|
var _a;
|
|
if (e === Errors_1.Errors.MustIgnore) {
|
|
locks = [];
|
|
}
|
|
else if (e) {
|
|
callback(e, null);
|
|
return;
|
|
}
|
|
if (resource.parent) {
|
|
var parentPath = path.getParent();
|
|
lockDiscovery(lockDiscoveryCache, arg, parentPath, resource.parent, function (e, l) {
|
|
if (e)
|
|
callback(e, null);
|
|
else {
|
|
l[path.toString()] = locks;
|
|
callback(null, l);
|
|
}
|
|
});
|
|
}
|
|
else
|
|
callback(null, (_a = {},
|
|
_a[path.toString()] = locks,
|
|
_a));
|
|
});
|
|
});
|
|
}
|
|
function parseRequestBody(arg) {
|
|
var allTrue = {
|
|
leftElements: [],
|
|
mustDisplay: function () { return true; },
|
|
mustDisplayValue: function () { return true; }
|
|
};
|
|
var onlyName = {
|
|
leftElements: [],
|
|
mustDisplay: function () { return true; },
|
|
mustDisplayValue: function () { return false; }
|
|
};
|
|
if (arg.contentLength <= 0)
|
|
return allTrue;
|
|
try {
|
|
var xml = xml_js_builder_1.XML.parse(arg.data);
|
|
var propfind = xml.find('DAV:propfind');
|
|
if (propfind.findIndex('DAV:propname') !== -1)
|
|
return onlyName;
|
|
if (propfind.findIndex('DAV:allprop') !== -1)
|
|
return allTrue;
|
|
var prop_1 = propfind.find('DAV:prop');
|
|
var fn = function (name) {
|
|
var index = prop_1.findIndex(name);
|
|
if (index === -1)
|
|
return false;
|
|
prop_1.elements.splice(index, 1);
|
|
return true;
|
|
};
|
|
return {
|
|
leftElements: prop_1.elements,
|
|
mustDisplay: fn,
|
|
mustDisplayValue: function () { return true; }
|
|
};
|
|
}
|
|
catch (ex) {
|
|
return allTrue;
|
|
}
|
|
}
|
|
function encode(url) {
|
|
return url;
|
|
}
|
|
function propstatStatus(status) {
|
|
return 'HTTP/1.1 ' + status + ' ' + http.STATUS_CODES[status];
|
|
}
|
|
function method(arg, callback) {
|
|
arg.getResource(function (e, resource) {
|
|
if (e || !resource) {
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.NotFound);
|
|
callback();
|
|
return;
|
|
}
|
|
var lockDiscoveryCache = {};
|
|
arg.checkIfHeader(resource, function () {
|
|
var targetSource = arg.isSource;
|
|
var multistatus = new xml_js_builder_1.XMLElementBuilder('D:multistatus', {
|
|
'xmlns:D': 'DAV:'
|
|
});
|
|
resource.type(function (e, type) { return process.nextTick(function () {
|
|
if (!type.isDirectory || arg.depth === 0) {
|
|
addXMLInfo(resource, multistatus, function (e) {
|
|
if (!e)
|
|
done(multistatus);
|
|
else {
|
|
if (e === Errors_1.Errors.BadAuthentication)
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.Unauthorized);
|
|
else
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
callback();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
arg.requirePrivilege('canGetChildren', resource, function () {
|
|
resource.getChildren(function (e, children) { return process.nextTick(function () {
|
|
function err(e) {
|
|
if (e === Errors_1.Errors.BadAuthentication)
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.Unauthorized);
|
|
else
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
callback();
|
|
}
|
|
addXMLInfo(resource, multistatus, function (e) {
|
|
if (e) {
|
|
err(e);
|
|
return;
|
|
}
|
|
new Workflow_1.Workflow()
|
|
.each(children, function (r, cb) { return addXMLInfo(r, multistatus, cb); })
|
|
.error(err)
|
|
.done(function () {
|
|
done(multistatus);
|
|
});
|
|
});
|
|
}); });
|
|
});
|
|
}); });
|
|
function addXMLInfo(resource, multistatus, _callback) {
|
|
var reqBody = parseRequestBody(arg);
|
|
var response = new xml_js_builder_1.XMLElementBuilder('D:response');
|
|
var callback = function (e) {
|
|
if (e === Errors_1.Errors.MustIgnore)
|
|
e = null;
|
|
else if (!e)
|
|
multistatus.add(response);
|
|
_callback(e);
|
|
};
|
|
var propstat = response.ele('D:propstat');
|
|
var privileges = [
|
|
'canGetCreationDate', 'canGetAvailableLocks', 'canGetLastModifiedDate', 'canGetMimeType', 'canGetProperties', 'canGetSize', 'canGetType', 'canGetWebName'
|
|
];
|
|
if (targetSource)
|
|
privileges.push('canSource');
|
|
arg.requireErPrivilege(privileges, resource, function (e, can) {
|
|
if (e) {
|
|
callback(e);
|
|
return;
|
|
}
|
|
if (!can) {
|
|
callback(Errors_1.Errors.BadAuthentication);
|
|
return;
|
|
}
|
|
propstat.ele('D:status').add('HTTP/1.1 200 OK');
|
|
var prop = propstat.ele('D:prop');
|
|
var nb = 1;
|
|
function nbOut(error) {
|
|
if (nb > 0 && error) {
|
|
nb = -1000;
|
|
callback(error);
|
|
return;
|
|
}
|
|
--nb;
|
|
if (nb === 0) {
|
|
if (reqBody.leftElements.length > 0) {
|
|
var propstatError = response.ele('D:propstat');
|
|
var prop_2 = propstatError.ele('D:prop');
|
|
propstatError.ele('D:status').add(propstatStatus(WebDAVRequest_1.HTTPCodes.NotFound));
|
|
for (var _i = 0, _a = reqBody.leftElements; _i < _a.length; _i++) {
|
|
var el = _a[_i];
|
|
if (el)
|
|
prop_2.ele(el.name);
|
|
}
|
|
}
|
|
callback();
|
|
}
|
|
}
|
|
var tags = {};
|
|
function mustDisplayTag(name) {
|
|
if (reqBody.mustDisplay('DAV:' + name))
|
|
tags[name] = {
|
|
el: prop.ele('D:' + name),
|
|
value: reqBody.mustDisplayValue('DAV:' + name)
|
|
};
|
|
else
|
|
tags[name] = {
|
|
value: false
|
|
};
|
|
}
|
|
mustDisplayTag('getlastmodified');
|
|
mustDisplayTag('lockdiscovery');
|
|
mustDisplayTag('supportedlock');
|
|
mustDisplayTag('creationdate');
|
|
mustDisplayTag('resourcetype');
|
|
mustDisplayTag('displayname');
|
|
mustDisplayTag('getetag');
|
|
function displayValue(values, fn) {
|
|
if (values.constructor === String ? tags[values].value : values.some(function (n) { return tags[n].value; })) {
|
|
++nb;
|
|
process.nextTick(fn);
|
|
}
|
|
}
|
|
displayValue('creationdate', function () {
|
|
resource.creationDate(function (e, ticks) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.creationdate.el.add(arg.dateISO8601(ticks));
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
++nb;
|
|
arg.getResourcePath(resource, function (e, path) {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
if (tags.lockdiscovery.value) {
|
|
++nb;
|
|
lockDiscovery(lockDiscoveryCache, arg, new FSPath_1.FSPath(path), resource, function (e, l) {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
for (var path_1 in l) {
|
|
for (var _i = 0, _a = l[path_1]; _i < _a.length; _i++) {
|
|
var _lock = _a[_i];
|
|
var lock = _lock;
|
|
var activelock = tags.lockdiscovery.el.ele('D:activelock');
|
|
activelock.ele('D:lockscope').ele('D:' + lock.lockKind.scope.value.toLowerCase());
|
|
activelock.ele('D:locktype').ele('D:' + lock.lockKind.type.value.toLowerCase());
|
|
activelock.ele('D:depth').add('Infinity');
|
|
if (lock.owner)
|
|
activelock.ele('D:owner').add(lock.owner);
|
|
activelock.ele('D:timeout').add('Second-' + (lock.expirationDate - Date.now()));
|
|
activelock.ele('D:locktoken').ele('D:href', undefined, true).add(lock.uuid);
|
|
activelock.ele('D:lockroot').ele('D:href', undefined, true).add(encode(arg.fullUri(path_1)));
|
|
}
|
|
}
|
|
nbOut(null);
|
|
});
|
|
}
|
|
resource.type(function (e, type) { return process.nextTick(function () {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
var p = encode(arg.fullUri(path));
|
|
var href = p.lastIndexOf('/') !== p.length - 1 && type.isDirectory ? p + '/' : p;
|
|
response.ele('D:href', undefined, true).add(href);
|
|
response.ele('D:location').ele('D:href', undefined, true).add(p);
|
|
if (tags.resourcetype.value && type.isDirectory)
|
|
tags.resourcetype.el.ele('D:collection');
|
|
if (type.isFile) {
|
|
mustDisplayTag('getcontentlength');
|
|
mustDisplayTag('getcontenttype');
|
|
if (tags.getcontenttype.value) {
|
|
++nb;
|
|
resource.mimeType(targetSource, function (e, mimeType) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.getcontenttype.el.add(mimeType);
|
|
nbOut(e);
|
|
}); });
|
|
}
|
|
if (tags.getcontentlength.value) {
|
|
++nb;
|
|
resource.size(targetSource, function (e, size) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.getcontentlength.el.add(size === undefined || size === null || size.constructor !== Number ? 0 : size);
|
|
nbOut(e);
|
|
}); });
|
|
}
|
|
}
|
|
nbOut();
|
|
}); });
|
|
});
|
|
displayValue('displayname', function () {
|
|
var methodDisplayName = resource.webName;
|
|
if (resource.displayName)
|
|
methodDisplayName = resource.displayName;
|
|
methodDisplayName.bind(resource)(function (e, name) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.displayname.el.add(name ? encode(name) : '');
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
displayValue('supportedlock', function () {
|
|
resource.getAvailableLocks(function (e, lockKinds) { return process.nextTick(function () {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
lockKinds.forEach(function (lockKind) {
|
|
var lockentry = tags.supportedlock.el.ele('D:lockentry');
|
|
var lockscope = lockentry.ele('D:lockscope');
|
|
lockscope.ele('D:' + lockKind.scope.value.toLowerCase());
|
|
var locktype = lockentry.ele('D:locktype');
|
|
locktype.ele('D:' + lockKind.type.value.toLowerCase());
|
|
});
|
|
nbOut();
|
|
}); });
|
|
});
|
|
displayValue(['getetag', 'getlastmodified'], function () {
|
|
resource.lastModifiedDate(function (e, lastModifiedDate) { return process.nextTick(function () {
|
|
if (!e) {
|
|
if (tags.getetag.value)
|
|
tags.getetag.el.add(IResource_1.ETag.createETag(lastModifiedDate));
|
|
if (tags.getlastmodified.value)
|
|
tags.getlastmodified.el.add(new Date(lastModifiedDate).toUTCString());
|
|
}
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
++nb;
|
|
process.nextTick(function () {
|
|
resource.getProperties(function (e, properties) { return process.nextTick(function () {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
for (var name_1 in properties) {
|
|
if (reqBody.mustDisplay(name_1)) {
|
|
var tag = prop.ele(name_1);
|
|
if (reqBody.mustDisplayValue(name_1))
|
|
tag.add(properties[name_1]);
|
|
}
|
|
}
|
|
nbOut();
|
|
}); });
|
|
});
|
|
nbOut();
|
|
});
|
|
}
|
|
function done(multistatus) {
|
|
arg.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
|
|
arg.writeXML(multistatus);
|
|
callback();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
exports.method = method;
|
|
method.isValidFor = function (type) {
|
|
return !!type;
|
|
};
|
|
exports.default = method;
|