1 /* 2 * Copyright ©2012 SARA bv, The Netherlands 3 * 4 * This file is part of js-webdav-client. 5 * 6 * js-webdav-client is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published 8 * by the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * js-webdav-client is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with js-webdav-client. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 "use strict"; 20 21 // If nl.sara.webdav.Ace is already defined, we have a namespace clash! 22 if (nl.sara.webdav.Ace !== undefined) { 23 throw new nl.sara.webdav.Exception('Namespace nl.sara.webdav.Ace already taken, could not load JavaScript library for WebDAV connectivity.', nl.sara.webdav.Exception.NAMESPACE_TAKEN); 24 } 25 26 /** 27 * @class WebDAV property 28 * 29 * @param {Node} [xmlNode] Optional; the xmlNode describing the ace object (should be compliant with RFC 3744) 30 * @property {mixed} principal The principal. Is one of the class constants ALL, AUTHENTICATED, UNAUTHENTICATED or SELF or a String with the path to the principal or a property. See RFC 3744 for more information on this. 31 * @property {Boolean} invertprincipal Whether to invert the principal; true means 'all principals except the one specified'. Default is false. 32 * @property {Boolean} isprotected Whether this ACE is protected. Default is false. 33 * @property {Number} grantdeny Grant or deny ACE? Is one of the class constants GRANT or DENY. 34 * @property {mixed} inherited False if the ACE is not inherited, else a String with the path to the parent collection from which this ACE is inherited. 35 */ 36 nl.sara.webdav.Ace = function(xmlNode) { 37 // First define private attributes 38 Object.defineProperty(this, '_namespaces', { 39 'value': {}, 40 'enumerable': false, 41 'configurable': false, 42 'writable': true 43 }); 44 Object.defineProperty(this, '_principal', { 45 'value': null, 46 'enumerable': false, 47 'configurable': false, 48 'writable': true 49 }); 50 Object.defineProperty(this, '_invertprincipal', { 51 'value': false, 52 'enumerable': false, 53 'configurable': false, 54 'writable': true 55 }); 56 Object.defineProperty(this, '_grantdeny', { 57 'value': null, 58 'enumerable': false, 59 'configurable': false, 60 'writable': true 61 }); 62 Object.defineProperty(this, '_isprotected', { 63 'value': false, 64 'enumerable': false, 65 'configurable': false, 66 'writable': true 67 }); 68 Object.defineProperty(this, '_inherited', { 69 'value': false, 70 'enumerable': false, 71 'configurable': false, 72 'writable': true 73 }); 74 75 // Constructor logic 76 function parsePrincipal(object, child) { 77 if (!nl.sara.webdav.Ie.isIE && !(child instanceof Node)) { 78 throw new nl.sara.webdav.Exception('Principal XML node not recognized!', nl.sara.webdav.Exception.WRONG_XML); 79 } 80 for (var j = 0; j < child.childNodes.length; j++) { 81 var principal = child.childNodes.item(j); 82 if ((principal.nodeType !== 1) || (principal.namespaceURI === null) || (principal.namespaceURI !== 'DAV:')) { // Skip if not from the right namespace 83 continue; 84 } 85 switch (nl.sara.webdav.Ie.getLocalName(principal)) { 86 case 'href': 87 object.principal = principal.childNodes.item(0).nodeValue; 88 break; 89 case 'all': 90 object.principal = nl.sara.webdav.Ace.ALL; 91 break; 92 case 'authenticated': 93 object.principal = nl.sara.webdav.Ace.AUTHENTICATED; 94 break; 95 case 'unauthenticated': 96 object.principal = nl.sara.webdav.Ace.UNAUTHENTICATED; 97 break; 98 case 'property': 99 for (var k = 0; k < principal.childNodes.length; k++) { 100 var element = principal.childNodes.item(k); 101 if (element.nodeType !== 1) { 102 continue; 103 } 104 var prop = new nl.sara.webdav.Property(element); 105 object.principal = prop; 106 break; 107 } 108 break; 109 case 'self': 110 object.principal = nl.sara.webdav.Ace.SELF; 111 break; 112 default: 113 throw new nl.sara.webdav.Exception('Principal XML Node contains illegal child node: ' + nl.sara.webdav.Ie.getLocalName(principal), nl.sara.webdav.Exception.WRONG_XML); 114 break; 115 } 116 } 117 } 118 119 function parsePrivileges(object, privilegeList) { 120 for (var i = 0; i < privilegeList.length; i++) { 121 var privilege = privilegeList.item(i); 122 if ( ( privilege.nodeType === 1 ) && 123 ( privilege.namespaceURI === 'DAV:' ) && 124 ( nl.sara.webdav.Ie.getLocalName( privilege ) === 'privilege' ) ) { 125 object.addPrivilege( new nl.sara.webdav.Privilege( privilege.childNodes[0] ) ); 126 } 127 } 128 } 129 130 // Parse the XML 131 if (typeof xmlNode !== 'undefined') { 132 if ((xmlNode.namespaceURI !== 'DAV:') || (nl.sara.webdav.Ie.getLocalName(xmlNode) !== 'ace')) { 133 throw new nl.sara.webdav.Exception('Node is not of type DAV:ace', nl.sara.webdav.Exception.WRONG_XML); 134 } 135 var data = xmlNode.childNodes; 136 for (var i = 0; i < data.length; i++) { 137 var child = data.item(i); 138 if ((child.namespaceURI === null) || (child.namespaceURI !== 'DAV:')) { // Skip if not from the right namespace 139 continue; 140 } 141 switch (nl.sara.webdav.Ie.getLocalName(child)) { 142 case 'principal': 143 this.invertprincipal = false; 144 parsePrincipal(this, child); 145 break; 146 case 'invert': 147 this.invertprincipal = true; 148 for (var j = 0; j < child.childNodes.length; j++) { 149 var element = child.childNodes.item(j); 150 if ((element.namespaceURI !== 'DAV:') || (nl.sara.webdav.Ie.getLocalName(element) !== 'principal')) { 151 continue; 152 } 153 parsePrincipal(this, element); 154 } 155 break; 156 case 'grant': 157 this.grantdeny = nl.sara.webdav.Ace.GRANT; 158 parsePrivileges(this, child.childNodes); 159 break; 160 case 'deny': 161 this.grantdeny = nl.sara.webdav.Ace.DENY; 162 parsePrivileges(this, child.childNodes); 163 break; 164 case 'protected': 165 this.isprotected = true; 166 break; 167 case 'inherited': 168 for (var j = 0; j < child.childNodes.length; j++) { 169 var element = child.childNodes.item(j); 170 if ((element.namespaceURI !== 'DAV:') || (nl.sara.webdav.Ie.getLocalName(element) !== 'href')) { 171 continue; 172 } 173 this.inherited = child.childNodes.item(j).childNodes.item(0).nodeValue; 174 } 175 break; 176 } 177 } 178 } 179 }; 180 181 /**#@+ 182 * Class constant 183 */ 184 nl.sara.webdav.Ace.GRANT = 1; 185 nl.sara.webdav.Ace.DENY = 2; 186 nl.sara.webdav.Ace.ALL = 3; 187 nl.sara.webdav.Ace.AUTHENTICATED = 4; 188 nl.sara.webdav.Ace.UNAUTHENTICATED = 5; 189 nl.sara.webdav.Ace.SELF = 6; 190 /**#@-*/ 191 192 //######################### DEFINE PUBLIC ATTRIBUTES ########################### 193 Object.defineProperty(nl.sara.webdav.Ace.prototype, 'principal', { 194 'set': function(value) { 195 switch (value) { 196 case nl.sara.webdav.Ace.ALL: 197 case nl.sara.webdav.Ace.AUTHENTICATED: 198 case nl.sara.webdav.Ace.UNAUTHENTICATED: 199 case nl.sara.webdav.Ace.SELF: 200 break; 201 default: // If it isn't one of the constants, it should be either a Property object or a string/URL 202 if (!nl.sara.webdav.Ie.isIE && !(value instanceof nl.sara.webdav.Property)) { 203 value = String(value); 204 } 205 break; 206 } 207 this._principal = value; 208 }, 209 'get': function() { 210 return this._principal; 211 } 212 }); 213 214 Object.defineProperty(nl.sara.webdav.Ace.prototype, 'invertprincipal', { 215 'set': function(value) { 216 this._invertprincipal = Boolean(value); 217 }, 218 'get': function() { 219 return this._invertprincipal; 220 } 221 }); 222 223 Object.defineProperty(nl.sara.webdav.Ace.prototype, 'isprotected', { 224 'set': function(value) { 225 this._isprotected = Boolean(value); 226 }, 227 'get': function() { 228 return this._isprotected; 229 } 230 }); 231 232 Object.defineProperty(nl.sara.webdav.Ace.prototype, 'grantdeny', { 233 'set': function(value) { 234 if ((value !== nl.sara.webdav.Ace.GRANT) && (value !== nl.sara.webdav.Ace.DENY)) { 235 throw new nl.sara.webdav.Exception('grantdeny must be either nl.sara.webdav.Ace.GRANT or nl.sara.webdav.Ace.DENY', nl.sara.webdav.Exception.WRONG_VALUE); 236 } 237 this._grantdeny = value; 238 }, 239 'get': function() { 240 return this._grantdeny; 241 } 242 }); 243 244 Object.defineProperty(nl.sara.webdav.Ace.prototype, 'inherited', { 245 'set': function(value) { 246 if (Boolean(value)) { 247 this._inherited = String(value); 248 }else{ 249 this._inherited = false; 250 } 251 }, 252 'get': function() { 253 return this._inherited; 254 } 255 }); 256 257 //########################## DEFINE PUBLIC METHODS ############################# 258 /** 259 * Adds a WebDAV privilege 260 * 261 * @param {nl.sara.webdav.Privilege} privilege The privilege to add 262 * @returns {nl.sara.webdav.Ace} The ace itself for chaining methods 263 */ 264 nl.sara.webdav.Ace.prototype.addPrivilege = function(privilege) { 265 if (!nl.sara.webdav.Ie.isIE && !(privilege instanceof nl.sara.webdav.Privilege)) { 266 throw new nl.sara.webdav.Exception('Privilege should be instance of Privilege', nl.sara.webdav.Exception.WRONG_TYPE); 267 } 268 var namespace = privilege.namespace; 269 if (namespace) { 270 if (this._namespaces[namespace] === undefined) { 271 this._namespaces[namespace] = {}; 272 } 273 }else{ 274 throw new nl.sara.webdav.Exception('Privilege should have a namespace', nl.sara.webdav.Exception.WRONG_TYPE); 275 } 276 277 this._namespaces[namespace][privilege.tagname] = privilege; 278 return this; 279 }; 280 281 /** 282 * Gets a WebDAV privilege 283 * 284 * @param {String} namespace The namespace of the privilege 285 * @param {String} privilege The privilege to get 286 * @returns {nl.sara.webdav.Privilege} The value of the privilege or undefined if the privilege doesn't exist 287 */ 288 nl.sara.webdav.Ace.prototype.getPrivilege = function(namespace, privilege) { 289 if ((this._namespaces[namespace] === undefined) || (this._namespaces[namespace][privilege] === undefined)) { 290 return undefined; 291 } 292 return this._namespaces[namespace][privilege]; 293 }; 294 295 /** 296 * Gets the namespace names 297 * 298 * @returns {String[]} The names of the different namespaces 299 */ 300 nl.sara.webdav.Ace.prototype.getNamespaceNames = function() { 301 return Object.keys(this._namespaces); 302 }; 303 304 /** 305 * Gets the privilege names of a namespace 306 * 307 * @param {String} namespace The namespace of the privilege 308 * @returns {String[]} The names of the different privilege of a namespace 309 */ 310 nl.sara.webdav.Ace.prototype.getPrivilegeNames = function(namespace) { 311 if (this._namespaces[namespace] === undefined) { 312 return new Array(); 313 } 314 return Object.keys(this._namespaces[namespace]); 315 }; 316 317 // End of library 318