From 26ab723052db199e442eccd10e752dd5a039c6f0 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Tue, 19 Jan 2010 11:33:37 +0000 Subject: [PATCH] Merged V3.2E to HEAD 17460: Refactored calendar views into separate objects 17466: Remote API part of fix for ETHREEOH-3268. - Added simple webscript to return details of the authentication system, such as account creation allowed. 17473: ETHREEOH-3268 - UI part of fix. - Add External Users is now disabled in Share if Alfresco instance does not support creating new users i.e. if LDAP or similar is used. 17479: ETHREEOH-2409 - Doc Library Details page displays incomplete action list; usability issue 17480: My Tasks dashlet - prevent display of fake date used for sorting 17484: Fixed ETHREEOH-2305 "It's impossible to implement a Search request with empty search field in Site Members area." - Default settings can be applied in web-framework-config-application.xml: 1 100 and later be overriden in the properties section for each searchable components binding file. - The components that override the min-search-term-length default value and set it to "0" are: site-finder, site-members & site-groups 17485: Merged DEV_TEMPORARY TO V3.2 17468: Problem rendering field description (MultilingualTextAreaGenerator) for app:folderlink 17486: Merged DEV_TEMPORARY to V3.2 (record-only) 17487: Partial fix for ETHREEOH-3308 (xf:switch cannot be used in repeating field type), fixes 'extra' set of fields seen when using a maxOccurs of more than 1 17489: MERGED DEV/TEMPORARY to V3.2 ETHREEOH-3068 - WCM Create Web Content Wizard 17492: Fix for ETHREEOH-2598 documents uploaded via Share interface are not incremented as versions with CIFS/SMB interface. - Auto versioning of documents now correctly handled via CIFS edit if an appropriate rule is applied to a doclib git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18123 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/authentication.get.desc.xml | 8 + .../repository/authentication.get.json.ftl | 6 + .../repository/comments/comment.get.js | 1 + .../repository/comments/comment.get.json.ftl | 2 +- .../repository/comments/comment.lib.ftl | 13 +- .../repository/comments/comment.put.json.ftl | 2 +- .../repository/comments/comment.put.json.js | 1 + .../repository/comments/comments.get.json.ftl | 8 +- .../comments/comments.post.json.ftl | 2 +- .../repository/comments/comments.post.json.js | 1 + .../alfresco/repository/upload/upload.post.js | 13 +- .../documentlibrary/action-sets.lib.js | 31 --- .../action/checkout.post.json.js | 8 +- .../slingshot/documentlibrary/doclist.get.js | 185 +++++++----------- .../documentlibrary/doclist.get.json.ftl | 42 ++-- .../documentlibrary/evaluator.lib.js | 173 ++++++++++++++++ .../slingshot/documentlibrary/filters.lib.js | 41 ++-- .../web-scripts-application-context.xml | 5 + .../repo/web/scripts/bean/Authentication.java | 63 ++++++ 19 files changed, 400 insertions(+), 205 deletions(-) create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.json.ftl delete mode 100644 config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action-sets.lib.js create mode 100644 config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js create mode 100644 source/java/org/alfresco/repo/web/scripts/bean/Authentication.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.desc.xml new file mode 100644 index 0000000000..23df05ef5c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.desc.xml @@ -0,0 +1,8 @@ + + Authentication + Authentication stack information + /api/authentication + + none + none + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.json.ftl new file mode 100644 index 0000000000..e698f1ed00 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/authentication.get.json.ftl @@ -0,0 +1,6 @@ +{ + "data": + { + "creationAllowed": ${creationAllowed?string} + } +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.js index df489c551d..0218f785a6 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.js @@ -11,6 +11,7 @@ function main() } model.item = getCommentData(node); + model.node = node; } main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.json.ftl index 12f6ea4350..59cdc5358d 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.get.json.ftl @@ -1,4 +1,4 @@ <#import "comment.lib.ftl" as commentLib/> { - "item" : <@commentLib.commentJSON item=item /> + "item": <@commentLib.commentJSON item=item parent=node /> } \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.lib.ftl index 3813e2818e..75b58d3504 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.lib.ftl @@ -3,9 +3,9 @@ <#escape x as jsonUtils.encodeJSONString(x)> "${fieldName}": { - <#if person.assocs["cm:avatar"]??> + <#if person.assocs["cm:avatar"]??> "avatarRef": "${person.assocs["cm:avatar"][0].nodeRef?string}", - + "username": "${person.properties["cm:userName"]}", "firstName": "${person.properties["cm:firstName"]}", "lastName": "${person.properties["cm:lastName"]}" @@ -16,13 +16,13 @@ <#-- This template renders a comment. --> -<#macro commentJSON item> +<#macro commentJSON item parent> <#escape x as jsonUtils.encodeJSONString(x)> { "url": "api/comment/node/${item.node.nodeRef?replace('://','/')}", "nodeRef": "${item.node.nodeRef}", "name": "${item.node.properties.name!''}", - "title": "${item.node.properties.title!''}", + "title": "${item.node.properties.title!''}", "content": "${stringUtils.stripUnsafeHTML(item.node.content)}", <#if item.author??> <@renderPerson person=item.author fieldName="author" /> @@ -37,8 +37,13 @@ "isUpdated": ${item.isUpdated?string}, "permissions": { + <#if parent?? && (parent.isLocked || parent.hasAspect("cm:workingcopy"))> + "edit": false, + "delete": false + <#else> "edit": ${item.node.hasPermission("Write")?string}, "delete": ${item.node.hasPermission("Delete")?string} + } } diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.ftl index 5ff6db311c..c957e54a53 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.ftl @@ -1,4 +1,4 @@ <#import "comment.lib.ftl" as commentLib/> { - "item" : <@commentLib.commentJSON item=item /> + "item": <@commentLib.commentJSON item=item parent=node /> } diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.js index 0ba127cbf7..cce8aa7e2a 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comment.put.json.js @@ -32,6 +32,7 @@ function main() // update comment updateComment(node); model.item = getCommentData(node); + model.node = node; // post an activity item, but only if we got a site if (json.has("site") && json.has("itemTitle") && json.has("page")) diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.get.json.ftl index f534cf2bc7..ec993bea1b 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.get.json.ftl @@ -1,9 +1,9 @@ -<#import "comment.lib.ftl" as commentLib/> -<#import "../generic-paged-results.lib.ftl" as gen/> +<#import "comment.lib.ftl" as commentLib> +<#import "../generic-paged-results.lib.ftl" as gen> { "nodePermissions": { - <#if node.isLocked> + <#if node.isLocked || node.hasAspect("cm:workingcopy")> "create": false, "edit": false, "delete": false @@ -14,6 +14,6 @@ }, <@gen.pagedResults data=data ; item> - <@commentLib.commentJSON item=item /> + <@commentLib.commentJSON item=item parent=node /> } \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.ftl index 5ff6db311c..c957e54a53 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.ftl @@ -1,4 +1,4 @@ <#import "comment.lib.ftl" as commentLib/> { - "item" : <@commentLib.commentJSON item=item /> + "item": <@commentLib.commentJSON item=item parent=node /> } diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js index 8b6f2f0d11..913d5dfcbb 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/comments/comments.post.json.js @@ -42,6 +42,7 @@ function main() var comment = addComment(node); model.item = getCommentData(comment); + model.node = node; // post an activitiy item, but only if we got a site if (json.has("site") && json.has("itemTitle") && json.has("page")) diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js index 7af33ffd45..e9c4248fd8 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js @@ -142,10 +142,9 @@ function main() // Ensure the original file is versionable - may have been uploaded via different route if (!workingCopy.hasAspect("cm:versionable")) { - // Ensure the file is versionable - but do not autoversion or create initial version yet - var props = new Array(2); - props["cm:autoVersion"] = false; - props["cm:initialVersion"] = false; + // Ensure the file is versionable + var props = new Array(1); + props["cm:autoVersionOnUpdateProps"] = false; workingCopy.addAspect("cm:versionable", props); } @@ -241,12 +240,6 @@ function main() newFile.properties.content.encoding = "UTF-8"; newFile.save(); - // Ensure the file is versionable - but do not autoversion or create initial version - var props = new Array(2); - props["cm:autoVersion"] = false; - props["cm:initialVersion"] = false; - newFile.addAspect("cm:versionable", props); - // Additional aspects? if (aspects.length > 0) { diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action-sets.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action-sets.lib.js deleted file mode 100644 index 9ec5612547..0000000000 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action-sets.lib.js +++ /dev/null @@ -1,31 +0,0 @@ -function getActionSet(asset, obj) -{ - var actionSet = "empty", - assetType = obj.assetType, - isLink = obj.isLink, - itemStatus = obj.itemStatus, - isItemOwner = (obj.itemOwner && obj.itemOwner.properties.userName == person.properties.userName); - - if (isLink) - { - actionSet = "link"; - } - else if (asset.isContainer) - { - actionSet = "folder"; - } - else if (itemStatus.indexOf("workingCopy") != -1) - { - actionSet = isItemOwner ? "workingCopyOwner" : "locked"; - } - else if (itemStatus.indexOf("locked") != -1) - { - actionSet = isItemOwner ? "lockOwner" : "locked"; - } - else - { - actionSet = "document"; - } - - return actionSet; -} diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/checkout.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/checkout.post.json.js index c5670a362a..c20a300699 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/checkout.post.json.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/checkout.post.json.js @@ -29,13 +29,11 @@ function runAction(p_params) return; } - // Ensure the file is versionable - but do not autoversion or create initial version + // Ensure the file is versionable if (!assetNode.hasAspect("cm:versionable")) { - // Do not autoversion (we perform explicit checkout) - var props = new Array(2); - props["cm:autoVersion"] = false; - props["cm:initialVersion"] = false; + var props = new Array(1); + props["cm:autoVersionOnUpdateProps"] = false; assetNode.addAspect("cm:versionable", props); } diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js index 383848c0dd..d8d9d35bab 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.js @@ -1,4 +1,4 @@ - + @@ -22,6 +22,22 @@ function getPerson(username) return PeopleCache[username]; } +/** + * Gets a person's full name + * @method getPersonName + * @param username {string} User name + */ +function getPersonName(username) +{ + var user = getPerson(username); + if (user) + { + // Return trimmed full name + return (user.properties.firstName + " " + user.properties.lastName).replace(/^\s+|\s+$/g, ""); + } + return username; +} + /** * Gets / caches a site object * @method getSite @@ -97,17 +113,32 @@ function main() }), query = filterParams.query; - // Query and sort the list before trimming to page chunks below - allAssets = search.luceneSearch(query, filterParams.sortBy, filterParams.sortByAscending, filterParams.limitResults ? filterParams.limitResults : 0); + // Query the assets - passing in sort and result limit parameters + if (query !== "") + { + allAssets = search.query( + { + query: query, + language: filterParams.language, + page: + { + maxItems: (filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : 0) + }, + sort: filterParams.sort, + templates: filterParams.templates, + namespace: (filterParams.namespace ? filterParams.namespace : null) + }); + } // Ensure folders and folderlinks appear at the top of the list - folderAssets = []; - documentAssets = []; + var folderAssets = [], + documentAssets = []; + for each (asset in allAssets) { try { - if (asset.isContainer || asset.type == "{http://www.alfresco.org/model/application/1.0}folderlink") + if (asset.isContainer || asset.typeShort == "app:folderlink") { folderAssets.push(asset); } @@ -143,12 +174,11 @@ function main() startIndex = (pagePos - 1) * pageSize; assets = assets.slice(startIndex, pagePos * pageSize); - - var itemStatus, itemOwner, actionSet, thumbnail, createdBy, modifiedBy, activeWorkflows, assetType, linkAsset, isLink, - location, qnamePaths, displayPaths, locationAsset; + + var thumbnail, assetEvaluator, defaultLocation, location, qnamePaths, displayPaths, site, item; // Location if we're in a site - var defaultLocation = + defaultLocation = { site: parsedArgs.location.site, siteTitle: parsedArgs.location.siteTitle, @@ -156,88 +186,33 @@ function main() path: parsedArgs.location.path, file: null }; + + // Evaluate parent container + var parent = Evaluator.run(parsedArgs.parentNode); // User permissions and role var user = { - permissions: - { - create: parsedArgs.parentNode.hasPermission("CreateChildren"), - edit: parsedArgs.parentNode.hasPermission("Write"), - "delete": parsedArgs.parentNode.hasPermission("Delete") - } + permissions: parent.actionPermissions }; if (defaultLocation.site !== null) { user.role = parsedArgs.location.siteNode.getMembersRole(person.properties.userName); } - - // Locked/working copy status defines action set + + // Loop through and evaluate each asset in this result set for each (asset in assets) { - itemStatus = []; - itemOwner = null; - createdBy = null; - modifiedBy = null; - activeWorkflows = []; - linkAsset = null; - isLink = false; + // Get evaluated properties. + item = Evaluator.run(asset); + // Note: Only access item.asset after this point, as a link may have been resolved. + + item.isFavourite = (favourites[item.asset.nodeRef] === true); - // Asset status - if (asset.isLocked) - { - itemStatus.push("locked"); - itemOwner = getPerson(asset.properties["cm:lockOwner"]); - } - if (asset.hasAspect("cm:workingcopy")) - { - itemStatus.push("workingCopy"); - itemOwner = getPerson(asset.properties["cm:workingCopyOwner"]); - } - // Is this user the item owner? - if (itemOwner && (itemOwner.properties.userName == person.properties.userName)) - { - itemStatus.push("lockedBySelf"); - } - - // Get users - createdBy = getPerson(asset.properties["cm:creator"]); - modifiedBy = getPerson(asset.properties["cm:modifier"]); - - // Asset type - if (asset.isContainer) - { - assetType = "folder"; - } - else if (asset.type == "{http://www.alfresco.org/model/application/1.0}folderlink") - { - assetType = "folder"; - isLink = true; - } - else if (asset.type == "{http://www.alfresco.org/model/application/1.0}filelink") - { - assetType = "document"; - isLink = true; - } - else - { - assetType = "document"; - } - - if (isLink) - { - /** - * NOTE: After this point, the "asset" object will be changed to a link's destination node - * if the original node was a filelink type - */ - linkAsset = asset; - asset = linkAsset.properties.destination; - } - // Does this collection of assets have potentially differering paths? - if (filterParams.variablePath || isLink) + if (filterParams.variablePath || item.isLink) { - locationAsset = (isLink && assetType == "document") ? linkAsset : asset; + locationAsset = (item.isLink && item.type == "document") ? item.linkAsset : item.asset; qnamePaths = locationAsset.qnamePath.split("/"); displayPaths = locationAsset.displayPath.split("/"); @@ -252,7 +227,8 @@ function main() path: "/" + displayPaths.slice(5, displayPaths.length).join("/"), file: locationAsset.name }; - var site = getSite(location.site); + + site = getSite(location.site); if (site != null) { location.siteTitle = site.title; @@ -281,51 +257,30 @@ function main() file: asset.name }; } - - // Make sure we have a thumbnail + + // Resolved location + item.location = location; + + // Make sure we have a thumbnail. if (haveThumbnails) { - thumbnail = asset.getThumbnail(THUMBNAIL_NAME); + thumbnail = item.asset.getThumbnail(THUMBNAIL_NAME); if (thumbnail === null) { // No thumbnail, so queue creation - asset.createThumbnail(THUMBNAIL_NAME, true); + item.asset.createThumbnail(THUMBNAIL_NAME, true); } } - // Get relevant actions set - actionSet = getActionSet(asset, - { - assetType: assetType, - isLink: isLink, - itemStatus: itemStatus, - itemOwner: itemOwner - }); - - // Part of an active workflow? - for each (activeWorkflow in asset.activeWorkflows) - { - activeWorkflows.push(activeWorkflow.id); - } - - items.push( - { - asset: asset, - linkAsset: linkAsset, - type: assetType, - isLink: isLink, - status: itemStatus, - owner: itemOwner, - createdBy: createdBy, - modifiedBy: modifiedBy, - actionSet: actionSet, - tags: asset.tags, - activeWorkflows: activeWorkflows, - location: location, - isFavourite: (favourites[asset.nodeRef] === true) - }); + items.push(item); } + var parentMeta = filterParams.variablePath ? null : + { + nodeRef: String(parsedArgs.parentNode.nodeRef), + type: parent.typeShort + }; + return ( { luceneQuery: query, @@ -342,7 +297,7 @@ function main() }, user: user, items: items, - parent: filterParams.variablePath ? null : parsedArgs.parentNode + parent: parentMeta }); } diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl index d340d496c0..c5b9654b6d 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/doclist.get.json.ftl @@ -11,15 +11,19 @@ { "parent": { - <#if doclist.parent??>"nodeRef": "${doclist.parent.nodeRef}", + <#if doclist.parent??> + "nodeRef": "${doclist.parent.nodeRef}", + "permissions": { "userRole": "${user.role!""}", "userAccess": { - "create" : ${user.permissions.create?string}, - "edit" : ${user.permissions.edit?string}, - "delete" : ${user.permissions.delete?string} + <#list user.permissions?keys as perm> + <#if user.permissions[perm]?is_boolean> + "${perm?string}": ${user.permissions[perm]?string}<#if perm_has_next>, + + } } }, @@ -36,12 +40,6 @@ <#assign d = item.asset> <#assign version = "1.0"> <#if d.hasAspect("cm:versionable") && d.versionHistory?size != 0><#assign version = d.versionHistory[0].versionLabel> - <#if item.owner??> - <#assign lockedBy = (item.owner.properties.firstName + " " + item.owner.properties.lastName)?trim> - <#assign lockedByUser = item.owner.properties.userName> - <#else> - <#assign lockedBy="" lockedByUser=""> - <#if item.createdBy??> <#assign createdBy = (item.createdBy.properties.firstName + " " + item.createdBy.properties.lastName)?trim> <#assign createdByUser = item.createdBy.properties.userName> @@ -54,6 +52,12 @@ <#else> <#assign modifiedBy="" modifiedByUser=""> + <#if item.lockedBy??> + <#assign lockedBy = (item.lockedBy.properties.firstName + " " + item.lockedBy.properties.lastName)?trim> + <#assign lockedByUser = item.lockedBy.properties.userName> + <#else> + <#assign lockedBy="" lockedByUser=""> + <#assign tags><#list item.tags as tag>"${tag}"<#if tag_has_next>, { "index": ${item_index}, @@ -64,9 +68,7 @@ "mimetype": "${d.mimetype!""}", "fileName": "<#if item.isLink>${item.linkAsset.name}<#else>${d.name}", "displayName": "${d.name?replace(workingCopyLabel, "")}", - "status": "<#list item.status as s>${s}<#if s_has_next>,", - "lockedBy": "${lockedBy}", - "lockedByUser": "${lockedByUser}", + "status": "<#list item.status?keys as s><#if item.status[s]?is_boolean && item.status[s] == true>${s}<#if s_has_next>,", "title": "${d.properties.title!""}", "description": "${d.properties.description!""}", "author": "${d.properties.author!""}", @@ -76,6 +78,8 @@ "modifiedOn": "<@dateFormat d.properties.modified />", "modifiedBy": "${modifiedBy}", "modifiedByUser": "${modifiedByUser}", + "lockedBy": "${lockedBy}", + "lockedByUser": "${lockedByUser}", "size": "${d.size?c}", "version": "${version}", "contentUrl": "api/node/content/${d.storeType}/${d.storeId}/${d.id}/${d.name?url}", @@ -102,12 +106,14 @@ ], "userAccess": { - "create": ${d.hasPermission("CreateChildren")?string}, - "edit": ${d.hasPermission("Write")?string}, - "delete": ${d.hasPermission("Delete")?string}, - "permissions": ${d.hasPermission("ChangePermissions")?string} + <#list item.actionPermissions?keys as actionPerm> + <#if item.actionPermissions[actionPerm]?is_boolean> + "${actionPerm?string}": ${item.actionPermissions[actionPerm]?string}<#if actionPerm_has_next>, + + } - } + }, + "custom": <#noescape>${item.custom} }<#if item_has_next>, ] diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js new file mode 100644 index 0000000000..ae7707c56e --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js @@ -0,0 +1,173 @@ +var Evaluator = +{ + /** + * Asset Type evaluator + */ + getAssetType: function Evaluator_getAssetType(asset) + { + var assetType = ""; + if (asset.isContainer) + { + assetType = "folder"; + } + else if (asset.typeShort == "app:folderlink") + { + assetType = "folderlink"; + } + else if (asset.typeShort == "app:filelink") + { + assetType = "filelink"; + } + else + { + assetType = "document"; + } + return assetType; + }, + + /** + * Asset Evaluator - main entrypoint + */ + run: function Evaluator_run(asset) + { + var assetType = Evaluator.getAssetType(asset), + actions = {}, + actionSet = "empty", + permissions = {}, + status = {}, + custom = {}, + activeWorkflows = [], + createdBy = getPerson(asset.properties["cm:creator"]), + modifiedBy = getPerson(asset.properties["cm:modifier"]), + isLink = false, + linkAsset = null, + lockedBy = null, + lockOwnerUser = ""; + + /** + * COMMON TO ALL + */ + permissions = + { + "create": asset.hasPermission("CreateChildren"), + "edit": asset.hasPermission("Write"), + "delete": asset.hasPermission("Delete"), + "permissions": asset.hasPermission("ChangePermissions"), + "cancel-checkout": asset.hasPermission("CancelCheckOut") + }; + + // Get relevant actions set + switch (assetType) + { + /** + * SPECIFIC TO: LINK + */ + case "folderlink": + case "filelink": + actionSet = "link"; + isLink = true; + /** + * NOTE: After this point, the "asset" object will be changed to a link's destination node + * if the original node was a filelink type. + */ + linkAsset = asset; + asset = linkAsset.properties.destination; + // Re-evaluate the assetType based on the link's destination node + assetType = Evaluator.getAssetType(asset); + break; + + /** + * SPECIFIC TO: FOLDER + */ + case "folder": + actionSet = "folder"; + break; + + /** + * SPECIFIC TO: DOCUMENTS + */ + case "document": + actionSet = "document"; + + // Working Copy? + if (asset.hasAspect("cm:workingcopy")) + { + lockedBy = getPerson(asset.properties["cm:workingCopyOwner"]); + lockOwnerUser = lockedBy.properties.userName; + if (lockOwnerUser == person.properties.userName) + { + status["editing"] = true; + actionSet = "workingCopyOwner"; + } + else + { + status["locked " + getPersonName(lockOwnerUser) + "|" + lockedBy.properties.userName] = true; + actionSet = "locked"; + } + var wcNode = asset.properties["source"]; + custom["isWorkingCopy"] = true; + custom["workingCopyOriginal"] = wcNode.nodeRef; + if (wcNode.hasAspect("cm:versionable") && wcNode.versionHistory.length > 0) + { + custom["workingCopyVersion"] = wcNode.versionHistory[0].label; + } + permissions["view-original"] = true; + } + // Locked? + else if (asset.isLocked) + { + lockedBy = getPerson(asset.properties["cm:lockOwner"]); + lockOwnerUser = lockedBy.properties.userName; + if (lockOwnerUser == person.properties.userName) + { + status["lock-owner"] = true; + actionSet = "lockOwner"; + } + else + { + status["locked " + getPersonName(lockOwnerUser) + "|" + lockedBy.properties.userName] = true; + actionSet = "locked"; + } + var srcNodes = search.query( + { + query: "+@cm\\:source:\"" + asset.nodeRef + "\" +ISNOTNULL:cm\\:workingCopyOwner", + language: "lucene", + page: + { + maxItems: 1 + } + }); + if (srcNodes.length == 1) + { + custom["hasWorkingCopy"] = true; + custom["workingCopyNode"] = srcNodes[0].nodeRef; + permissions["view-working-copy"] = true; + } + } + break; + } + + // Part of an active workflow? + for each (activeWorkflow in asset.activeWorkflows) + { + activeWorkflows.push(activeWorkflow.id); + } + + return( + { + asset: asset, + type: assetType, + linkAsset: linkAsset, + isLink: isLink, + status: status, + actionSet: actionSet, + actionPermissions: permissions, + createdBy: createdBy, + modifiedBy: modifiedBy, + lockedBy: lockedBy, + tags: asset.tags, + activeWorkflows: activeWorkflows, + custom: jsonUtils.toJSONString(custom), + }); + } +}; diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/filters.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/filters.lib.js index 8b6d58587d..c21c5d6276 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/filters.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/filters.lib.js @@ -13,8 +13,13 @@ var Filters = { query: "+PATH:\"" + parsedArgs.parentNode.qnamePath + "/*\"", limitResults: null, - sortBy: "@{http://www.alfresco.org/model/content/1.0}name", - sortByAscending: true, + sort: [ + { + column: "@{http://www.alfresco.org/model/content/1.0}name", + ascending: true + }], + language: "lucene", + templates: null, variablePath: false }; @@ -34,20 +39,20 @@ var Filters = } // Create query based on passed-in arguments - var filterId = String(filter), - filterData = String(args.filterData), + var filterData = String(args.filterData), filterQuery = ""; // Common types and aspects to filter from the UI - filterQueryDefaults = " -ASPECT:\"{http://www.alfresco.org/model/content/1.0}workingcopy\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/content/1.0}thumbnail\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/content/1.0}systemfolder\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}forums\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}forum\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}topic\""; - filterQueryDefaults += " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\""; + filterQueryDefaults = + " -TYPE:\"{http://www.alfresco.org/model/content/1.0}thumbnail\"" + + " -TYPE:\"{http://www.alfresco.org/model/content/1.0}systemfolder\"" + + " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}forums\"" + + " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}forum\"" + + " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}topic\"" + + " -TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" + + " -@cm\\:lockType:READ_ONLY_LOCK"; - switch (filterId) + switch (String(filter)) { case "all": filterQuery = "+PATH:\"" + parsedArgs.rootNode.qnamePath + "//*\""; @@ -96,8 +101,11 @@ var Filters = } filterQuery += " -TYPE:\"{http://www.alfresco.org/model/content/1.0}folder\""; - filterParams.sortBy = "@{http://www.alfresco.org/model/content/1.0}" + dateField; - filterParams.sortByAscending = false; + filterParams.sort = [ + { + column: "@{http://www.alfresco.org/model/content/1.0}" + dateField, + ascending: false + }]; filterParams.variablePath = true; filterParams.query = filterQuery + filterQueryDefaults; break; @@ -152,7 +160,10 @@ var Filters = } // Specialise by passed-in type - filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || ""); + if (filterParams.query !== "") + { + filterParams.query += " " + (Filters.TYPE_MAP[parsedArgs.type] || ""); + } return filterParams; } diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 7cbd27d7a3..82aa18ba3f 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -395,6 +395,11 @@ + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/bean/Authentication.java b/source/java/org/alfresco/repo/web/scripts/bean/Authentication.java new file mode 100644 index 0000000000..29796b922a --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/bean/Authentication.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.repo.web.scripts.bean; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.web.scripts.DeclarativeWebScript; +import org.alfresco.web.scripts.Status; +import org.alfresco.web.scripts.WebScriptRequest; + +/** + * WebScript java backed bean implementation - to return information about the + * authentication system, such as account mutability. + * + * @author Kevin Roast + */ +public class Authentication extends DeclarativeWebScript +{ + private MutableAuthenticationService authenticationService; + + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = (MutableAuthenticationService)authenticationService; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.DeclarativeWebScript#executeImpl(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse) + */ + @Override + protected Map executeImpl(WebScriptRequest req, Status status) + { + Map model = new HashMap(2); + + model.put("creationAllowed", this.authenticationService.isAuthenticationCreationAllowed()); + + return model; + } +} \ No newline at end of file