1 /** 2 * @fileOverview 3 * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>) 4 * @license Copyright (c) 2012-2019 LabKey Corporation 5 * <p/> 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * <p/> 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * <p/> 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * <p/> 18 */ 19 20 /** 21 * @namespace LabKey Security Reporting and Helper class. 22 * This class provides several static methods and data members for 23 * calling the security-related APIs, and interpreting the results. 24 * <p>Additional Documentation: 25 * <ul> 26 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=security">LabKey Security and Accounts</a></li> 27 * </ul> 28 * </p> 29 */ 30 LABKEY.Security = new function() 31 { 32 /*-- public methods --*/ 33 /** @scope LABKEY.Security */ 34 return { 35 36 /** 37 * A map of the various permission bits supported in the LabKey Server. 38 * You can use these values with the hasPermission() method to test if 39 * a user or group has a particular permission. The values in this map 40 * are as follows: 41 * <ul> 42 * <li>read</li> 43 * <li>insert</li> 44 * <li>update</li> 45 * <li>del</li> 46 * <li>readOwn</li> 47 * <li>updateOwn</li> 48 * <li>deleteOwn</li> 49 * <li>all</li> 50 * </ul> 51 * For example, to refer to the update permission, the syntax would be:<br/> 52 * <pre><code>LABKEY.Security.permissions.update</code></pre> 53 */ 54 permissions : { 55 read: 1, 56 insert: 2, 57 update: 4, 58 del: 8, 59 readOwn: 16, 60 updateOwn: 64, 61 deleteOwn: 128, 62 admin: 32768, 63 all: 65535 64 }, 65 66 /** 67 * A map of commonly used effective permissions supported in the LabKey Server. 68 * You can use these values with the hasEffectivePermission() method to test if 69 * a user or group has a particular permission. The values in this map 70 * are as follows: 71 * <ul> 72 * <li>read</li> 73 * <li>insert</li> 74 * <li>update</li> 75 * <li>del</li> 76 * <li>readOwn</li> 77 * </ul> 78 * For example, to refer to the update permission, the syntax would be:<br/> 79 * <pre><code>LABKEY.Security.effectivePermissions.update</code></pre> 80 */ 81 effectivePermissions : { 82 insert: "org.labkey.api.security.permissions.InsertPermission", 83 read: "org.labkey.api.security.permissions.ReadPermission", 84 admin: "org.labkey.api.security.permissions.AdminPermission", 85 del: "org.labkey.api.security.permissions.DeletePermission", 86 readOwn: "org.labkey.api.security.permissions.ReadSomePermission", 87 update: "org.labkey.api.security.permissions.UpdatePermission" 88 }, 89 90 /** 91 * A map of the various permission roles exposed in the user interface. 92 * The members are as follows: 93 * <ul> 94 * <li>admin</li> 95 * <li>editor</li> 96 * <li>author</li> 97 * <li>reader</li> 98 * <li>restrictedReader</li> 99 * <li>noPerms</li> 100 * </ul> 101 * For example, to refer to the author role, the syntax would be:<br/> 102 * <pre><code>LABKEY.Security.roles.author</code></pre> 103 */ 104 roles : { 105 admin: 65535, 106 editor: 15, 107 author: 195, 108 reader: 1, 109 restrictedReader: 16, 110 submitter: 2, 111 noPerms: 0 112 }, 113 114 /** 115 * A map of the special system group ids. These ids are assigned by the system 116 * at initial startup and are constant across installations. The values in 117 * this map are as follows: 118 * <ul> 119 * <li>administrators</li> 120 * <li>users</li> 121 * <li>guests</li> 122 * <li>developers</li> 123 * </ul> 124 * For example, to refer to the administrators group, the syntax would be:<br/> 125 * <pre><code>LABKEY.Security.systemGroups.administrators</code></pre> 126 */ 127 systemGroups : { 128 administrators: -1, 129 users: -2, 130 guests: -3, 131 developers: -4 132 }, 133 134 /** 135 * Get the effective permissions for all groups within the container, optionally 136 * recursing down the container hierarchy. 137 * @param config A configuration object with the following properties: 138 * @param {function} config.success A reference to a function to call with the API results. This 139 * function will be passed the following parameters: 140 * <ul> 141 * <li><b>groupPermsInfo:</b> an object containing properties about the container and group permissions. 142 * This object will have the following shape: 143 * <ul> 144 * <li>container 145 * <ul> 146 * <li>id: the container id</li> 147 * <li>name: the container name</li> 148 * <li>path: the container path</li> 149 * <li>isInheritingPerms: true if the container is inheriting permissions from its parent</li> 150 * <li>groups: an array of group objects, each of which will have the following properties: 151 * <ul> 152 * <li>id: the group id</li> 153 * <li>name: the group's name</li> 154 * <li>type: the group's type ('g' for group, 'r' for role, 'm' for module-specific)</li> 155 * <li>roleLabel: (DEPRECATED) a description of the group's permission role. This will correspond 156 * to the visible labels shown on the permissions page (e.g., 'Admin (all permissions)'.</li> 157 * <li>role: (DEPRECATED) the group's role value (e.g., 'ADMIN'). Use this property for programmatic checks.</li> 158 * <li>permissions: (DEPRECATED) The group's effective permissions as a bit mask. 159 * Use this with the hasPermission() method to test for specific permissions.</li> 160 * <li>roles: An array of role unique names that this group is playing in the container. This replaces the 161 * existing roleLabel, role and permissions properties. Groups may now play multiple roles in a container 162 * and each role grants the user a set of permissions. Use the getRoles() method to retrieve information 163 * about the roles, including which permissions are granted by each role. 164 * </li> 165 * <li>effectivePermissions: An array of effective permission unique names the group has.</li> 166 * </ul> 167 * </li> 168 * <li>children: if includeSubfolders was true, this will contain an array of objects, each of 169 * which will have the same shape as the parent container object.</li> 170 * </ul> 171 * </li> 172 * </ul> 173 * </li> 174 * <li><b>response:</b> The XMLHttpResponse object</li> 175 * </ul> 176 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 177 * function will be passed the following parameters: 178 * <ul> 179 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 180 * <li><b>response:</b> The XMLHttpResponse object</li> 181 * </ul> 182 * @param {boolean} [config.includeSubfolders] Set to true to recurse down the subfolders (defaults to false) 183 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 184 * the current container path will be used. 185 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 186 * @returns {Mixed} In client-side scripts, this method will return a transaction id 187 * for the async request that can be used to cancel the request 188 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 189 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 190 */ 191 getGroupPermissions : function(config) 192 { 193 var params = {}; 194 if (config.includeSubfolders != undefined) 195 params.includeSubfolders = config.includeSubfolders; 196 197 return LABKEY.Ajax.request({ 198 url: LABKEY.ActionURL.buildURL("security", "getGroupPerms", config.containerPath), 199 method : 'GET', 200 params: params, 201 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 202 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 203 }); 204 }, 205 206 /** 207 * Returns true if the permission passed in 'perm' is on in the permissions 208 * set passed as 'perms'. This is a local function and does not make a call to the server. 209 * @param {int} perms The permission set, typically retrieved for a given user or group. 210 * @param {int} perm A specific permission bit to check for. 211 */ 212 hasPermission : function(perms, perm) 213 { 214 return perms & perm; 215 }, 216 217 /** 218 * Returns true if the permission passed in 'desiredPermission' is in the permissions 219 * array passed as 'effectivePermissions'. This is a local function and does not make a call to the server. 220 * @param {Array} effectivePermissions The permission set, typically retrieved for a given user or group. 221 * @param {String} desiredPermission A specific permission bit to check for. 222 * @returns {boolean} 223 */ 224 hasEffectivePermission : function(effectivePermissions, desiredPermission) 225 { 226 for (var i = 0; i < effectivePermissions.length; i++) 227 { 228 if (effectivePermissions[i] == desiredPermission) 229 { 230 return true; 231 } 232 } 233 return false; 234 }, 235 236 /** 237 * Returns the name of the security role represented by the permissions passed as 'perms'. 238 * The return value will be the name of a property in the LABKEY.Security.roles map. 239 * This is a local function, and does not make a call to the server. 240 * @param {int} perms The permissions set 241 * @deprecated Do not use this anymore. Use the roles array in the various responses and the 242 * getRoles() method to obtain extra information about each role. 243 */ 244 getRole : function(perms) 245 { 246 for (var role in LABKEY.Security.roles) 247 { 248 if (LABKEY.Security.roles.hasOwnProperty(role)) 249 { 250 if (perms == LABKEY.Security.roles[role]) 251 { 252 return role; 253 } 254 } 255 } 256 }, 257 258 /** 259 * Returns information about the container paths visible to the current user 260 * @param config A configuration object containing the following properties 261 * @param {boolean} [config.includeSubfolders] If set to true, the entire branch of containers will be returned. 262 * If false, only the immediate children of the starting container will be returned (defaults to false). 263 * @param {int} [config.depth] May be used to control the depth of recursion if includeSubfolders is set to true. 264 * @param {Mixed} [config.container] A container id or full-path String or an Array of container id/full-path 265 * Strings (only the first will be used). If not present, the current container is used. 266 * @param {Function} config.success A reference to a function to call with the API results. This 267 * function will be passed an array of container paths as strings 268 */ 269 getReadableContainers : function(config) 270 { 271 var params = {}; 272 config = config || {}; 273 if (undefined !== config.container) 274 { 275 if (LABKEY.Utils.isArray(config.container)) 276 { 277 if (config.container.length > 0) 278 { 279 config.container = [config.container[0]]; 280 } 281 else 282 { 283 delete config.container; 284 } 285 } 286 else 287 { 288 config.container = [ config.container ]; 289 } 290 params.container = config.container; 291 } 292 if (undefined !== config.includeSubfolders) 293 params.includeSubfolders = config.includeSubfolders; 294 if (undefined !== config.depth) 295 params.depth = config.depth; 296 297 return LABKEY.Ajax.request({ 298 url: LABKEY.ActionURL.buildURL("project", "getReadableContainers", config.containerPath), 299 method : 'GET', 300 params: params, 301 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope, false, function(o) { return o.containers; }), 302 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 303 }); 304 }, 305 306 /** 307 * Returns information about a user's permissions within a container. If you don't specify a user id, this 308 * will return information about the current user. 309 * @param config A configuration object containing the following properties 310 * @param {int} config.userId The id of the user. Omit to get the current user's information 311 * @param {string} config.userEmail The email address (user name) of the user (specify only userId or userEmail, not both) 312 * @param {Function} config.success A reference to a function to call with the API results. This 313 * function will be passed the following parameters: 314 * <ul> 315 * <li><b>userPermsInfo:</b> an object containing properties about the user's permissions. 316 * This object will have the following shape: 317 * <ul> 318 * <li>container: information about the container and the groups the user belongs to in that container 319 * <ul> 320 * <li>id: the container id</li> 321 * <li>name: the container name</li> 322 * <li>path: the container path</li> 323 * <li>roleLabel: (DEPRECATED) a description of the user's permission role in this container. This will correspond 324 * to the visible labels shown on the permissions page (e.g., 'Admin (all permissions)'.</li> 325 * <li>role: (DEPRECATED) the user's role value (e.g., 'ADMIN'). Use this property for programmatic checks.</li> 326 * <li>permissions: (DEPRECATED) The user's effective permissions in this container as a bit mask. 327 * Use this with the hasPermission() method to test for specific permissions.</li> 328 * <li>roles: An array of role unique names that this user is playing in the container. This replaces the 329 * existing roleLabel, role and permissions properties. Users may now play multiple roles in a container 330 * and each role grants the user a set of permissions. Use the getRoles() method to retrieve information 331 * about the roles, including which permissions are granted by each role. 332 * </li> 333 * <li>effectivePermissions: An array of effective permission unique names the user has.</li> 334 * <li>groups: an array of group objects to which the user belongs, each of which will have the following properties: 335 * <ul> 336 * <li>id: the group id</li> 337 * <li>name: the group's name</li> 338 * <li>roleLabel: (DEPRECATED) a description of the group's permission role. This will correspond 339 * to the visible labels shown on the permissions page (e.g., 'Admin (all permissions)'.</li> 340 * <li>role: (DEPRECATED) the group's role value (e.g., 'ADMIN'). Use this property for programmatic checks.</li> 341 * <li>permissions: (DEPRECATED) The group's effective permissions as a bit mask. 342 * Use this with the hasPermission() method to test for specific permissions.</li> 343 * <li>roles: An array of role unique names that this group is playing in the container. This replaces the 344 * existing roleLabel, role and permissions properties. Groups may now play multiple roles in a container 345 * and each role grants the user a set of permissions. Use the getRoles() method to retrieve information 346 * about the roles, including which permissions are granted by each role. 347 * </li> 348 * <li>effectivePermissions: An array of effective permission unique names the group has.</li> 349 * </ul> 350 * </li> 351 * <li>children: if includeSubfolders was true, this will contain an array of objects, each of 352 * which will have the same shape as the parent container object.</li> 353 * </ul> 354 * </li> 355 * <li>user: information about the requested user 356 * <ul> 357 * <li>userId: the user's id</li> 358 * <li>displayName: the user's display name</li> 359 * </ul> 360 * </li> 361 * </ul> 362 * </li> 363 * <li><b>response:</b> The XMLHttpResponse object</li> 364 * </ul> 365 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 366 * function will be passed the following parameters: 367 * <ul> 368 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 369 * <li><b>response:</b> The XMLHttpResponse object</li> 370 * </ul> 371 * @param {boolean} [config.includeSubfolders] Set to true to recurse down the subfolders (defaults to false) 372 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 373 * the current container path will be used. 374 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 375 * @returns {Mixed} In client-side scripts, this method will return a transaction id 376 * for the async request that can be used to cancel the request 377 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 378 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 379 */ 380 getUserPermissions : function(config) 381 { 382 var params = {}; 383 384 if(config.userId != undefined) 385 params.userId = config.userId; 386 else if(config.userEmail != undefined) 387 params.userEmail = config.userEmail; 388 389 if(config.includeSubfolders != undefined) 390 params.includeSubfolders = config.includeSubfolders; 391 392 return LABKEY.Ajax.request({ 393 url: LABKEY.ActionURL.buildURL("security", "getUserPerms", config.containerPath), 394 method : 'GET', 395 params: params, 396 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 397 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 398 }); 399 }, 400 401 /** 402 * Returns a list of users given selection criteria. This may be called by any logged-in user. 403 * @param config A configuration object containing the following properties 404 * @param {int} [config.groupId] The id of a project group for which you want the members. 405 * @param {string} [config.group] The name of a project group for which you want the members (specify groupId or group, not both). 406 * @param {string} [config.name] The first part of the user name, useful for user name completion. If specified, 407 * only users whose email address or display name starts with the value supplied will be returned. 408 * @param {boolean} [config.allMembers] This value is used to fetch all members in subgroups. 409 * @param {boolean} [config.active] This value is used to filter members based on activity (defaults to false). 410 * @param {Mixed} [config.permissions] A permissions string or an Array of permissions strings. 411 * If not present, no permission filtering occurs. If multiple permissions, all permissions are required. 412 * @param {function} config.success A reference to a function to call with the API results. This 413 * function will be passed the following parameters: 414 * <ul> 415 * <li><b>usersInfo:</b> an object with the following shape: 416 * <ul> 417 * <li>users: an array of user objects in the following form: 418 * <ul> 419 * <li>userId: the user's id</li> 420 * <li>displayName: the user's display name</li> 421 * <li>email: the user's email address</li> 422 * </ul> 423 * </li> 424 * <li>container: the path of the requested container</li> 425 * </ul> 426 * </li> 427 * <li><b>response:</b> The XMLHttpResponse object</li> 428 * </ul> 429 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 430 * function will be passed the following parameters: 431 * <ul> 432 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 433 * <li><b>response:</b> The XMLHttpResponse object</li> 434 * </ul> 435 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 436 * the current container path will be used. 437 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 438 * @returns {Mixed} In client-side scripts, this method will return a transaction id 439 * for the async request that can be used to cancel the request 440 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 441 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 442 */ 443 getUsers : function(config) 444 { 445 var params = {}; 446 if(undefined != config.groupId) 447 params.groupId = config.groupId; 448 else if(undefined != config.group) 449 params.group = config.group; 450 451 if(undefined != config.name) 452 params.name = config.name; 453 454 if(undefined != config.allMembers) 455 params.allMembers = config.allMembers; 456 457 if (undefined != config.active) 458 params.active = config.active; 459 460 if (undefined != config.permissions) 461 { 462 if (!LABKEY.Utils.isArray(config.permissions)) 463 { 464 config.permissions = [ config.permissions ]; 465 } 466 params.permissions = config.permissions; 467 } 468 469 return LABKEY.Ajax.request({ 470 url: LABKEY.ActionURL.buildURL("user", "getUsers.api", config.containerPath), 471 method : 'GET', 472 params: params, 473 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 474 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 475 }); 476 }, 477 478 /** 479 * Creates a new container, which may be a project, folder, or workbook. 480 * @param config A configuration object with the following properties 481 * @param {String} [config.name] Required for projects or folders. The name of the container. 482 * @param {String} [config.title] The title of the container, used primarily for workbooks. 483 * @param {String} [config.description] The description of the container, used primarily for workbooks. 484 * @param {boolean} [config.isWorkbook] Whether this a workbook should be created. Defaults to false. 485 * @param {String} [config.folderType] The name of the folder type to be applied. 486 * @param {function} [config.success] A reference to a function to call with the API results. This 487 * function will be passed the following parameters: 488 * <ul> 489 * <li><b>containersInfo:</b> an object with the following properties: 490 * <ul> 491 * <li>id: the id of the requested container</li> 492 * <li>name: the name of the requested container</li> 493 * <li>path: the path of the requested container</li> 494 * <li>sortOrder: the relative sort order of the requested container</li> 495 * <li>description: an optional description for the container (may be null or missing)</li> 496 * <li>title: an optional non-unique title for the container (may be null or missing)</li> 497 * <li>isWorkbook: true if this container is a workbook. Workbooks do not appear in the left-hand project tree.</li> 498 * <li>effectivePermissions: An array of effective permission unique names the group has.</li> 499 * </ul> 500 * </li> 501 * <li><b>response:</b> The XMLHttpResponse object</li> 502 * </ul> 503 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 504 * function will be passed the following parameters: 505 * <ul> 506 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 507 * <li><b>response:</b> The XMLHttpResponse object</li> 508 * </ul> 509 * @param {string} [config.containerPath] An alternate container in which to create a new container. If not specified, 510 * the current container path will be used. 511 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 512 * @returns {Mixed} In client-side scripts, this method will return a transaction id 513 * for the async request that can be used to cancel the request 514 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 515 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 516 */ 517 createContainer : function(config) 518 { 519 var params = {}; 520 params.name = config.name; 521 params.title = config.title; 522 params.description = config.description; 523 params.isWorkbook = config.isWorkbook; 524 params.folderType = config.folderType; 525 526 return LABKEY.Ajax.request({ 527 url: LABKEY.ActionURL.buildURL("core", "createContainer", config.containerPath), 528 method : 'POST', 529 jsonData : params, 530 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 531 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 532 }); 533 }, 534 535 /** 536 * Deletes an existing container, which may be a project, folder, or workbook. 537 * @param config A configuration object with the following properties 538 * @param {function} [config.success] A reference to a function to call with the API results. This 539 * function will be passed the following parameter: 540 * <ul> 541 * <li><b>object:</b> Empty JavaScript object</li> 542 * <li><b>response:</b> The XMLHttpResponse object</li> 543 * </ul> 544 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 545 * function will be passed the following parameters: 546 * <ul> 547 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 548 * <li><b>response:</b> The XMLHttpResponse object</li> 549 * </ul> 550 * @param {string} [config.containerPath] The container which should be deleted. If not specified, 551 * the current container path will be deleted. 552 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 553 * @returns {Mixed} In client-side scripts, this method will return a transaction id 554 * for the async request that can be used to cancel the request 555 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 556 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 557 */ 558 deleteContainer : function(config) 559 { 560 return LABKEY.Ajax.request({ 561 url: LABKEY.ActionURL.buildURL("core", "deleteContainer", config.containerPath), 562 method : 'POST', 563 jsonData : {}, 564 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 565 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 566 }); 567 }, 568 569 /** 570 * Moves an existing container, which may be a folder or workbook to be the subfolder of another folder and/or project. 571 * @param config A configuration object with the following properties 572 * @param {string} config.containerPath The current container path of the container that is going to be moved. Additionally, the container 573 * entity id is also valid. 574 * @param {string} config.destinationParent The container path of destination parent. Additionally, the destination parent entity id 575 * is also valid. 576 * @param {boolean} [config.addAlias] Add alias of current container path to container that is being moved (defaults to True). 577 * @param {function} [config.success] A reference to a function to call with the API results. This function will 578 * be passed the following parameters: 579 * <ul> 580 * <li><b>object:</b> Empty JavaScript object</li> 581 * <li><b>response:</b> The XMLHttpResponse object</li> 582 * </ul> 583 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 584 * function will be passed the following parameters: 585 * <ul> 586 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 587 * <li><b>response:</b> The XMLHttpResponse object</li> 588 * </ul> 589 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 590 */ 591 moveContainer : function(config) { 592 593 var params = {}; 594 params.container = config.container || config.containerPath; 595 params.parent = config.destinationParent || config.parent || config.parentPath; 596 params.addAlias = true; 597 598 if (!params.container) { 599 console.error("'containerPath' must be specified for LABKEY.Security.moveContainer invocation."); 600 return; 601 } 602 603 if (!params.parent) { 604 console.error("'parent' must be specified for LABKEY.Security.moveContainer invocation."); 605 return; 606 } 607 608 if (config.addAlias === false) { 609 params.addAlias = false; 610 } 611 612 return LABKEY.Ajax.request({ 613 url : LABKEY.ActionURL.buildURL("core", "moveContainer", params.container), 614 method : 'POST', 615 jsonData : params, 616 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 617 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 618 }); 619 }, 620 621 /** 622 * Retrieves the full set of folder types that are available on the server. 623 * @param config A configuration object with the following properties 624 * @param {function} config.success A reference to a function to call with the API results. This 625 * function will be passed the following parameter: 626 * <ul> 627 * <li><b>folderTypes:</b> Map from folder type name to folder type object, which consists of the following properties: 628 * <ul> 629 * <li><b>name:</b> the cross-version stable name of the folder type</li> 630 * <li><b>description:</b> a short description of the folder type</li> 631 * <li><b>label:</b> the name that's shown to the user for this folder type</li> 632 * <li><b>defaultModule:</b> name of the module that provides the home screen for this folder type</li> 633 * <li><b>activeModules:</b> an array of module names that are automatically active for this folder type</li> 634 * <li><b>workbookType:</b> boolean that indicates if this is specifically intended to use as a workbook type 635 * <li><b>requiredWebParts:</b> an array of web parts that are part of this folder type and cannot be removed 636 * <ul> 637 * <li><b>name:</b> the name of the web part</li> 638 * <li><b>properties:</b> a map of properties that are automatically set</li> 639 * </ul> 640 * </li> 641 * <li><b>preferredWebParts:</b> an array of web parts that are part of this folder type but may be removed. Same structure as requiredWebParts</li> 642 * </ul> 643 * </li> 644 * <li><b>response:</b> The XMLHttpResponse object</li> 645 * </ul> 646 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 647 * function will be passed the following parameters: 648 * <ul> 649 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 650 * <li><b>response:</b> The XMLHttpResponse object</li> 651 * </ul> 652 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 653 * @returns {Mixed} In client-side scripts, this method will return a transaction id 654 * for the async request that can be used to cancel the request 655 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 656 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 657 */ 658 getFolderTypes : function(config) 659 { 660 return LABKEY.Ajax.request({ 661 url: LABKEY.ActionURL.buildURL("core", "getFolderTypes", config.containerPath), 662 method : 'POST', 663 jsonData : {}, 664 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 665 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 666 }); 667 }, 668 669 670 /** 671 * Retrieves the full set of modules that are installed on the server. 672 * @param config A configuration object with the following properties 673 * @param {function} config.success A reference to a function to call with the API results. This 674 * function will be passed the following parameter: 675 * <ul> 676 * <li><b>folderType:</b> the folderType, based on the container used when calling this API</li> 677 * <li><b>modules:</b> Array of all modules present on this site, each of which consists of the following properties: 678 * <ul> 679 * <li><b>name:</b> the name of the module</li> 680 * <li><b>required:</b> whether this module is required in the folder type specified above</li> 681 * <li><b>tabName:</b> name of the tab associated with this module</li> 682 * <li><b>active:</b> whether this module should be active for this container</li> 683 * <li><b>enabled:</b> whether this module should be enabled by default for this container</li> 684 * </ul> 685 * </li> 686 * <li><b>response:</b> The XMLHttpResponse object</li> 687 * </ul> 688 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 689 * function will be passed the following parameters: 690 * <ul> 691 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 692 * <li><b>response:</b> The XMLHttpResponse object</li> 693 * </ul> 694 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 695 * @returns {Mixed} In client-side scripts, this method will return a transaction id 696 * for the async request that can be used to cancel the request 697 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 698 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 699 */ 700 getModules : function(config) 701 { 702 return LABKEY.Ajax.request({ 703 url: LABKEY.ActionURL.buildURL("admin", "getModules", config.containerPath), 704 method : 'POST', 705 jsonData : {}, 706 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 707 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 708 }); 709 }, 710 711 712 /** 713 * Returns information about the specified container, including the user's current permissions within 714 * that container. If the includeSubfolders config option is set to true, it will also return information 715 * about all descendants the user is allowed to see. 716 * @param config A configuration object with the following properties 717 * @param {Mixed} [config.container] A container id or full-path String or an Array of container id/full-path Strings. If not present, the current container is used. 718 * @param {boolean} [config.includeSubfolders] If set to true, the entire branch of containers will be returned. 719 * If false, only the immediate children of the starting container will be returned (defaults to false). 720 * @param {boolean} [config.includeEffectivePermissions] If set to false, the effective permissions for this container resource 721 * will not be included. (defaults to true) 722 * @param {int} [config.depth] May be used to control the depth of recursion if includeSubfolders is set to true. 723 * @param {Array} [config.moduleProperties] The names (Strings) of modules whose Module Property values should be included for each container. 724 * Use "*" to get the value of all Module Properties for all modules. 725 * @param {function} config.success A reference to a function to call with the API results. This 726 * function will be passed the following parameters: 727 * <ul> 728 * <li><b>containersInfo:</b> 729 * If <code>config.container</code> is an Array, an object with property 730 * <code>containers</code> and value Array of 'container info' is returned. 731 * If <code>config.container</code> is a String, a object of 'container info' is returned. 732 * <br> 733 * The 'container info' properties are as follows: 734 * <ul> 735 * <li>id: the id of the requested container</li> 736 * <li>name: the name of the requested container</li> 737 * <li>path: the path of the requested container</li> 738 * <li>sortOrder: the relative sort order of the requested container</li> 739 * <li>activeModules: an assay of the names (strings) of active modules in the container</li> 740 * <li>folderType: the name (string) of the folder type, matched with getFolderTypes()</li> 741 * <li>description: an optional description for the container (may be null or missing)</li> 742 * <li>title: an optional non-unique title for the container (may be null or missing)</li> 743 * <li>isWorkbook: true if this container is a workbook. Workbooks do not appear in the left-hand project tree.</li> 744 * <li>isContainerTab: true if this container is a Container Tab. Container Tabs do not appear in the left-hand project tree.</li> 745 * <li>userPermissions: (DEPRECATED) the permissions the current user has in the requested container. 746 * Use this value with the hasPermission() method to test for specific permissions.</li> 747 * <li>effectivePermissions: An array of effective permission unique names the group has.</li> 748 * <li>children: if the includeSubfolders parameter was true, this will contain 749 * an array of child container objects with the same shape as the parent object.</li> 750 * <li>moduleProperties: if requested in the config object, an array of module properties for each included module: 751 * <ul> 752 * <li>name: the name of the Module Property.</li> 753 * <li>moduleName: the name of the module specifying this property.</li> 754 * <li>effectiveValue: the value of the property, including a value potentially inherited from parent containers.</li> 755 * <li>value: the value of the property as set for this specific container</li> 756 * </ul> 757 * </li> 758 * </ul> 759 * </li> 760 * <li><b>response:</b> The XMLHttpResponse object</li> 761 * </ul> 762 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 763 * function will be passed the following parameters: 764 * <ul> 765 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 766 * <li><b>response:</b> The XMLHttpResponse object</li> 767 * </ul> 768 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 769 * the current container path will be used. 770 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 771 * @returns {Mixed} In client-side scripts, this method will return a transaction id 772 * for the async request that can be used to cancel the request 773 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 774 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 775 */ 776 getContainers : function(config) 777 { 778 var params = {}; 779 config = config || {}; 780 if (undefined != config.container) 781 { 782 if (LABKEY.Utils.isArray(config.container)) 783 { 784 params.multipleContainers = true; 785 } 786 else 787 { 788 config.container = [ config.container ]; 789 } 790 params.container = config.container; 791 } 792 if (undefined != config.includeSubfolders) 793 params.includeSubfolders = config.includeSubfolders; 794 if (undefined != config.depth) 795 params.depth = config.depth; 796 if (undefined != config.moduleProperties) 797 params.moduleProperties = config.moduleProperties; 798 if (undefined != config.includeEffectivePermissions) 799 params.includeEffectivePermissions = config.includeEffectivePermissions; 800 801 return LABKEY.Ajax.request({ 802 url: LABKEY.ActionURL.buildURL("project", "getContainers", config.containerPath), 803 method : 'GET', 804 params: params, 805 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 806 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 807 }); 808 }, 809 810 /** 811 * Exposes limited information about the current user. This property returns a JavaScript object 812 * with the following properties: 813 * <ul> 814 * <li>id: the user's unique id number</li> 815 * <li>displayName: the user's display name</li> 816 * <li>email: the user's email address</li> 817 * <li>canInsert: set to true if this user can insert data in the current folder</li> 818 * <li>canUpdate: set to true if this user can update data in the current folder</li> 819 * <li>canUpdateOwn: set to true if this user can update data this user created in the current folder</li> 820 * <li>canDelete: set to true if this user can delete data in the current folder</li> 821 * <li>canDeleteOwn: set to true if this user can delete data this user created in the current folder</li> 822 * <li>isAdmin: set to true if this user has admin permissions in the current folder</li> 823 * <li>isGuest: set to true if this user is the guest (anonymous) user</li> 824 * <li>isSystemAdmin: set to true if this user is a system administrator</li> 825 * <li>isDeveloper: set to true if this user is a developer</li> 826 * <li>isSignedIn: set to true if this user is signed in</li> 827 * </ul> 828 */ 829 currentUser : LABKEY.user, 830 831 /** 832 * Exposes limited information about the current container. This property returns a JavaScript object 833 * with the following properties: 834 * <ul> 835 * <li>id: the container's unique id (entityid)</li> 836 * <li>name: the name of the container</li> 837 * <li>path: the path of the current container</li> 838 * <li>type: the type of container, either project, folder or workbook</li> 839 * </ul> 840 */ 841 currentContainer : LABKEY.container, 842 843 /** 844 * Returns the set of groups the current user belongs to in the current container or specified containerPath. 845 * This may be called by any user. 846 * @param {object} config A configuration object with the following properties: 847 * @param {function} config.success A reference to a function that will be called with the results. 848 * This function will receive the follwing parameters: 849 * <ul> 850 * <li>results: an object with the following properties: 851 * <ul> 852 * <li>groups: An array of group information objects, each of which has the following properties: 853 * <ul> 854 * <li>id: The unique id of the group.</li> 855 * <li>name: The name of the group.</li> 856 * <li>isProjectGroup: true if this group is defined at the project level.</li> 857 * <li>isSystemGroup: true if this group is defined at the system level.</li> 858 * </ul> 859 * </li> 860 * </ul> 861 * </li> 862 * </ul> 863 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 864 * function will be passed the following parameters: 865 * <ul> 866 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 867 * <li><b>response:</b> The XMLHttpResponse object</li> 868 * </ul> 869 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 870 * the current container path will be used. 871 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 872 * @returns {Mixed} In client-side scripts, this method will return a transaction id 873 * for the async request that can be used to cancel the request 874 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 875 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 876 */ 877 getGroupsForCurrentUser : function(config) 878 { 879 return LABKEY.Ajax.request({ 880 url: LABKEY.ActionURL.buildURL("security", "getGroupsForCurrentUser", config.containerPath), 881 method: 'GET', 882 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 883 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 884 }); 885 }, 886 887 /** 888 * Ensures that the current user is logged in. 889 * @param {object} config A configuration object with the following properties: 890 * @param {boolean} [config.useSiteLoginPage] Set to true to redirect the browser to the normal site login page. 891 * After the user logs in, the browser will be redirected back to the current page, and the current user information 892 * will be available via {@link LABKEY.Security.currentUser}. If omitted or set to false, this function 893 * will attempt to login via an AJAX request, which will cause the browser to display the basic authentication 894 * dialog. After the user logs in successfully, the config.success function will be called. 895 * @param {function} config.success A reference to a function that will be called after a successful login. 896 * It is passed the following parameters: 897 * <ul> 898 * <li>results: an object with the following properties: 899 * <ul> 900 * <li>currentUser: a reference to the current user. See {@link LABKEY.Security.currentUser} for more details.</li> 901 * </ul> 902 * </li> 903 * </ul> 904 * Note that if the current user is already logged in, the successCallback function will be called immediately, 905 * passing the current user information from {@link LABKEY.Security.currentUser}. 906 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 907 * function will be passed the following parameters: 908 * <ul> 909 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 910 * <li><b>response:</b> The XMLHttpResponse object</li> 911 * </ul> 912 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 913 * @param {boolean} [config.force] Set to true to force a login even if the user is already logged in. 914 * This is useful for keeping a session alive during a long-lived page. To do so, call this function 915 * with config.force set to true, and config.useSiteLoginPage to false (or omit). 916 * @returns {Mixed} In client-side scripts, this method will return a transaction id 917 * for the async request that can be used to cancel the request 918 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 919 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 920 */ 921 ensureLogin : function(config) 922 { 923 if (LABKEY.Security.currentUser.isGuest || config.force) 924 { 925 if (config.useSiteLoginPage) 926 { 927 window.location = LABKEY.ActionURL.buildURL("login", "login") + "?returnUrl=" + window.location; 928 } 929 else 930 { 931 return LABKEY.Ajax.request({ 932 url: LABKEY.ActionURL.buildURL("security", "ensureLogin"), 933 method: 'GET', 934 success: LABKEY.Utils.getCallbackWrapper(function(data, req){ 935 if(data.currentUser) 936 LABKEY.Security.currentUser = data.currentUser; 937 938 if(LABKEY.Utils.getOnSuccess(config)) 939 LABKEY.Utils.getOnSuccess(config).call(config.scope || this, data, req); 940 941 }, this), 942 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 943 }); 944 } 945 } 946 else 947 { 948 LABKEY.Utils.getOnSuccess(config).call(config.scope || this, {currentUser: LABKEY.Security.currentUser}); 949 } 950 }, 951 952 /** 953 * Returns the tree of securable resources from the current container downward 954 * @param config A configuration object with the following properties: 955 * @param {Boolean} config.includeSubfolders If set to true, the response will include subfolders 956 * and their contained securable resources (defaults to false). 957 * @param {Boolean} config.includeEffectivePermissions If set to true, the response will include the 958 * list of effective permissions (unique names) the current user has to each resource (defaults to false). 959 * These permissions are calcualted based on the current user's group memberships and role assignments, and 960 * represent the actual permissions the user has to these resources at the time of the API call. 961 * @param {Function} config.success A reference to a function to call with the API results. This 962 * function will be passed the following parameters: 963 * <ul> 964 * <li><b>data:</b> an object with a property named "resources" which contains the root resource. 965 * Each resource has the following properties: 966 * <ul> 967 * <li>id: The unique id of the resource (String, typically a GUID).</li> 968 * <li>name: The name of the resource suitable for showing to a user.</li> 969 * <li>description: The description of the reosurce.</li> 970 * <li>resourceClass: The fully-qualified Java class name of the resource.</li> 971 * <li>sourceModule: The name of the module in which the resource is defined and managed</li> 972 * <li>parentId: The parent resource's id (may be omitted if no parent)</li> 973 * <li>parentContainerPath: The parent resource's container path (may be omitted if no parent)</li> 974 * <li>children: An array of child resource objects.</li> 975 * <li>effectivePermissions: An array of permission unique names the current user has on the resource. This will be 976 * present only if the includeEffectivePermissions property was set to true on the config object.</li> 977 * </ul> 978 * </li> 979 * <li><b>response:</b> The XMLHttpResponse object</li> 980 * </ul> 981 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 982 * function will be passed the following parameters: 983 * <ul> 984 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 985 * <li><b>response:</b> The XMLHttpResponse object</li> 986 * </ul> 987 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 988 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 989 * the current container path will be used. 990 * @returns {Mixed} In client-side scripts, this method will return a transaction id 991 * for the async request that can be used to cancel the request 992 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 993 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 994 */ 995 getSecurableResources : function(config) 996 { 997 var params = {}; 998 if(undefined != config.includeSubfolders) 999 params.includeSubfolders = config.includeSubfolders; 1000 if(undefined != config.includeEffectivePermissions) 1001 params.includeEffectivePermissions = config.includeEffectivePermissions; 1002 1003 return LABKEY.Ajax.request({ 1004 url: LABKEY.ActionURL.buildURL("security", "getSecurableResources", config.containerPath), 1005 method: "GET", 1006 params: params, 1007 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1008 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 1009 }); 1010 }, 1011 1012 /* 1013 * EXPERIMENTAL! gets permissions for a set of tables within a schema. 1014 * Currently only study tables have individual permissions so only works on the study schema 1015 * @param config A configuration object with the following properties: 1016 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 1017 * @param {object} [config.schemaName] Name of the schema to retrieve information on. 1018 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1019 * the current container path will be used. 1020 * @param {Function} config.success A reference to a function to call with the API results. This 1021 * function will be passed the following parameters: 1022 * <ul> 1023 * <li><b>data:</b> an object with a property named "schemas" which contains a queries object. 1024 * The queries object property with the name of each table/queries. So 1025 * schemas.study.queries.Demographics would yield the following results 1026 * <ul> 1027 * <li>id: The unique id of the resource (String, typically a GUID).</li> 1028 * <li>name: The name of the resource suitable for showing to a user.</li> 1029 * <li>description: The description of the reosurce.</li> 1030 * <li>resourceClass: The fully-qualified Java class name of the resource.</li> 1031 * <li>sourceModule: The name of the module in which the resource is defined and managed</li> 1032 * <li>parentId: The parent resource's id (may be omitted if no parent)</li> 1033 * <li>parentContainerPath: The parent resource's container path (may be omitted if no parent)</li> 1034 * <li>children: An array of child resource objects.</li> 1035 * <li>effectivePermissions: An array of permission unique names the current user has on the resource. This will be 1036 * present only if the includeEffectivePermissions property was set to true on the config object.</li> 1037 * <li>permissionMap: An object with one property per effectivePermission allowed the user. This restates 1038 * effectivePermissions in a slightly more convenient way 1039 * </ul> 1040 * </li> 1041 * <li><b>response:</b> The XMLHttpResponse object</li> 1042 * </ul> 1043 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1044 * function will be passed the following parameters: 1045 * <ul> 1046 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1047 * <li><b>response:</b> The XMLHttpResponse object</li> 1048 * </ul> 1049 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1050 * for the async request that can be used to cancel the request 1051 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1052 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1053 */ 1054 getSchemaPermissions: function(config) { 1055 if (config.schemaName && config.schemaName != "study") 1056 throw "Method only works for the study schema"; 1057 1058 var successCallback = function(json, response) { 1059 1060 //First lets make sure there is a study in here. 1061 var studyResource = null; 1062 for (var i = 0; i < json.resources.children.length; i++) 1063 { 1064 var resource = json.resources.children[i]; 1065 if (resource.resourceClass == "org.labkey.study.model.StudyImpl"){ 1066 studyResource = resource; 1067 break; 1068 } 1069 } 1070 1071 if (null == studyResource) 1072 { 1073 config.failure.apply(config.scope || this, [{description:"No study found in container."}, response]); 1074 return; 1075 } 1076 1077 var result = {queries:{}}, dataset; 1078 1079 for (i=0; i < studyResource.children.length; i++) { 1080 dataset = studyResource.children[i]; 1081 result.queries[dataset.name] = dataset; 1082 dataset.permissionMap = {}; 1083 for (var j=0; j < dataset.effectivePermissions.length; j++) { 1084 dataset.permissionMap[dataset.effectivePermissions[j]] = true; 1085 } 1086 } 1087 1088 config.success.apply(config.scope || this, [{schemas:{study:result}}, response]); 1089 }; 1090 1091 var myConfig = {}; 1092 if (config) { 1093 for (var c in config) { 1094 if (config.hasOwnProperty(c)) { 1095 myConfig[c] = config[c]; 1096 } 1097 } 1098 } 1099 myConfig.includeEffectivePermissions = true; 1100 myConfig.success = successCallback; 1101 return LABKEY.Security.getSecurableResources(myConfig); 1102 }, 1103 1104 /** 1105 * Returns the complete set of roles defined on the server, along with the permissions each role grants. 1106 * @param config A configuration object with the following properties: 1107 * @param {Function} config.success A reference to a function to call with the API results. This 1108 * function will be passed the following parameters: 1109 * <ul> 1110 * <li><b>roles:</b> An array of role objects, each of which has the following properties: 1111 * <ul> 1112 * <li>uniqueName: The unique name of the resource (String, typically a fully-qualified class name).</li> 1113 * <li>name: The name of the role suitable for showing to a user.</li> 1114 * <li>description: The description of the role.</li> 1115 * <li>sourceModule: The name of the module in which the role is defined.</li> 1116 * <li>permissions: An array of permissions the role grants. Each permission has the following properties: 1117 * <ul> 1118 * <li>uniqueName: The unique name of the permission (String, typically a fully-qualified class name).</li> 1119 * <li>name: The name of the permission.</li> 1120 * <li>description: A description of the permission.</li> 1121 * <li>sourceModule: The module in which the permission is defined.</li> 1122 * </ul> 1123 * </li> 1124 * </ul> 1125 * </li> 1126 * <li><b>response:</b> The XMLHttpResponse object</li> 1127 * </ul> 1128 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1129 * function will be passed the following parameters: 1130 * <ul> 1131 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1132 * <li><b>response:</b> The XMLHttpResponse object</li> 1133 * </ul> 1134 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 1135 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1136 * for the async request that can be used to cancel the request 1137 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1138 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1139 */ 1140 getRoles : function(config) 1141 { 1142 return LABKEY.Ajax.request({ 1143 url: LABKEY.ActionURL.buildURL("security", "getRoles"), 1144 method: "GET", 1145 success: LABKEY.Utils.getCallbackWrapper(function(data, req){ 1146 1147 //roles and perms are returned in two separate blocks for efficiency 1148 var idx; 1149 var permMap = {}; 1150 var perm; 1151 for(idx = 0; idx < data.permissions.length; ++idx) 1152 { 1153 perm = data.permissions[idx]; 1154 permMap[perm.uniqueName] = perm; 1155 } 1156 1157 var idxPerm; 1158 var role; 1159 for(idx = 0; idx < data.roles.length; ++idx) 1160 { 1161 role = data.roles[idx]; 1162 for(idxPerm = 0; idxPerm < role.permissions.length; ++idxPerm) 1163 { 1164 role.permissions[idxPerm] = permMap[role.permissions[idxPerm]]; 1165 } 1166 } 1167 1168 var fn = LABKEY.Utils.getOnSuccess(config); 1169 if (fn) 1170 fn.call(config.scope || this, data.roles, req); 1171 1172 }, this), 1173 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 1174 }); 1175 }, 1176 1177 /** 1178 * Retrieves the security policy for the requested resource id. Note that this will return the 1179 * policy in effect for this resource, which might be the policy from a parent resource if there 1180 * is no explicit policy set on the requested resource. Use the isInherited method on the returned 1181 * LABKEY.SecurityPolicy object to determine if the policy is inherited or not. 1182 * Note that the securable resource must be within the current container, or one of its descendants. 1183 * @param config A configuration object with the following properties 1184 * @param {String} config.resourceId The unique id of the securable resource. 1185 * @param {Function} config.success A reference to a function to call with the API results. This 1186 * function will be passed the following parameters: 1187 * <ul> 1188 * <li><b>policy:</b> an instance of a LABKEY.SecurityPolicy object.</li> 1189 * <li><b>relevantRoles:</b> an array of role ids that are relevant for the given resource.</li> 1190 * <li><b>response:</b> The XMLHttpResponse object</li> 1191 * </ul> 1192 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1193 * function will be passed the following parameters: 1194 * <ul> 1195 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1196 * <li><b>response:</b> The XMLHttpResponse object</li> 1197 * </ul> 1198 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 1199 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1200 * the current container path will be used. 1201 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1202 * for the async request that can be used to cancel the request 1203 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1204 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1205 */ 1206 getPolicy : function(config) 1207 { 1208 return LABKEY.Ajax.request({ 1209 url: LABKEY.ActionURL.buildURL("security", "getPolicy", config.containerPath), 1210 method: "GET", 1211 params: { resourceId: config.resourceId }, 1212 success: LABKEY.Utils.getCallbackWrapper(function(data, req){ 1213 data.policy.requestedResourceId = config.resourceId; 1214 LABKEY.Utils.getOnSuccess(config).call(config.scope || this, data.policy, data.relevantRoles, req); 1215 }, this), 1216 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 1217 }); 1218 }, 1219 1220 /** 1221 * Deletes the security policy for the requested resource id. This will cause resource to inherit its 1222 * security policy from its parent resource. 1223 * @param config A configuration object with the following properties 1224 * @param {String} config.resourceId The unique id of the securable resource. 1225 * @param {Function} config.success A reference to a function to call with the API results. This 1226 * function will be passed the following parameters: 1227 * <ul> 1228 * <li><b>data:</b> a simple object with one property called 'success' which will be set to true.</li> 1229 * <li><b>response:</b> The XMLHttpResponse object</li> 1230 * </ul> 1231 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1232 * function will be passed the following parameters: 1233 * <ul> 1234 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1235 * <li><b>response:</b> The XMLHttpResponse object</li> 1236 * </ul> 1237 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1238 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1239 * the current container path will be used. 1240 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1241 * for the async request that can be used to cancel the request 1242 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1243 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1244 */ 1245 deletePolicy : function(config) 1246 { 1247 return LABKEY.Ajax.request({ 1248 url: LABKEY.ActionURL.buildURL("security", "deletePolicy", config.containerPath), 1249 method: "POST", 1250 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1251 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1252 jsonData: { resourceId: config.resourceId }, 1253 headers : { 1254 'Content-Type' : 'application/json' 1255 } 1256 }); 1257 }, 1258 1259 /** 1260 * Saves the supplied security policy. This object should be a LABKEY.SecurityPolicy object. This 1261 * method will completely overwrite the existing policy for the resource. If another user has changed 1262 * the policy in between the time it was selected and this method is called, the save will fail with 1263 * an optimistic concurrency exception. To force your policy over the other, call the setModified() 1264 * method on the policy passing null. 1265 * @param config A configuration object with the following properties 1266 * @param {String} config.policy The LABKEY.SecurityPolicy object 1267 * @param {Function} config.success A reference to a function to call with the API results. This 1268 * function will be passed the following parameters: 1269 * <ul> 1270 * <li><b>data:</b> a simple object with one property called 'success' which will be set to true.</li> 1271 * <li><b>response:</b> The XMLHttpResponse object</li> 1272 * </ul> 1273 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1274 * function will be passed the following parameters: 1275 * <ul> 1276 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1277 * <li><b>response:</b> The XMLHttpResponse object</li> 1278 * </ul> 1279 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1280 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1281 * the current container path will be used. 1282 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1283 * for the async request that can be used to cancel the request 1284 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1285 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1286 */ 1287 savePolicy : function(config) 1288 { 1289 return LABKEY.Ajax.request({ 1290 url: LABKEY.ActionURL.buildURL("security", "savePolicy", config.containerPath), 1291 method : 'POST', 1292 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1293 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1294 jsonData : config.policy.policy, 1295 headers : { 1296 'Content-Type' : 'application/json' 1297 } 1298 }); 1299 }, 1300 1301 /** 1302 * Creates a new group. The new group will be created at the project level when the current 1303 * container is a folder or project, or will be created at the system level if the current 1304 * container is the root. 1305 * @param config A configuration object with the following properties: 1306 * @param {String} config.groupName The name of the group to create 1307 * @param {Function} config.success A reference to a function to call with the API results. This 1308 * function will be passed the following parameters: 1309 * <ul> 1310 * <li><b>data:</b> a simple object with two properties: id and name (the new group id and name respectively)</li> 1311 * <li><b>response:</b> The XMLHttpResponse object</li> 1312 * </ul> 1313 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1314 * function will be passed the following parameters: 1315 * <ul> 1316 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1317 * <li><b>response:</b> The XMLHttpResponse object</li> 1318 * </ul> 1319 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1320 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1321 * the current container path will be used. 1322 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1323 * for the async request that can be used to cancel the request 1324 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1325 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1326 */ 1327 createGroup : function(config) 1328 { 1329 var params = {name: config.groupName}; 1330 return LABKEY.Ajax.request({ 1331 url: LABKEY.ActionURL.buildURL("security", "createGroup", config.containerPath), 1332 method: "POST", 1333 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1334 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1335 jsonData: params, 1336 headers : { 1337 'Content-Type' : 'application/json' 1338 } 1339 }); 1340 }, 1341 1342 /** 1343 * Deletes a group. 1344 * @param config A configuration object with the following properties: 1345 * @param {int} config.groupId The id of the group to delete 1346 * @param {Function} config.success A reference to a function to call with the API results. This 1347 * function will be passed the following parameters: 1348 * <ul> 1349 * <li><b>data:</b> a simple object with a property named "deleted" that contains the deleted group id.</li> 1350 * <li><b>response:</b> The XMLHttpResponse object</li> 1351 * </ul> 1352 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1353 * function will be passed the following parameters: 1354 * <ul> 1355 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1356 * <li><b>response:</b> The XMLHttpResponse object</li> 1357 * </ul> 1358 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1359 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1360 * the current container path will be used. 1361 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1362 * for the async request that can be used to cancel the request 1363 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1364 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1365 */ 1366 deleteGroup : function(config) 1367 { 1368 var params = {id: config.groupId}; 1369 return LABKEY.Ajax.request({ 1370 url: LABKEY.ActionURL.buildURL("security", "deleteGroup", config.containerPath), 1371 method: "POST", 1372 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1373 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1374 jsonData: params, 1375 headers : { 1376 'Content-Type' : 'application/json' 1377 } 1378 }); 1379 }, 1380 1381 /** 1382 * Renames a group. 1383 * @param config A configuration object with the following properties: 1384 * @param {int} config.groupId The id of the group to delete 1385 * @param {String} config.newName The new name for the group 1386 * @param {Function} config.success A reference to a function to call with the API results. This 1387 * function will be passed the following parameters: 1388 * <ul> 1389 * <li><b>data:</b> a simple object with the following properties: 'renamed'=the group id; 'oldName'=the old name; 'newName'=the new name.</li> 1390 * <li><b>response:</b> The XMLHttpResponse object</li> 1391 * </ul> 1392 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1393 * function will be passed the following parameters: 1394 * <ul> 1395 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1396 * <li><b>response:</b> The XMLHttpResponse object</li> 1397 * </ul> 1398 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1399 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1400 * the current container path will be used. 1401 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1402 * for the async request that can be used to cancel the request 1403 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1404 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1405 */ 1406 renameGroup : function(config) { 1407 return LABKEY.Ajax.request({ 1408 url: LABKEY.ActionURL.buildURL("security", "renameGroup", config.containerPath), 1409 method: "POST", 1410 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1411 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1412 jsonData: { id: config.groupId, newName: config.newName }, 1413 headers : { 1414 'Content-Type' : 'application/json' 1415 } 1416 }); 1417 1418 }, 1419 1420 /** 1421 * Adds a new member to an existing group. 1422 * @param config A configuration object with the following properties: 1423 * @param {int} config.groupId The id of the group to which you want to add the member. 1424 * @param {int|int[]} config.principalIds An integer id or array of ids of the users or groups you want to add as members. 1425 * @param {Function} config.success A reference to a function to call with the API results. This 1426 * function will be passed the following parameters: 1427 * <ul> 1428 * <li><b>data:</b> a simple object with a property named "added" that contains the added principal id.</li> 1429 * <li><b>response:</b> The XMLHttpResponse object</li> 1430 * </ul> 1431 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1432 * function will be passed the following parameters: 1433 * <ul> 1434 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1435 * <li><b>response:</b> The XMLHttpResponse object</li> 1436 * </ul> 1437 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1438 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1439 * the current container path will be used. 1440 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1441 * for the async request that can be used to cancel the request 1442 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1443 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1444 */ 1445 addGroupMembers : function(config) 1446 { 1447 var params = { 1448 groupId: config.groupId, 1449 principalIds: (LABKEY.Utils.isArray(config.principalIds) ? config.principalIds : [config.principalIds]) 1450 }; 1451 return LABKEY.Ajax.request({ 1452 url: LABKEY.ActionURL.buildURL("security", "addGroupMember", config.containerPath), 1453 method: "POST", 1454 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1455 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1456 jsonData: params, 1457 headers : { 1458 'Content-Type' : 'application/json' 1459 } 1460 }); 1461 1462 }, 1463 1464 /** 1465 * Removes a member from an existing group. 1466 * @param config A configuration object with the following properties: 1467 * @param {int} config.groupId The id of the group from which you want to remove the member. 1468 * @param {int|int[]} config.principalIds An integer id or array of ids of the users or groups you want to remove. 1469 * @param {Function} config.success A reference to a function to call with the API results. This 1470 * function will be passed the following parameters: 1471 * <ul> 1472 * <li><b>data:</b> a simple object with a property named "removed" that contains the removed principal id.</li> 1473 * <li><b>response:</b> The XMLHttpResponse object</li> 1474 * </ul> 1475 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1476 * function will be passed the following parameters: 1477 * <ul> 1478 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1479 * <li><b>response:</b> The XMLHttpResponse object</li> 1480 * </ul> 1481 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1482 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1483 * the current container path will be used. 1484 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1485 * for the async request that can be used to cancel the request 1486 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1487 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1488 */ 1489 removeGroupMembers : function(config) 1490 { 1491 var params = { 1492 groupId: config.groupId, 1493 principalIds: (LABKEY.Utils.isArray(config.principalIds) ? config.principalIds : [config.principalIds]) 1494 }; 1495 return LABKEY.Ajax.request({ 1496 url: LABKEY.ActionURL.buildURL("security", "removeGroupMember", config.containerPath), 1497 method: "POST", 1498 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1499 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1500 jsonData: params, 1501 headers : { 1502 'Content-Type' : 'application/json' 1503 } 1504 }); 1505 }, 1506 1507 /** 1508 * Creates a new user account 1509 * @param config A configuration object with the following properties: 1510 * @param {String} config.email The new user's email address, or a semicolon separated list of email addresses. 1511 * @param {Boolean} config.sendEmail Set to false to stop the server from sending a welcome email to the user. 1512 * @param {String} config.optionalMessage An optional message to include in the new user registration email. 1513 * @param {Function} config.success A reference to a function to call with the API results. This 1514 * function will be passed the following parameters: 1515 * <ul> 1516 * <li><b>data:</b> a simple object, or array of objects, with three properties: userId, email, and message.</li> 1517 * <li><b>response:</b> The XMLHttpResponse object</li> 1518 * </ul> 1519 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 1520 * function will be passed the following parameters: 1521 * <ul> 1522 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 1523 * <li><b>response:</b> The XMLHttpResponse object</li> 1524 * </ul> 1525 * @param {Object} [config.scope] A scoping object for the success and error callback functions (default to this). 1526 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 1527 * the current container path will be used. 1528 * @returns {Mixed} In client-side scripts, this method will return a transaction id 1529 * for the async request that can be used to cancel the request 1530 * (see <a href="http://dev.sencha.com/deploy/dev/docs/?class=Ext.data.Connection&member=abort" target="_blank">Ext.data.Connection.abort</a>). 1531 * In server-side scripts, this method will return the JSON response object (first parameter of the success or failure callbacks.) 1532 */ 1533 createNewUser : function(config) 1534 { 1535 var params = { 1536 email: config.email, 1537 sendEmail: config.sendEmail, 1538 optionalMessage: config.optionalMessage 1539 }; 1540 return LABKEY.Ajax.request({ 1541 url: LABKEY.ActionURL.buildURL("security", "createNewUser", config.containerPath), 1542 method: "POST", 1543 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 1544 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 1545 jsonData: params, 1546 headers : { 1547 'Content-Type' : 'application/json' 1548 } 1549 }); 1550 }, 1551 1552 /** 1553 * Returns the name of the home container, which is automatically created when your server is set up. It is usually 'home' 1554 * @returns {string} The name of the home container automatically created on this server. 1555 */ 1556 getHomeContainer: function(){ 1557 return LABKEY.homeContainer; 1558 }, 1559 1560 /** 1561 * Returns the name of the shared container, which is automatically created when your server is setup. It is usually 'Shared' 1562 * @returns {string} The name of the shared container automatically created on this server. 1563 */ 1564 getSharedContainer: function(){ 1565 return LABKEY.sharedContainer; 1566 } 1567 }; 1568 }; 1569