Permalink
Browse files

trying to fix propfind 404 requests and more porting from PHP

  • Loading branch information...
1 parent 03333a9 commit e2b60fbcc4d457e820eb0e5ff7d7446d87691305 @mikedeboer committed Jan 16, 2013
Showing with 534 additions and 508 deletions.
  1. +4 −3 lib/DAV/handler.js
  2. +529 −504 lib/DAVACL/plugin.js
  3. +1 −1 lib/DAVACL/principal.js
View
7 lib/DAV/handler.js
@@ -223,7 +223,7 @@ exports.STATUS_MAP = {
};
}
- this.dispatchEvent("beforeMethod", method, function(stop) {
+ this.dispatchEvent("beforeMethod", method, this.getRequestUri(), function(stop) {
if (stop === true)
return;
if (stop)
@@ -1559,7 +1559,8 @@ exports.STATUS_MAP = {
nodes[path] = parentNode;
nodesPath.push(path);
- console.log("getPropertiesForPath", depth, parentNode,parentNode.hasFeature(jsDAV_iCollection));
+ if (jsDAV.debugMode)
+ console.log("getPropertiesForPath", depth, parentNode,parentNode.hasFeature(jsDAV_iCollection));
if (depth == 1 && parentNode.hasFeature(jsDAV_iCollection)) {
parentNode.getChildren(function(err, cNodes) {
if (!Util.empty(err))
@@ -1584,7 +1585,7 @@ exports.STATUS_MAP = {
function afterGetProperty(rprop, rpath, remRT, newProps, cbnext) {
// If we were unable to find the property, we will list it as 404.
if (!allProperties && newProps["200"][rprop])
- delete newProps["404"][rprop];
+ newProps["404"][rprop] = null;
var node = nodes[rpath];
rpath = Util.trim(rpath, "/");
View
1,033 lib/DAVACL/plugin.js
@@ -49,9 +49,9 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
/**
* Reference to server object.
*
- * @var jsDAV_Server
+ * @var jsDAV_Handler
*/
- server: null
+ handler: null,
/**
* List of urls containing principal collections.
@@ -61,7 +61,7 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
*/
principalCollectionSet: [
"principals"
- ];
+ ],
/**
* By default ACL is only enforced for nodes that have ACL support (the
@@ -177,47 +177,37 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
*
* @param string uri
* @param array|string privileges
- * @param int recursion
- * @param bool throwExceptions if set to false, this method won't throw exceptions.
- * @throws Sabre\DAVACL\Exception\NeedPrivileges
+ * @param number recursion
+ * @throws jsDAV_Exception_NeedPrivileges
* @return bool
*/
- checkPrivileges: function(uri, privileges, recursion, throwExceptions) {
- if (!is_array(privileges)) privileges = array(privileges);
- if (typeof throwExceptions == "undefined")
- throwExceptions = true;
+ checkPrivileges: function(uri, privileges, recursion, callback) {
+ if (!Array.isArray(privileges))
+ privileges = [privileges];
+
recursion = recursion || this.R_PARENT;
+ var self = this;
- acl = this.getCurrentUserPrivilegeSet(uri);
+ this.getCurrentUserPrivilegeSet(uri, function(err, acl) {
+ if (err)
+ return callback(err);
- if (is_null(acl)) {
- if (this.allowAccessToNodesWithoutACL) {
- return true;
- } else {
- if (throwExceptions)
- throw new Exception\NeedPrivileges(uri,privileges);
+ if (acl) {
+ if (self.allowAccessToNodesWithoutACL)
+ return callback(null, true);
else
- return false;
-
+ return callback(new Exc.NeedPrivileges(uri, privileges), false);
}
- }
- failed = array();
- foreach(privileges as priv) {
+ var failed = privileges.filter(function(priv) {
+ return acl.indexOf(priv) === -1;
+ });
- if (!in_array(priv, acl)) {
- failed[] = priv;
- }
-
- }
+ if (failed.length)
+ return callback(new Exc.NeedPrivileges(uri, failed), false);
- if (failed) {
- if (throwExceptions)
- throw new Exception\NeedPrivileges(uri,failed);
- else
- return false;
- }
- return true;
+ return true;
+ });
},
/**
@@ -228,18 +218,22 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
*
* @return string|null
*/
- public function getCurrentUserPrincipal() {
-
- authPlugin = this.server.getPlugin("auth");
- if (is_null(authPlugin)) return null;
- /** @var authPlugin Sabre\DAV\Auth\Plugin */
-
- userName = authPlugin.getCurrentUser();
- if (!userName) return null;
-
- return this.defaultUsernamePath . "/" . userName;
-
- }
+ getCurrentUserPrincipal: function(callback) {
+ var authPlugin = this.handler.plugins.auth;
+
+ if (!authPlugin)
+ return callback();
+ /** @var authPlugin jsDAV_Auth_Plugin */
+
+ var self = this;
+ authPlugin.getCurrentUser(function(err, userName) {
+ if (err)
+ return callback(err);
+ if (!userName)
+ return callback();
+ callback(null, self.defaultUsernamePath + "/" + userName);
+ });
+ },
/**
@@ -248,71 +242,85 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
*
* @return array
*/
- public function getCurrentUserPrincipals() {
-
- currentUser = this.getCurrentUserPrincipal();
-
- if (is_null(currentUser)) return array();
-
- return array_merge(
- array(currentUser),
- this.getPrincipalMembership(currentUser)
- );
-
- }
+ getCurrentUserPrincipals: function(callback) {
+ var self = this;
+ this.getCurrentUserPrincipal(function(err, currentUser) {
+ if (err)
+ return callback(err);
+ if (!currentUser)
+ return callback(null, []);
+
+ self.getPrincipalMembership(currentUser, function(err, membership) {
+ if (err)
+ return callback(err);
+ callback(null, [currentUser].concat(membership));
+ });
+ });
+ },
/**
* This array holds a cache for all the principals that are associated with
* a single principal.
*
* @var array
*/
- protected principalMembershipCache = array();
-
+ principalMembershipCache: [],
/**
* Returns all the principal groups the specified principal is a member of.
*
* @param string principal
* @return array
*/
- public function getPrincipalMembership(mainPrincipal) {
-
+ getPrincipalMembership: function(mainPrincipal, callback) {
// First check our cache
- if (isset(this.principalMembershipCache[mainPrincipal])) {
- return this.principalMembershipCache[mainPrincipal];
+ if (this.principalMembershipCache[mainPrincipal])
+ return callback(null, this.principalMembershipCache[mainPrincipal]);
+
+ var check = [mainPrincipal];
+ var principals = [];
+ var self = this;
+
+ function checkNext() {
+ var principal = check.shift();
+ if (!principal)
+ return checkedAll();
+
+ self.handler.getNodeForPath(principal, function(err, node) {
+ if (err)
+ return checkedAll(err);
+
+ if (node.hasFeature(jsDAVACL_iPrincipal)) {
+ node.getGroupMembership(function(err, memberships) {
+ if (err)
+ return checkedAll(err);
+
+ memberships.forEach(function(groupMember) {
+ if (pricipals.indexOf(groupMember) === -1) {
+ check.push(groupMember);
+ principals.push(groupMember);
+ }
+ });
+ checkNext();
+ });
+ }
+ else
+ checkNext();
+ });
}
- check = array(mainPrincipal);
- principals = array();
-
- while(count(check)) {
-
- principal = array_shift(check);
+ function checkedAll(err) {
+ if (err)
+ return callback(err, []);
- node = this.server.tree.getNodeForPath(principal);
- if (node instanceof IPrincipal) {
- foreach(node.getGroupMembership() as groupMember) {
-
- if (!in_array(groupMember, principals)) {
-
- check[] = groupMember;
- principals[] = groupMember;
-
- }
-
- }
-
- }
+ // Store the result in the cache
+ self.principalMembershipCache[mainPrincipal] = principals;
+ callback(err, principals);
}
- // Store the result in the cache
- this.principalMembershipCache[mainPrincipal] = principals;
-
- return principals;
-
- }
+ checkNext();
+ },
/**
* Returns the supported privilege structure for this ACL plugin.
@@ -326,81 +334,89 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string|DAV\INode node
* @return array
*/
- public function getSupportedPrivilegeSet(node) {
-
- if (is_string(node)) {
- node = this.server.tree.getNodeForPath(node);
+ getSupportedPrivilegeSet: function(node, callback) {
+ if (!node.hasFeature) {
+ this.handler.getNodeForPath(node, function(err, n) {
+ if (err)
+ return callback(err);
+ node = n;
+ gotNode();
+ });
}
-
- if (node instanceof IACL) {
- result = node.getSupportedPrivilegeSet();
-
- if (result)
- return result;
+ else
+ gotNode();
+
+ var self = this;
+
+ function gotNode() {
+ if (node.getSupportedPrivilegeSet) {
+ node.getSupportedPrivilegeSet(function(err, result) {
+ if (err)
+ return callback(err);
+ callback(null, result || self.getDefaultSupportedPrivilegeSet());
+ });
+ }
+ else
+ callback(null, self.getDefaultSupportedPrivilegeSet());
}
-
- return self::getDefaultSupportedPrivilegeSet();
-
- }
+ },
/**
* Returns a fairly standard set of privileges, which may be useful for
* other systems to use as a basis.
*
* @return array
*/
- static function getDefaultSupportedPrivilegeSet() {
-
- return array(
- "privilege" => "{DAV:}all",
- "abstract" => true,
- "aggregates" => array(
- array(
- "privilege" => "{DAV:}read",
- "aggregates" => array(
- array(
- "privilege" => "{DAV:}read-acl",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}read-current-user-privilege-set",
- "abstract" => true,
- ),
- ),
- ), // {DAV:}read
- array(
- "privilege" => "{DAV:}write",
- "aggregates" => array(
- array(
- "privilege" => "{DAV:}write-acl",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}write-properties",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}write-content",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}bind",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}unbind",
- "abstract" => true,
- ),
- array(
- "privilege" => "{DAV:}unlock",
- "abstract" => true,
- ),
- ),
- ), // {DAV:}write
- ),
- ); // {DAV:}all
-
- }
+ getDefaultSupportedPrivilegeSet: function() {
+ return {
+ "privilege" : "{DAV:}all",
+ "abstract" : true,
+ "aggregates" : [
+ {
+ "privilege" : "{DAV:}read",
+ "aggregates" : [
+ {
+ "privilege" : "{DAV:}read-acl",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}read-current-user-privilege-set",
+ "abstract" : true
+ }
+ ]
+ }, // {DAV:}read
+ {
+ "privilege" : "{DAV:}write",
+ "aggregates" : [
+ {
+ "privilege" : "{DAV:}write-acl",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}write-properties",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}write-content",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}bind",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}unbind",
+ "abstract" : true
+ },
+ {
+ "privilege" : "{DAV:}unlock",
+ "abstract" : true
+ }
+ ]
+ } // {DAV:}write
+ ]
+ }; // {DAV:}all
+ },
/**
* Returns the supported privilege set as a flat list
@@ -416,53 +432,42 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string|DAV\INode node
* @return array
*/
- final public function getFlatPrivilegeSet(node) {
-
- privs = this.getSupportedPrivilegeSet(node);
-
- flat = array();
- this.getFPSTraverse(privs, null, flat);
-
- return flat;
-
- }
-
- /**
- * Traverses the privilege set tree for reordering
- *
- * This function is solely used by getFlatPrivilegeSet, and would have been
- * a closure if it wasn't for the fact I need to support PHP 5.2.
- *
- * @param array priv
- * @param concrete
- * @param array flat
- * @return void
- */
- final private function getFPSTraverse(priv, concrete, &flat) {
-
- myPriv = array(
- "privilege" => priv["privilege"],
- "abstract" => isset(priv["abstract"]) && priv["abstract"],
- "aggregates" => array(),
- "concrete" => isset(priv["abstract"]) && priv["abstract"]?concrete:priv["privilege"],
- );
-
- if (isset(priv["aggregates"]))
- foreach(priv["aggregates"] as subPriv) myPriv["aggregates"][] = subPriv["privilege"];
-
- flat[priv["privilege"]] = myPriv;
-
- if (isset(priv["aggregates"])) {
-
- foreach(priv["aggregates"] as subPriv) {
+ getFlatPrivilegeSet: function(node, callback) {
+ var self = this;
+
+ this.getSupportedPrivilegeSet(node, function(err, privs) {
+ if (err)
+ return callback(err);
+
+ var flat = [];
+
+ // Traverses the privilege set tree for reordering
+ function getFPSTraverse(priv, isConcrete, flat) {
+ myPriv = {
+ "privilege" : priv.privilege,
+ "abstract" : !!priv.abstract && priv.abstract,
+ "aggregates" : [],
+ "concrete" : !!priv.abstract && priv.abstract ? isConcrete : priv.privilege
+ };
+
+ if (priv.aggregates) {
+ priv.aggregates.forEach(function(subPriv) {
+ myPriv.aggregates.push(subPriv.privilege);
+ });
+ }
- this.getFPSTraverse(subPriv, myPriv["concrete"], flat);
+ flat[priv.privilege] = myPriv;
+ if (priv.aggregates) {
+ priv.aggregates.forEach(function(subPriv) {
+ getFPSTraverse(subPriv, myPriv.concrete, flat);
+ });
+ }
}
- }
-
- }
+ callback(null, getFPSTraverse(privs, null, []));
+ });
+ },
/**
* Returns the full ACL list.
@@ -474,110 +479,128 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string|DAV\INode node
* @return array
*/
- public function getACL(node) {
-
- if (is_string(node)) {
- node = this.server.tree.getNodeForPath(node);
- }
- if (!node instanceof IACL) {
- return null;
+ getACL: function(node, callback) {
+ if (typeof node == "string") {
+ node = this.handler.getNodeForPath(node, function(err, n) {
+ if (err)
+ return callback(err);
+ node = n;
+ gotNode();
+ });
}
- acl = node.getACL();
- foreach(this.adminPrincipals as adminPrincipal) {
- acl[] = array(
- "principal" => adminPrincipal,
- "privilege" => "{DAV:}all",
- "protected" => true,
- );
+ else
+ gotNode();
+
+ var self = this;
+
+ function gotNode() {
+ if (!node.hasFeature(jsDAVACL_iACL))
+ return callback();
+
+ node.getACL(function(err, acl) {
+ if (err)
+ return callback(err);
+
+ self.adminPrincipals.forEach(function(adminPrincipal) {
+ acl.push({
+ "principal" : adminPrincipal,
+ "privilege" : "{DAV:}all",
+ "protected" : true
+ });
+ });
+ return callback(null, acl);
+ });
}
- return acl;
-
- }
+ },
/**
* Returns a list of privileges the current user has
* on a particular node.
*
- * Either a uri or a DAV\INode may be passed.
+ * Either a uri or a jsDAV_iNode may be passed.
*
* null will be returned if the node doesn't support ACLs.
*
- * @param string|DAV\INode node
+ * @param string|jsDAV_iNode node
* @return array
*/
- public function getCurrentUserPrivilegeSet(node) {
-
- if (is_string(node)) {
- node = this.server.tree.getNodeForPath(node);
+ getCurrentUserPrivilegeSet: function(node, callback) {
+ if (typeof node == "string") {
+ node = this.handler.getNodeForPath(node, function(err, n) {
+ if (err)
+ return callback(err);
+ node = n;
+ gotNode();
+ });
}
-
- acl = this.getACL(node);
-
- if (is_null(acl)) return null;
-
- principals = this.getCurrentUserPrincipals();
-
- collected = array();
-
- foreach(acl as ace) {
-
- principal = ace["principal"];
-
- switch(principal) {
-
- case "{DAV:}owner" :
- owner = node.getOwner();
- if (owner && in_array(owner, principals)) {
- collected[] = ace;
- }
- break;
-
-
- // 'all' matches for every user
- case "{DAV:}all" :
-
- // 'authenticated' matched for every user that's logged in.
- // Since it's not possible to use ACL while not being logged
- // in, this is also always true.
- case "{DAV:}authenticated" :
- collected[] = ace;
- break;
-
- // 'unauthenticated' can never occur either, so we simply
- // ignore these.
- case "{DAV:}unauthenticated" :
- break;
-
- default :
- if (in_array(ace["principal"], principals)) {
- collected[] = ace;
- }
- break;
-
- }
-
-
- }
-
- // Now we deduct all aggregated privileges.
- flat = this.getFlatPrivilegeSet(node);
-
- collected2 = array();
- while(count(collected)) {
-
- current = array_pop(collected);
- collected2[] = current["privilege"];
-
- foreach(flat[current["privilege"]]["aggregates"] as subPriv) {
- collected2[] = subPriv;
- collected[] = flat[subPriv];
- }
-
+ else
+ gotNode();
+
+ var self = this;
+
+ function gotNode() {
+ self.getACL(node, function(err, acl) {
+ if (err)
+ return callback(err);
+ if (!acl)
+ return callback();
+
+ self.getCurrentUserPrincipals(function(err, principals) {
+ if (err)
+ return callback(err);
+
+ var collected = [];
+
+ acl.forEach(function(ace) {
+ var principal = ace.principal;
+ switch (principal) {
+ case "{DAV:}owner" :
+ var owner = node.getOwner();
+ if (owner && principals.indexOf(owner) > -1)
+ collected.push(ace);
+ break;
+ // 'all' matches for every user
+ case "{DAV:}all" :
+ // 'authenticated' matched for every user that's logged in.
+ // Since it's not possible to use ACL while not being logged
+ // in, this is also always true.
+ case "{DAV:}authenticated" :
+ collected.push(ace);
+ break;
+ // 'unauthenticated' can never occur either, so we simply
+ // ignore these.
+ case "{DAV:}unauthenticated" :
+ break;
+ default :
+ if (principals.indexOf(ace.principal) > -1)
+ collected.push(ace);
+ break;
+ }
+ });
+
+ // Now we deduct all aggregated privileges.
+ self.getFlatPrivilegeSet(node, function(err, flat) {
+ if (err)
+ return callback(err);
+
+ var current;
+ var collected2 = [];
+ while (collected.length) {
+ current = collected.pop();
+ collected2.push(current.privilege);
+
+ flat[current["privilege"]]["aggregates"].forEach(function(subPriv) {
+ collected2.push(subPriv);
+ collected.push(flat[subPriv]);
+ });
+ }
+
+ callback(null, Util.makeUnique(collected2));
+ });
+ });
+ });
}
-
- return array_values(array_unique(collected2));
-
- }
+ },
/**
* Principal property search
@@ -601,65 +624,80 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* properties are index by a HTTP status code.
*
*/
- public function principalSearch(array searchProperties, array requestedProperties, collectionUri = null) {
-
- if (!is_null(collectionUri)) {
- uris = array(collectionUri);
- } else {
+ principalSearch: function(searchProperties, requestedProperties, collectionUri) {
+ var uris;
+ if (collectionUri)
+ uris = [collectionUri];
+ else
uris = this.principalCollectionSet;
- }
-
- lookupResults = array();
- foreach(uris as uri) {
-
- principalCollection = this.server.tree.getNodeForPath(uri);
- if (!principalCollection instanceof IPrincipalCollection) {
- // Not a principal collection, we're simply going to ignore
- // this.
- continue;
- }
-
- results = principalCollection.searchPrincipals(searchProperties);
- foreach(results as result) {
- lookupResults[] = rtrim(uri,"/") . "/" . result;
- }
- }
-
- matches = array();
-
- foreach(lookupResults as lookupResult) {
-
- list(matches[]) = this.server.getPropertiesForPath(lookupResult, requestedProperties, 0);
-
- }
-
- return matches;
+ lookupResults = [];
+ var self = this;
+ Async.list(uris)
+ .each(function(uri, next) {
+ self.handler.getNodeForPath(uri, function(err, principalCollection) {
+ if (err)
+ return next(err);
+
+ if (!principalCollection.hasFeature(jsDAVACL_iPrincipalCollection)) {
+ // Not a principal collection, we're simply going to ignore
+ // this.
+ return next();
+ }
- }
+ principalCollection.searchPrincipals(searchProperties, function(err, results) {
+ if (err)
+ return next(err);
+
+ results.forEach(function(result) {
+ lookupResults.push(Util.rtrim(uri, "/") + "/" + result);
+ });
+ next();
+ });
+ });
+ })
+ .end(function(err) {
+ if (err)
+ return callback(err);
+
+ var matches = [];
+ Async.list(lookupResults)
+ .each(function(lookupResult, next) {
+ self.handler.getPropertiesForPath(lookupResult, requestedProperties, 0, function(err, props) {
+ if (err)
+ return next(err);
+
+ matches.push(props);
+ next();
+ });
+ })
+ .end(function(err) {
+ callback(err, matches)
+ });
+ });
+ },
/**
* Sets up the plugin
*
* This method is automatically called by the server class.
*
- * @param DAV\Server server
+ * @param jsDAV_Handler handler
* @return void
*/
- public function initialize(DAV\Server server) {
-
- this.server = server;
- server.subscribeEvent("beforeGetProperties",array(this,"beforeGetProperties"));
-
- server.subscribeEvent("beforeMethod", array(this,"beforeMethod"),20);
- server.subscribeEvent("beforeBind", array(this,"beforeBind"),20);
- server.subscribeEvent("beforeUnbind", array(this,"beforeUnbind"),20);
- server.subscribeEvent("updateProperties",array(this,"updateProperties"));
- server.subscribeEvent("beforeUnlock", array(this,"beforeUnlock"),20);
- server.subscribeEvent("report",array(this,"report"));
- server.subscribeEvent("unknownMethod", array(this, "unknownMethod"));
-
- array_push(server.protectedProperties,
+ initialize: function(handler) {
+ this.handler = handler;
+
+ handler.addEventListener("beforeGetProperties", this.beforeGetProperties.bind(this));
+ handler.addEventListener("beforeMethod", this.beforeMethod.bind(this));
+ handler.addEventListener("beforeBind", this.beforeBind.bind(this));
+ handler.addEventListener("beforeUnbind", this.beforeUnbind.bind(this));
+ handler.addEventListener("updateProperties",this.updateProperties.bind(this));
+ handler.addEventListener("beforeUnlock", this.beforeUnlock.bind(this));
+ handler.addEventListener("report",this.report.bind(this));
+ handler.addEventListener("unknownMethod", this.unknownMethod.bind(this));
+
+ handler.protectedProperties.push(
"{DAV:}alternate-URI-set",
"{DAV:}principal-URL",
"{DAV:}group-membership",
@@ -676,16 +714,12 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
// Automatically mapping nodes implementing IPrincipal to the
// {DAV:}principal resourcetype.
- server.resourceTypeMapping["Sabre\\DAVACL\\IPrincipal"] = "{DAV:}principal";
+ handler.resourceTypeMapping["jsDAVACL_iPrincipal"] = "{DAV:}principal";
// Mapping the group-member-set property to the HrefList property
// class.
- server.propertyMap["{DAV:}group-member-set"] = "Sabre\\DAV\\Property\\HrefList";
-
- }
-
-
- /* {{{ Event handlers */
+ handler.propertyMap["{DAV:}group-member-set"] = "jsDAV_Property_HrefList";
+ },
/**
* Triggered before any method is handled
@@ -694,61 +728,57 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string uri
* @return void
*/
- public function beforeMethod(method, uri) {
-
- exists = this.server.tree.nodeExists(uri);
-
- // If the node doesn't exists, none of these checks apply
- if (!exists) return;
-
- switch(method) {
-
- case "GET" :
- case "HEAD" :
- case "OPTIONS" :
- // For these 3 we only need to know if the node is readable.
- this.checkPrivileges(uri,"{DAV:}read");
- break;
-
- case "PUT" :
- case "LOCK" :
- case "UNLOCK" :
- // This method requires the write-content priv if the node
- // already exists, and bind on the parent if the node is being
- // created.
- // The bind privilege is handled in the beforeBind event.
- this.checkPrivileges(uri,"{DAV:}write-content");
- break;
-
-
- case "PROPPATCH" :
- this.checkPrivileges(uri,"{DAV:}write-properties");
- break;
-
- case "ACL" :
- this.checkPrivileges(uri,"{DAV:}write-acl");
- break;
-
- case "COPY" :
- case "MOVE" :
- // Copy requires read privileges on the entire source tree.
- // If the target exists write-content normally needs to be
- // checked, however, we're deleting the node beforehand and
- // creating a new one after, so this is handled by the
- // beforeUnbind event.
- //
- // The creation of the new node is handled by the beforeBind
- // event.
- //
- // If MOVE is used beforeUnbind will also be used to check if
- // the sourcenode can be deleted.
- this.checkPrivileges(uri,"{DAV:}read",self::R_RECURSIVE);
-
- break;
-
- }
-
- }
+ beforeMethod: function(e, method, uri) {
+ var self = this;
+ this.handler.getNodeForPath(uri, function(err, node) {
+ // do not yield errors:
+ // If the node doesn't exists, none of these checks apply
+ if (err)
+ return e.next();
+
+ switch(method) {
+ case "GET" :
+ case "HEAD" :
+ case "OPTIONS" :
+ // For these 3 we only need to know if the node is readable.
+ self.checkPrivileges(uri, "{DAV:}read", null, e.next);
+ break;
+ case "PUT" :
+ case "LOCK" :
+ case "UNLOCK" :
+ // This method requires the write-content priv if the node
+ // already exists, and bind on the parent if the node is being
+ // created.
+ // The bind privilege is handled in the beforeBind event.
+ self.checkPrivileges(uri, "{DAV:}write-content", null, e.next);
+ break;
+ case "PROPPATCH" :
+ self.checkPrivileges(uri, "{DAV:}write-properties", null, e.next);
+ break;
+ case "ACL" :
+ self.checkPrivileges(uri, "{DAV:}write-acl", null, e.next);
+ break;
+ case "COPY" :
+ case "MOVE" :
+ // Copy requires read privileges on the entire source tree.
+ // If the target exists write-content normally needs to be
+ // checked, however, we're deleting the node beforehand and
+ // creating a new one after, so this is handled by the
+ // beforeUnbind event.
+ //
+ // The creation of the new node is handled by the beforeBind
+ // event.
+ //
+ // If MOVE is used beforeUnbind will also be used to check if
+ // the sourcenode can be deleted.
+ self.checkPrivileges(uri, "{DAV:}read", self.R_RECURSIVE, e.next);
+ break;
+ default:
+ e.next();
+ break;
+ }
+ });
+ },
/**
* Triggered before a new node is created.
@@ -759,12 +789,10 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string uri
* @return void
*/
- public function beforeBind(uri) {
-
- list(parentUri,nodeName) = DAV\URLUtil::splitPath(uri);
- this.checkPrivileges(parentUri,"{DAV:}bind");
-
- }
+ beforeBind: function(e, uri) {
+ var parentUri = Util.splitPath(uri)[0];
+ this.checkPrivileges(parentUri, "{DAV:}bind", null, e.next);
+ },
/**
* Triggered before a node is deleted
@@ -775,12 +803,10 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @param string uri
* @return void
*/
- public function beforeUnbind(uri) {
-
- list(parentUri,nodeName) = DAV\URLUtil::splitPath(uri);
- this.checkPrivileges(parentUri,"{DAV:}unbind",self::R_RECURSIVEPARENTS);
-
- }
+ beforeUnbind: function(e, uri) {
+ var parentUri = Util.splitPath(uri)[0];
+ this.checkPrivileges(parentUri, "{DAV:}unbind", this.R_RECURSIVEPARENTS, e.next);
+ },
/**
* Triggered before a node is unlocked.
@@ -790,10 +816,9 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @TODO: not yet implemented
* @return void
*/
- public function beforeUnlock(uri, DAV\Locks\LockInfo lock) {
-
-
- }
+ beforeUnlock: function(e, uri, lock) {
+ e.next();
+ },
/**
* Triggered before properties are looked up in specific nodes.
@@ -805,139 +830,139 @@ var jsDAVACL_Plugin = module.exports = jsDAV_ServerPlugin.extend({
* @TODO really should be broken into multiple methods, or even a class.
* @return bool
*/
- public function beforeGetProperties(uri, DAV\INode node, &requestedProperties, &returnedProperties) {
-
+ beforeGetProperties: function(e, uri, node, requestedProperties, returnedProperties) {
// Checking the read permission
- if (!this.checkPrivileges(uri,"{DAV:}read",self::R_PARENT,false)) {
-
- // User is not allowed to read properties
- if (this.hideNodesFromListings) {
- return false;
+ var self = this;
+ this.checkPrivileges(uri,"{DAV:}read", this.R_PARENT, function(err, hasPriv) {
+ if (!hasPriv) {
+ // User is not allowed to read properties
+ if (self.hideNodesFromListings)
+ return e.stop();
+
+ // Marking all requested properties as '403'.
+ Object.keys(requestedProperties).forEach(function(key) {
+ delete requestedProperties[key];
+ returnedProperties["403"][requestedProperties[key]] = null;
+ });
+ return e.next();
}
- // Marking all requested properties as '403'.
- foreach(requestedProperties as key=>requestedProperty) {
- unset(requestedProperties[key]);
- returnedProperties[403][requestedProperty] = null;
- }
- return;
-
- }
-
- /* Adding principal properties */
- if (node instanceof IPrincipal) {
+ /* Adding principal properties */
+ if (node.hasFeature(jsDAVACL_iPrincipal)) {
+ if (false !== (index = array_search("{DAV:}alternate-URI-set", requestedProperties))) {
- if (false !== (index = array_search("{DAV:}alternate-URI-set", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}alternate-URI-set"] = new DAV\Property\HrefList(node.getAlternateUriSet());
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}alternate-URI-set"] = new DAV\Property\HrefList(node.getAlternateUriSet());
+ }
+ if (false !== (index = array_search("{DAV:}principal-URL", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}principal-URL", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}principal-URL"] = new DAV\Property\Href(node.getPrincipalUrl() . "/");
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}principal-URL"] = new DAV\Property\Href(node.getPrincipalUrl() . "/");
+ }
+ if (false !== (index = array_search("{DAV:}group-member-set", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}group-member-set", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}group-member-set"] = new DAV\Property\HrefList(node.getGroupMemberSet());
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}group-member-set"] = new DAV\Property\HrefList(node.getGroupMemberSet());
+ }
+ if (false !== (index = array_search("{DAV:}group-membership", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}group-membership", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}group-membership"] = new DAV\Property\HrefList(node.getGroupMembership());
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}group-membership"] = new DAV\Property\HrefList(node.getGroupMembership());
+ }
- }
+ if (false !== (index = array_search("{DAV:}displayname", requestedProperties))) {
- if (false !== (index = array_search("{DAV:}displayname", requestedProperties))) {
+ returnedProperties[200]["{DAV:}displayname"] = node.getDisplayName();
- returnedProperties[200]["{DAV:}displayname"] = node.getDisplayName();
+ }
}
+ if (false !== (index = array_search("{DAV:}principal-collection-set", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}principal-collection-set", requestedProperties))) {
+ unset(requestedProperties[index]);
+ val = this.principalCollectionSet;
+ // Ensuring all collections end with a slash
+ foreach(val as k=>v) val[k] = v . "/";
+ returnedProperties[200]["{DAV:}principal-collection-set"] = new DAV\Property\HrefList(val);
- unset(requestedProperties[index]);
- val = this.principalCollectionSet;
- // Ensuring all collections end with a slash
- foreach(val as k=>v) val[k] = v . "/";
- returnedProperties[200]["{DAV:}principal-collection-set"] = new DAV\Property\HrefList(val);
+ }
+ if (false !== (index = array_search("{DAV:}current-user-principal", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}current-user-principal", requestedProperties))) {
+ unset(requestedProperties[index]);
+ if (url = this.getCurrentUserPrincipal()) {
+ returnedProperties[200]["{DAV:}current-user-principal"] = new Property\Principal(Property\Principal::HREF, url . "/");
+ } else {
+ returnedProperties[200]["{DAV:}current-user-principal"] = new Property\Principal(Property\Principal::UNAUTHENTICATED);
+ }
- unset(requestedProperties[index]);
- if (url = this.getCurrentUserPrincipal()) {
- returnedProperties[200]["{DAV:}current-user-principal"] = new Property\Principal(Property\Principal::HREF, url . "/");
- } else {
- returnedProperties[200]["{DAV:}current-user-principal"] = new Property\Principal(Property\Principal::UNAUTHENTICATED);
}
+ if (false !== (index = array_search("{DAV:}supported-privilege-set", requestedProperties))) {
- }
- if (false !== (index = array_search("{DAV:}supported-privilege-set", requestedProperties))) {
-
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}supported-privilege-set"] = new Property\SupportedPrivilegeSet(this.getSupportedPrivilegeSet(node));
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}supported-privilege-set"] = new Property\SupportedPrivilegeSet(this.getSupportedPrivilegeSet(node));
- }
- if (false !== (index = array_search("{DAV:}current-user-privilege-set", requestedProperties))) {
+ }
+ if (false !== (index = array_search("{DAV:}current-user-privilege-set", requestedProperties))) {
- if (!this.checkPrivileges(uri, "{DAV:}read-current-user-privilege-set", self::R_PARENT, false)) {
- returnedProperties[403]["{DAV:}current-user-privilege-set"] = null;
- unset(requestedProperties[index]);
- } else {
- val = this.getCurrentUserPrivilegeSet(node);
- if (!is_null(val)) {
+ if (!this.checkPrivileges(uri, "{DAV:}read-current-user-privilege-set", self::R_PARENT, false)) {
+ returnedProperties[403]["{DAV:}current-user-privilege-set"] = null;
unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}current-user-privilege-set"] = new Property\CurrentUserPrivilegeSet(val);
+ } else {
+ val = this.getCurrentUserPrivilegeSet(node);
+ if (!is_null(val)) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}current-user-privilege-set"] = new Property\CurrentUserPrivilegeSet(val);
+ }
}
+
}
- }
+ /* The ACL property contains all the permissions */
+ if (false !== (index = array_search("{DAV:}acl", requestedProperties))) {
- /* The ACL property contains all the permissions */
- if (false !== (index = array_search("{DAV:}acl", requestedProperties))) {
+ if (!this.checkPrivileges(uri, "{DAV:}read-acl", self::R_PARENT, false)) {
- if (!this.checkPrivileges(uri, "{DAV:}read-acl", self::R_PARENT, false)) {
+ unset(requestedProperties[index]);
+ returnedProperties[403]["{DAV:}acl"] = null;
- unset(requestedProperties[index]);
- returnedProperties[403]["{DAV:}acl"] = null;
+ } else {
- } else {
+ acl = this.getACL(node);
+ if (!is_null(acl)) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}acl"] = new Property\Acl(this.getACL(node));
+ }
- acl = this.getACL(node);
- if (!is_null(acl)) {
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}acl"] = new Property\Acl(this.getACL(node));
}
}
- }
+ /* The acl-restrictions property contains information on how privileges
+ * must behave.
+ */
+ if (false !== (index = array_search("{DAV:}acl-restrictions", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}acl-restrictions"] = new Property\AclRestrictions();
+ }
- /* The acl-restrictions property contains information on how privileges
- * must behave.
- */
- if (false !== (index = array_search("{DAV:}acl-restrictions", requestedProperties))) {
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}acl-restrictions"] = new Property\AclRestrictions();
- }
+ /* Adding ACL properties */
+ if (node instanceof IACL) {
- /* Adding ACL properties */
- if (node instanceof IACL) {
+ if (false !== (index = array_search("{DAV:}owner", requestedProperties))) {
- if (false !== (index = array_search("{DAV:}owner", requestedProperties))) {
+ unset(requestedProperties[index]);
+ returnedProperties[200]["{DAV:}owner"] = new DAV\Property\Href(node.getOwner() . "/");
- unset(requestedProperties[index]);
- returnedProperties[200]["{DAV:}owner"] = new DAV\Property\Href(node.getOwner() . "/");
+ }
}
- }
+ });
+
}
View
2 lib/DAVACL/principal.js
@@ -151,7 +151,7 @@ var jsDAVACL_Principal = module.exports = jsDAV_Node.extend(jsDAVACL_iPrincipal,
* @param array requestedProperties
* @return array
*/
- getProperties: function(requestedProperties, callback) {
+ getProperties: function(requestedProperties) {
var newProperties = {};
for (var propName, i = 0, l = requestedProperties.length; i < l; ++i) {
propName = requestedProperties[i];

0 comments on commit e2b60fb

Please sign in to comment.