diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.js index 012b81ef77..856d16ce6a 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.js @@ -13,6 +13,7 @@ function main() model.person = person; model.capabilities = people.getCapabilities(person); model.groups = groups ? people.getContainerGroups(person) : null; + model.immutability = groups ? people.getImmutableProperties(userName) : null; } else { diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.json.ftl index b9805d7f0e..471c655644 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.get.json.ftl @@ -1,6 +1,6 @@ <#import "person.lib.ftl" as personLib/> <#if groups??> - <@personLib.personGroupsJSON person=person groups=groups capabilities=capabilities /> + <@personLib.personGroupsJSON person=person groups=groups capabilities=capabilities immutability=immutability /> <#else> <@personLib.personCapJSON person=person capabilities=capabilities /> \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.lib.ftl index ada66e071e..e38fdc00ab 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/person/person.lib.ftl @@ -46,7 +46,7 @@ } -<#macro personGroupsJSON person groups capabilities> +<#macro personGroupsJSON person groups capabilities immutability> <#escape x as jsonUtils.encodeJSONString(x)> { <@personJSONinner person=person/>, @@ -61,7 +61,11 @@ { "itemName": "${authName}", "displayName": "${displayName}" - }<#if g_has_next>,] + }<#if g_has_next>,], + "immutability": + { + <@serializeHash hash=immutability/> + } } diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/version/version.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/version/version.get.js index 43646ce90a..da98e7582e 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/version/version.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/version/version.get.js @@ -10,16 +10,35 @@ function getPerson(username) if (typeof PeopleCache[username] == "undefined") { var person = people.getPerson(username); - if (person == null && (username == "System" || username.match("^System@") == "System@")) + if (person == null) { - person = + if (username == "System" || username.match("^System@") == "System@") { - properties: + // special case for the System users + person = { - userName: "System", - firstName: "System", - lastName: "User" - } + properties: + { + userName: "System", + firstName: "System", + lastName: "User" + }, + assocs: {} + }; + } + else + { + // missing person - may have been deleted from the database + person = + { + properties: + { + userName: username, + firstName: "", + lastName: "" + }, + assocs: {} + }; } } PeopleCache[username] = diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.desc.xml new file mode 100644 index 0000000000..875a281ef5 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.desc.xml @@ -0,0 +1,10 @@ + + Get the content of the specified asset within the specified web project and sandbox. + /api/wcm/webprojects/{webprojectref}/sandboxes/{sandboxref}/assets/content/{path} + /api/wcm/webprojects/{webprojectref}/sandboxes/{sandboxref}/assets/content/{path}?webApp={webApp?} + argument + user + required + WCM/Asset + draft_public_api + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.js new file mode 100644 index 0000000000..20f7b01eb1 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.js @@ -0,0 +1,55 @@ +/* + * Get asset content script + */ +function main() +{ + var urlElements = url.extension.split("/"); + var shortName = urlElements[0]; + var boxName = urlElements[2]; + var pathArray = urlElements.slice(5); + var path = pathArray.join("/"); + + var webproject = webprojects.getWebProject(shortName); + if (null == webproject) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The webproject '" + shortName + "' does not exist."); + return; + } + + var sandbox; + sandbox = webproject.getSandbox(boxName); + if (null == sandbox) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The sandbox '" + boxName + "' in webproject '" + shortName + "' does not exist."); + return; + } + + var webApp = args["webApp"]; + + var asset; + + if(null != webApp) + { + asset = sandbox.getAssetWebApp(webApp, path); + } + else + { + asset = sandbox.getAsset(path); + } + + if (null == asset) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The asset '" + path + "' in webproject '" + shortName + "' does not exist."); + return; + } + + // set model properties + model.sandbox = sandbox; + model.webproject = asset.getContent(); + model.asset = asset; +} + +main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.json.ftl new file mode 100644 index 0000000000..dd6eb79a4b --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/content.get.json.ftl @@ -0,0 +1,4 @@ +<#import "asset.lib.ftl" as assetLib/> +{ + "content": "${asset.content}" +} diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.desc.xml new file mode 100644 index 0000000000..63e553fe16 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.desc.xml @@ -0,0 +1,9 @@ + + Update a WCM asset + /api/wcm/webprojects/{webprojectref}/sandboxes/{sandboxref}/assets/properties/{path} + argument + user + required + WCM/Asset + draft_public_api + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.ftl new file mode 100644 index 0000000000..1229613d38 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.ftl @@ -0,0 +1,4 @@ +<#import "asset.lib.ftl" as assetLib/> +{ + data: <@assetLib.assetJSON asset=asset depth=0/> +} diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.js b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.js new file mode 100644 index 0000000000..3605bd577c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/wcm/sandbox/Asset/properties.post.json.js @@ -0,0 +1,72 @@ +/* + * Post -update a asset file/folder + * optionally updates simple content + */ +function main() +{ + var urlElements = url.extension.split("/"); + var shortName = urlElements[0]; + var boxName = urlElements[2]; + var pathArray = urlElements.slice(5); + var path = pathArray.join("/"); + + var webproject = webprojects.getWebProject(shortName); + if (null == webproject) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The webproject, " + shortName + ", does not exist."); + return; + } + var sandbox = webproject.getSandbox(boxName); + if (null == sandbox) + { + // Site cannot be found + status.setCode(status.STATUS_NOT_FOUND, "The sandbox, " + boxName + ", in webproject, " + shortName + ", does not exist."); + return; + } + var asset = sandbox.getAsset(path); + + if (null == asset) + { + status.setCode(status.STATUS_NOT_FOUND, "The asset, " + path + ", in webproject, " + shortName + ", does not exist."); + return; + } + + // Now read the values from the json form +// if(!json.has("properties")) +// { +// status.setCode(status.BAD_REQUEST, "JSON property 'properties' must specified"); +// return; +// } + + var properties = null; + if (json.has("properties")) + { + properties = json.get("properties"); + } + var content = null; + + if(json.has("content")) + { + content = json.get("content"); + } + + if (null != properties) + { + asset.setProperties(properties); + asset.save(); + } + if (null != content) + { + asset.writeContent(content); + } + + // set model properties + model.sandbox = sandbox; + model.webproject = webproject; + model.asset = asset; + + status.code = status.STATUS_ACCEPTED; +} + +main(); diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/datalists/parse-args.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/datalists/parse-args.lib.js index 645c172798..1ff0706eca 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/datalists/parse-args.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/datalists/parse-args.lib.js @@ -40,18 +40,36 @@ var Common = if (typeof Common.PeopleCache[username] == "undefined") { var person = people.getPerson(username); - if (person == null && (username == "System" || username.match("^System@") == "System@")) + if (person == null) { - person = + if (username == "System" || username.match("^System@") == "System@") { - properties: + // special case for the System users + person = { - userName: "System", - firstName: "System", - lastName: "User" - }, - assocs: {} - }; + properties: + { + userName: "System", + firstName: "System", + lastName: "User" + }, + assocs: {} + }; + } + else + { + // missing person - may have been deleted from the database + person = + { + properties: + { + userName: username, + firstName: "", + lastName: "" + }, + assocs: {} + }; + } } Common.PeopleCache[username] = { 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 50c79bf02f..87c7b7a5ac 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 @@ -114,42 +114,45 @@ function getDoclist() { // Get evaluated properties. item = Evaluator.run(node); - item.isFavourite = (favourites[item.node.nodeRef] === true); - - // Does this collection of nodes have potentially differering paths? - if (filterParams.variablePath || item.isLink) + if (item !== null) { - locationNode = (item.isLink && item.type == "document") ? item.linkNode : item.node; - location = Common.getLocation(locationNode); - } - else - { - location = + item.isFavourite = (favourites[item.node.nodeRef] === true); + + // Does this collection of nodes have potentially differering paths? + if (filterParams.variablePath || item.isLink) { - site: parsedArgs.location.site, - siteTitle: parsedArgs.location.siteTitle, - container: parsedArgs.location.container, - path: parsedArgs.location.path, - file: node.name - }; - } - - // Resolved location - item.location = location; - - // Is our thumbnail type registered? - if (isThumbnailNameRegistered) - { - // Make sure we have a thumbnail. - thumbnail = item.node.getThumbnail(THUMBNAIL_NAME); - if (thumbnail === null) - { - // No thumbnail, so queue creation - item.node.createThumbnail(THUMBNAIL_NAME, true); + locationNode = (item.isLink && item.type == "document") ? item.linkNode : item.node; + location = Common.getLocation(locationNode); } + else + { + location = + { + site: parsedArgs.location.site, + siteTitle: parsedArgs.location.siteTitle, + container: parsedArgs.location.container, + path: parsedArgs.location.path, + file: node.name + }; + } + + // Resolved location + item.location = location; + + // Is our thumbnail type registered? + if (isThumbnailNameRegistered) + { + // Make sure we have a thumbnail. + thumbnail = item.node.getThumbnail(THUMBNAIL_NAME); + if (thumbnail === null) + { + // No thumbnail, so queue creation + item.node.createThumbnail(THUMBNAIL_NAME, true); + } + } + + items.push(item); } - - items.push(item); } return ( 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 index 5a725a48dd..ebada43a36 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js @@ -108,8 +108,11 @@ var Evaluator = */ linkNode = node; node = linkNode.properties.destination; - // Re-evaluate the nodeType based on the link's destination node - nodeType = Evaluator.getNodeType(node); + if (node !== null) + { + // Re-evaluate the nodeType based on the link's destination node + nodeType = Evaluator.getNodeType(node); + } break; /** @@ -247,32 +250,39 @@ var Evaluator = break; } - // Part of an active workflow? Guard against stale worklow tasks. - try + if (node !== null) { - for each (activeWorkflow in node.activeWorkflows) + // Part of an active workflow? Guard against stale worklow tasks. + try { - activeWorkflows.push(activeWorkflow.id); + for each (activeWorkflow in node.activeWorkflows) + { + activeWorkflows.push(activeWorkflow.id); + } } + catch (e) {} + + return( + { + node: node, + type: nodeType, + linkNode: linkNode, + isLink: isLink, + status: status, + actionSet: actionSet, + actionPermissions: permissions, + createdBy: createdBy, + modifiedBy: modifiedBy, + lockedBy: lockedBy, + tags: node.tags, + activeWorkflows: activeWorkflows, + custom: jsonUtils.toJSONString(custom), + actionLabels: actionLabels + }); } - catch (e) {} - - return( + else { - node: node, - type: nodeType, - linkNode: linkNode, - isLink: isLink, - status: status, - actionSet: actionSet, - actionPermissions: permissions, - createdBy: createdBy, - modifiedBy: modifiedBy, - lockedBy: lockedBy, - tags: node.tags, - activeWorkflows: activeWorkflows, - custom: jsonUtils.toJSONString(custom), - actionLabels: actionLabels - }); + return null; + } } }; diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/parse-args.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/parse-args.lib.js index 5f990f6eb7..ebe472b621 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/parse-args.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/parse-args.lib.js @@ -26,18 +26,36 @@ var Common = if (typeof Common.PeopleCache[username] == "undefined") { var person = people.getPerson(username); - if (person == null && (username == "System" || username.match("^System@") == "System@")) + if (person == null) { - person = + if (username == "System" || username.match("^System@") == "System@") { - properties: + // special case for the System users + person = { - userName: "System", - firstName: "System", - lastName: "User" - }, - assocs: {} - }; + properties: + { + userName: "System", + firstName: "System", + lastName: "User" + }, + assocs: {} + }; + } + else + { + // missing person - may have been deleted from the database + person = + { + properties: + { + userName: username, + firstName: "", + lastName: "" + }, + assocs: {} + }; + } } Common.PeopleCache[username] = { diff --git a/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.html.ftl index 4c056783c8..71f726b6ee 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.html.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.html.ftl @@ -86,6 +86,11 @@ { <@serializeHash hash=capabilities/> } + , + "immutableProperties": + { + <@serializeHash hash=immutableProperties/> + } diff --git a/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js b/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js index 77a1ec0da6..3f5830a2f5 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js @@ -21,6 +21,7 @@ else if (args["user"] != null) model.isUser = true; model.includeChildren = false; model.capabilities = people.getCapabilities(object); + model.immutableProperties = people.getImmutableProperties(userId); } // load content by relative path diff --git a/source/java/org/alfresco/repo/cmis/ws/utils/PropertyUtil.java b/source/java/org/alfresco/repo/cmis/ws/utils/PropertyUtil.java index 2a3268281b..fa1218f3f9 100644 --- a/source/java/org/alfresco/repo/cmis/ws/utils/PropertyUtil.java +++ b/source/java/org/alfresco/repo/cmis/ws/utils/PropertyUtil.java @@ -568,12 +568,26 @@ public class PropertyUtil { for (Object propertyValue : (Collection) value) { - property.getValue().add(BigInteger.valueOf((Long) propertyValue)); + if(propertyValue instanceof Long) + { + property.getValue().add(BigInteger.valueOf((Long) propertyValue)); + } + else + { + property.getValue().add(BigInteger.valueOf((Integer) propertyValue)); + } } } else { - property.getValue().add(BigInteger.valueOf((Long) value)); + if(value instanceof Long) + { + property.getValue().add(BigInteger.valueOf((Long) value)); + } + else + { + property.getValue().add(BigInteger.valueOf((Integer) value)); + } } return property; diff --git a/source/java/org/alfresco/repo/web/scripts/wcm/sandbox/AssetTest.java b/source/java/org/alfresco/repo/web/scripts/wcm/sandbox/AssetTest.java index 6122478c83..031ce28a55 100644 --- a/source/java/org/alfresco/repo/web/scripts/wcm/sandbox/AssetTest.java +++ b/source/java/org/alfresco/repo/web/scripts/wcm/sandbox/AssetTest.java @@ -20,6 +20,8 @@ package org.alfresco.repo.web.scripts.wcm.sandbox; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; @@ -31,6 +33,7 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.util.PropertyMap; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest; @@ -68,7 +71,18 @@ public class AssetTest extends BaseWebScriptTest { private static final String WEBAPP_ROOT = "ROOT"; private static final String WEBAPP_YELLOW = "YELLOW"; private static final String WEBAPP_GREEN = "GREEN"; - + + private static final String ROOT_FILE = "index.htm"; + + private static final String FIELD_DATA = "data"; + private static final String FIELD_PROPERTIES = "properties"; + private static final String FIELD_CONTENT = "content"; + + private static final String PROP_NAME = "cm:name"; + private static final String PROP_TITLE = "cm:title"; + + private static final String TEST_CONTENT_ENTRY = "This is test content entry for an Asset"; + // override jbpm.job.executor idleInterval to 5s (was 1.5m) for WCM unit tests private static final String SUBMIT_CONFIG_LOCATION = "classpath:wcm/wcm-jbpm-context.xml"; private static final long SUBMIT_DELAY = 15000L; // (in millis) 15s - to allow time for async submit workflow to complete (as per 5s idleInterval above) @@ -133,7 +147,7 @@ public class AssetTest extends BaseWebScriptTest { Response response = sendRequest(new PostRequest(URL_WEB_PROJECT, webProj.toString(), "application/json"), Status.STATUS_OK); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject data = result.getJSONObject("data"); + JSONObject data = result.getJSONObject(FIELD_DATA); String webProjectRef = data.getString("webprojectref"); assertNotNull("webproject ref is null", webProjectRef); @@ -171,7 +185,7 @@ public class AssetTest extends BaseWebScriptTest { String validURL = "/api/wcm/webprojects/" + webprojref + "/sandboxes"; Response response = sendRequest(new PostRequest(validURL, box.toString(), "application/json"), Status.STATUS_OK); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject data = result.getJSONObject("data"); + JSONObject data = result.getJSONObject(FIELD_DATA); sandboxref = data.getString("sandboxref"); assertNotNull("sandboxref is null", sandboxref); } @@ -184,7 +198,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("sandbox is not empty", lookupResult.length() == 0); } @@ -246,7 +260,7 @@ public class AssetTest extends BaseWebScriptTest { Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); System.out.println(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 1); @@ -289,7 +303,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 0); } @@ -322,7 +336,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 1); @@ -359,7 +373,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 2); } @@ -379,7 +393,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 3); } @@ -472,7 +486,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); } @@ -518,7 +532,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); @@ -555,7 +569,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); @@ -598,7 +612,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); JSONArray assets = new JSONArray(); JSONArray paths = new JSONArray(); JSONArray omitted = new JSONArray(); @@ -638,7 +652,7 @@ public class AssetTest extends BaseWebScriptTest { Response listTwo = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject resultTwo = new JSONObject(listTwo.getContentAsString()); - JSONArray lookupResultTwo = resultTwo.getJSONArray("data"); + JSONArray lookupResultTwo = resultTwo.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResultTwo.length() == 2); /** @@ -701,7 +715,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertEquals("testListUserSandbox", lookupResult.length(), 1); @@ -771,7 +785,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); } @@ -808,7 +822,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); @@ -838,7 +852,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() > 0); @@ -897,7 +911,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); JSONArray assets = new JSONArray(); JSONArray paths = new JSONArray(); JSONArray omitted = new JSONArray(); @@ -933,7 +947,7 @@ public class AssetTest extends BaseWebScriptTest { Response listTwo = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject resultTwo = new JSONObject(listTwo.getContentAsString()); - JSONArray lookupResultTwo = resultTwo.getJSONArray("data"); + JSONArray lookupResultTwo = resultTwo.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResultTwo.length() == 2); /** @@ -992,7 +1006,7 @@ public class AssetTest extends BaseWebScriptTest { String sandboxesURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/modified"; Response list = sendRequest(new GetRequest(sandboxesURL), Status.STATUS_OK); JSONObject result = new JSONObject(list.getContentAsString()); - JSONArray lookupResult = result.getJSONArray("data"); + JSONArray lookupResult = result.getJSONArray(FIELD_DATA); assertTrue("testListUserSandbox", lookupResult.length() == 1); @@ -1008,7 +1022,6 @@ public class AssetTest extends BaseWebScriptTest { public void testGetAsset() throws Exception { final String YELLOW_FILE = "YellowFile.xyz"; - final String ROOT_FILE = "index.htm"; this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); String webprojref = createWebProject(); @@ -1036,7 +1049,7 @@ public class AssetTest extends BaseWebScriptTest { Response root = sendRequest(new GetRequest(rootURL), Status.STATUS_OK); JSONObject result = new JSONObject(root.getContentAsString()); System.out.println(root.getContentAsString()); - JSONObject rootDir = result.getJSONObject("data"); + JSONObject rootDir = result.getJSONObject(FIELD_DATA); String name = rootDir.getString("name"); JSONArray children = rootDir.getJSONArray("children"); assertEquals("name is wrong", WEBAPP_ROOT, name); @@ -1050,7 +1063,7 @@ public class AssetTest extends BaseWebScriptTest { String yellowURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets" + "/www/avm_webapps/" + WEBAPP_YELLOW + "/" + YELLOW_FILE ; Response yellow = sendRequest(new GetRequest(yellowURL), Status.STATUS_OK); JSONObject result = new JSONObject(yellow.getContentAsString()); - JSONObject yellowFile = result.getJSONObject("data"); + JSONObject yellowFile = result.getJSONObject(FIELD_DATA); String name = yellowFile.getString("name"); long version = yellowFile.getLong("version"); long fileSize = yellowFile.getLong("fileSize"); @@ -1064,7 +1077,7 @@ public class AssetTest extends BaseWebScriptTest { String yellowURL = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets" + "/" + YELLOW_FILE +"?webApp="+ WEBAPP_YELLOW; Response yellow = sendRequest(new GetRequest(yellowURL), Status.STATUS_OK); JSONObject result = new JSONObject(yellow.getContentAsString()); - JSONObject yellowFile = result.getJSONObject("data"); + JSONObject yellowFile = result.getJSONObject(FIELD_DATA); String name = yellowFile.getString("name"); long version = yellowFile.getLong("version"); long fileSize = yellowFile.getLong("fileSize"); @@ -1110,7 +1123,6 @@ public class AssetTest extends BaseWebScriptTest { { final String YELLOW_FILE = "YellowFile.xyz"; final String YELLOW_FILE2 = "Buffy.jpg"; - final String ROOT_FILE = "index.htm"; this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); String webprojref = createWebProject(); @@ -1197,7 +1209,6 @@ public class AssetTest extends BaseWebScriptTest { public void testCreateAsset() throws Exception { final String YELLOW_FILE = "YellowFile.xyz"; - final String ROOT_FILE = "index.htm"; this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); String webprojref = createWebProject(); @@ -1215,7 +1226,7 @@ public class AssetTest extends BaseWebScriptTest { Response response = sendRequest(new PostRequest(rootURL, submitForm.toString(), "application/json"), Status.STATUS_CREATED); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); boolean isFolder = lookupResult.getBoolean("isFolder"); boolean isFile = lookupResult.getBoolean("isFile"); @@ -1234,10 +1245,10 @@ public class AssetTest extends BaseWebScriptTest { JSONObject submitForm = new JSONObject(); submitForm.put("name", ROOT_FILE); submitForm.put("type", "file"); - submitForm.put("content", "Hello World"); + submitForm.put(FIELD_CONTENT, "Hello World"); Response response = sendRequest(new PostRequest(rootURL, submitForm.toString(), "application/json"), Status.STATUS_CREATED); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); long fileSize = lookupResult.getLong("fileSize"); assertEquals("name is wrong", ROOT_FILE, name); @@ -1281,7 +1292,7 @@ public class AssetTest extends BaseWebScriptTest { submitForm.put("type", "file"); Response response = sendRequest(new PostRequest(rootURL, submitForm.toString(), "application/json"), Status.STATUS_CREATED); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); String path = lookupResult.getString("path"); assertEquals("name not correct", name, "dawn.jpg"); @@ -1299,7 +1310,6 @@ public class AssetTest extends BaseWebScriptTest { public void testRenameAsset() throws Exception { final String YELLOW_FILE = "buffy.jpg"; - final String ROOT_FILE = "index.htm"; final String PURPLE_FILE = "buffy.htm"; final String PURPLE_FILE2 = "willow.htm"; final String ROOT_MOVED_FILE = "smashing.htm"; @@ -1321,7 +1331,7 @@ public class AssetTest extends BaseWebScriptTest { submitForm.put("name", WEBAPP_GREEN); Response response = sendRequest(new PutRequest(yellowURL, submitForm.toString(), "application/json"), Status.STATUS_OK); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); assertEquals("name is wrong", WEBAPP_GREEN, name); } @@ -1337,7 +1347,7 @@ public class AssetTest extends BaseWebScriptTest { submitForm.put("name", ROOT_MOVED_FILE); Response response = sendRequest(new PutRequest(yellowURL, submitForm.toString(), "application/json"), Status.STATUS_OK); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); assertEquals("name is wrong", ROOT_MOVED_FILE, name); @@ -1358,7 +1368,7 @@ public class AssetTest extends BaseWebScriptTest { submitForm.put("name", PURPLE_FILE2); Response response = sendRequest(new PutRequest(purpleURL, submitForm.toString(), "application/json"), Status.STATUS_OK); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); assertEquals("name is wrong", PURPLE_FILE2, name); } @@ -1382,7 +1392,6 @@ public class AssetTest extends BaseWebScriptTest { public void testMoveAsset() throws Exception { final String YELLOW_FILE = "buffy.jpg"; - final String ROOT_FILE = "index.htm"; this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); String webprojref = createWebProject(); @@ -1403,7 +1412,7 @@ public class AssetTest extends BaseWebScriptTest { Response response = sendRequest(new PutRequest(myURL, submitForm.toString(), "application/json"), Status.STATUS_OK); System.out.println(response.getContentAsString()); JSONObject result = new JSONObject(response.getContentAsString()); - JSONObject lookupResult = result.getJSONObject("data"); + JSONObject lookupResult = result.getJSONObject(FIELD_DATA); String name = lookupResult.getString("name"); assertEquals("name is wrong", ROOT_FILE, name); @@ -1413,7 +1422,84 @@ public class AssetTest extends BaseWebScriptTest { sendRequest(new PutRequest(myURL, submitForm.toString(), "application/json"), Status.STATUS_NOT_FOUND); } } - + + /** + * Tests updating properties of an Asset + * + * @throws Exception + */ + public void testUpdateAssetProperties() throws Exception + { + this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); + String webprojref = createWebProject(); + createMembership(webprojref, USER_ONE, ROLE_CONTENT_MANAGER); + String sandboxref = createSandbox(webprojref, AuthenticationUtil.getAdminUserName()); + + // Update properties for the File object + createFile(webprojref, sandboxref, WEBAPP_ROOT, "/", ROOT_FILE); + updatePropertiesAndAssert(webprojref, sandboxref, ROOT_FILE, ("Renamed_" + ROOT_FILE)); + + // Update properties for the Folder object + createFolder(webprojref, sandboxref, WEBAPP_ROOT, "/", WEBAPP_GREEN); + updatePropertiesAndAssert(webprojref, sandboxref, WEBAPP_GREEN, ("Renamed_" + WEBAPP_GREEN)); + } + + private void updatePropertiesAndAssert(String webprojref, String sandboxref, String oldName, String updatedName) throws JSONException, IOException, + UnsupportedEncodingException + { + String propertiesUrl = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets/properties/www/avm_webapps/" + WEBAPP_ROOT + "/" + oldName; + JSONObject properties = new JSONObject(); + properties.put(ContentModel.PROP_TITLE.getLocalName(), updatedName); + properties.put(ContentModel.PROP_NAME.getLocalName(), updatedName); + JSONObject submitForm = new JSONObject(); + submitForm.put(FIELD_PROPERTIES, properties); + Response response = sendRequest(new PostRequest(propertiesUrl, submitForm.toString(), "application/json"), Status.STATUS_ACCEPTED); + assertUpdatedProperties(updatedName, response); + // Check whether the updated File is allowable + String assetRequestUrl = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets/www/avm_webapps/" + WEBAPP_ROOT + "/" + updatedName; + response = sendRequest(new GetRequest(assetRequestUrl), Status.STATUS_OK); + assertUpdatedProperties(updatedName, response); + // Negative test + assetRequestUrl = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets/www/avm_webapps" + WEBAPP_ROOT + "/" + oldName; + response = sendRequest(new GetRequest(assetRequestUrl), Status.STATUS_NOT_FOUND); + } + + private void assertUpdatedProperties(String updatedName, Response response) throws JSONException, UnsupportedEncodingException + { + JSONObject result = new JSONObject(response.getContentAsString()); + JSONObject properties = (JSONObject) result.get(FIELD_DATA); + properties = (JSONObject) properties.get(FIELD_PROPERTIES); + assertEquals(updatedName, properties.get(PROP_TITLE)); + assertEquals(updatedName, properties.get(PROP_NAME)); + } + + /** + * Tests updating of Content of an File Asset + * + * @throws Exception + */ + public void testGetAndUpdateAssetContent() throws Exception + { + this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName()); + String webprojref = createWebProject(); + createMembership(webprojref, USER_ONE, ROLE_CONTENT_MANAGER); + String sandboxref = createSandbox(webprojref, USER_ONE); + + createFile(webprojref, sandboxref, WEBAPP_ROOT, "/", ROOT_FILE); + String contentRequestUrl = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets/content/www/avm_webapps/" + WEBAPP_ROOT + "/" + ROOT_FILE; + sendRequest(new GetRequest(contentRequestUrl), Status.STATUS_INTERNAL_SERVER_ERROR); + + String propertiesRequestUrl = URL_WEB_PROJECT + "/" + webprojref + URI_SANDBOXES + "/" + sandboxref + "/assets/properties/www/avm_webapps/" + WEBAPP_ROOT + "/" + ROOT_FILE; + JSONObject contentEntry = new JSONObject(); + String content = TEST_CONTENT_ENTRY; + contentEntry.put(FIELD_CONTENT, content); + sendRequest(new PostRequest(propertiesRequestUrl, contentEntry.toString(), "application/json"), Status.STATUS_ACCEPTED); + + Response response = sendRequest(new GetRequest(contentRequestUrl), Status.STATUS_OK); + contentEntry = new JSONObject(response.getContentAsString()); + assertEquals(content, contentEntry.get(FIELD_CONTENT)); + } + /** * Utility method to create a folder * @param webprojref diff --git a/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java b/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java index 46a8c143db..96124f0415 100644 --- a/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java +++ b/source/java/org/alfresco/repo/webdav/HierarchicalMethod.java @@ -175,7 +175,7 @@ public abstract class HierarchicalMethod extends WebDAVMethod boolean localPath = true; - if (url.getPort() != -1 && url.getPort() != m_request.getLocalPort()) + if (url.getPort() != -1 && url.getPort() != m_request.getServerPort()) { // Debug @@ -184,7 +184,7 @@ public abstract class HierarchicalMethod extends WebDAVMethod localPath = false; } - else if (url.getHost().equalsIgnoreCase( m_request.getLocalName()) == false + else if (url.getHost().equalsIgnoreCase( m_request.getServerName()) == false && url.getHost().equals(m_request.getLocalAddr()) == false) { // The target host may contain a domain or be specified as a numeric IP address @@ -193,7 +193,7 @@ public abstract class HierarchicalMethod extends WebDAVMethod if ( IPAddress.isNumericAddress( targetHost) == false) { - String localHost = m_request.getLocalName(); + String localHost = m_request.getServerName(); int pos = targetHost.indexOf( "."); if ( pos != -1) @@ -234,7 +234,7 @@ public abstract class HierarchicalMethod extends WebDAVMethod if (localPath == false && logger.isDebugEnabled()) { logger.debug("Destination path, different server name/address"); - logger.debug(" URL host=" + url.getHost() + ", localName=" + m_request.getLocalName() + ", localAddr=" + m_request.getLocalAddr()); + logger.debug(" URL host=" + url.getHost() + ", ServerName=" + m_request.getServerName() + ", localAddr=" + m_request.getLocalAddr()); } } else if (url.getPath().indexOf(m_request.getServletPath()) == -1) diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java index 1ca44cebd8..5801a5d415 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseAuthenticationFilter.java @@ -29,6 +29,8 @@ import javax.servlet.http.HttpSession; import org.alfresco.model.ContentModel; import org.alfresco.repo.SessionUser; +import org.alfresco.repo.management.subsystems.ActivateableBean; +import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; @@ -69,9 +71,17 @@ public abstract class BaseAuthenticationFilter /** The transaction service. */ protected TransactionService transactionService; + /** The authentication component. */ + protected AuthenticationComponent authenticationComponent; + + /** The remote user mapper. */ + protected RemoteUserMapper remoteUserMapper; + /** The configured user attribute name. */ private String userAttributeName = AUTHENTICATION_USER; + + /** * Sets the authentication service. * @@ -116,6 +126,28 @@ public abstract class BaseAuthenticationFilter this.transactionService = transactionService; } + /** + * Sets the authentication component. + * + * @param authenticationComponent + * the authentication component + */ + public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) + { + this.authenticationComponent = authenticationComponent; + } + + /** + * Sets the remote user mapper. + * + * @param remoteUserMapper + * the remote user mapper + */ + public void setRemoteUserMapper(RemoteUserMapper remoteUserMapper) + { + this.remoteUserMapper = remoteUserMapper; + } + /** * Create the user object that will be stored in the session. * @@ -150,6 +182,15 @@ public abstract class BaseAuthenticationFilter protected SessionUser getSessionUser(ServletContext servletContext, final HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, final boolean externalAuth) { + String userId = null; + + // If the remote user mapper is configured, we may be able to map in an externally authenticated user + if (remoteUserMapper != null + && (!(remoteUserMapper instanceof ActivateableBean) || ((ActivateableBean) remoteUserMapper).isActive())) + { + userId = remoteUserMapper.getRemoteUser(httpServletRequest); + } + String sessionAttrib = getUserAttributeName(); HttpSession session = httpServletRequest.getSession(); SessionUser sessionUser = (SessionUser) session.getAttribute(sessionAttrib); @@ -167,6 +208,36 @@ public abstract class BaseAuthenticationFilter sessionUser = null; } } + + if (userId != null) + { + // We have a previously-cached user with the wrong identity - replace them + if (sessionUser != null && !sessionUser.getUserName().equals(userId)) + { + session.removeAttribute(sessionAttrib); + session.invalidate(); + sessionUser = null; + } + + if (sessionUser == null) + { + // If we have been authenticated by other means, just propagate through the user identity + authenticationComponent.setCurrentUser(userId); + session = httpServletRequest.getSession(); + String sessionId = session.getId(); + + try + { + sessionUser = createUserEnvironment(session, authenticationService.getCurrentUserName(), authenticationService.getCurrentTicket(sessionId), true); + } + catch (Throwable e) + { + if (getLogger().isDebugEnabled()) + getLogger().debug("Error during ticket validation and user creation: " + e.getMessage(), e); + } + } + } + return sessionUser; } @@ -279,6 +350,32 @@ public abstract class BaseAuthenticationFilter } } + /** + * Callback to create the User environment as appropriate for a filter impl + * + * @param session + * HttpSession + * @param userName + * String + * @return SessionUser + * @throws IOException + * @throws ServletException + */ + protected SessionUser createUserEnvironment(final HttpSession session, final String userName) throws IOException, + ServletException + { + return this.transactionService.getRetryingTransactionHelper().doInTransaction( + new RetryingTransactionHelper.RetryingTransactionCallback() + { + + public SessionUser execute() throws Throwable + { + authenticationComponent.setCurrentUser(userName); + return createUserEnvironment(session, userName, authenticationService.getCurrentTicket(session.getId()), true); + } + }); + } + /** * Return the logger. * diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java index 70b6a648f5..7de1551701 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java @@ -279,7 +279,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica // Restart the authentication - restartLoginChallenge(resp, req.getSession()); + restartLoginChallenge(req, resp, req.getSession()); chain.doFilter(sreq, sresp); return; @@ -349,7 +349,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica // Send back a request for SPNEGO authentication - restartLoginChallenge( resp, httpSess); + restartLoginChallenge(req, resp, httpSess); } else { @@ -366,7 +366,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica // Restart the authentication - restartLoginChallenge(resp, httpSess); + restartLoginChallenge(req, resp, httpSess); return; } @@ -419,7 +419,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica { // Send back a request for SPNEGO authentication - restartLoginChallenge( resp, httpSess); + restartLoginChallenge(req, resp, httpSess); } } catch (AuthenticationException ex) @@ -448,7 +448,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica // Send back a request for SPNEGO authentication - restartLoginChallenge( resp, httpSess); + restartLoginChallenge(req, resp, httpSess); } } } @@ -578,12 +578,13 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica * @param httpSess HttpSession * @throws IOException */ - protected void restartLoginChallenge(HttpServletResponse resp, HttpSession session) throws IOException + protected void restartLoginChallenge(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws IOException { // Force the logon to start again resp.setHeader("WWW-Authenticate", "Negotiate"); resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeLoginPageLink(req, resp); resp.flushBuffer(); } diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java index c8cb0eb4e3..cf80d2bc42 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java @@ -214,7 +214,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication // Restart the authentication - restartLoginChallenge(resp, req.getSession()); + restartLoginChallenge(req, resp, req.getSession()); return; } } @@ -263,7 +263,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication if ( hasLoginPage()) redirectToLoginPage(req, resp); else - restartLoginChallenge(resp, httpSess); + restartLoginChallenge(req, resp, httpSess); return; } @@ -293,7 +293,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication req.getRemoteAddr() + ":" + req.getRemotePort() + ") SID:" + req.getSession().getId()); // Send back a request for NTLM authentication - restartLoginChallenge(resp, httpSess); + restartLoginChallenge(req, resp, httpSess); } else { @@ -639,7 +639,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication } else { - restartLoginChallenge(res, session); + restartLoginChallenge(req, res, session); } } } @@ -1005,7 +1005,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication * @param httpSess * @throws IOException */ - protected void restartLoginChallenge(HttpServletResponse res, HttpSession session) throws IOException + protected void restartLoginChallenge(HttpServletRequest req, HttpServletResponse res, HttpSession session) throws IOException { // Remove any existing session and NTLM details from the session session.removeAttribute(NTLM_AUTH_SESSION); @@ -1014,6 +1014,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication // Force the logon to start again res.setHeader(WWW_AUTHENTICATE, AUTH_NTLM); res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + writeLoginPageLink(req, res); res.flushBuffer(); } diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java index 444cb33307..1848de8b58 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java @@ -19,6 +19,7 @@ package org.alfresco.repo.webdav.auth; import java.io.IOException; +import java.io.PrintWriter; import java.net.InetAddress; import java.net.UnknownHostException; @@ -37,9 +38,7 @@ import org.alfresco.jlan.server.config.SecurityConfigSection; import org.alfresco.jlan.util.IPAddress; import org.alfresco.repo.SessionUser; import org.alfresco.repo.management.subsystems.ActivateableBean; -import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationException; -import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter; import org.springframework.beans.factory.InitializingBean; @@ -65,7 +64,6 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt // Various services required by NTLM authenticator - protected AuthenticationComponent authenticationComponent; private String m_loginPage; // Indicate whether ticket based logons are supported @@ -87,13 +85,6 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt this.serverConfiguration = serverConfiguration; } - /** - * @param authenticationComponent the authenticationComponent to set - */ - public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) - { - this.authenticationComponent = authenticationComponent; - } /** * Activates or deactivates the bean @@ -136,31 +127,6 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt { } - /** - * Callback to create the User environment as appropriate for a filter impl - * - * @param session - * HttpSession - * @param userName - * String - * @return SessionUser - * @throws IOException - * @throws ServletException - */ - protected SessionUser createUserEnvironment(final HttpSession session, final String userName) throws IOException, - ServletException - { - return this.transactionService.getRetryingTransactionHelper().doInTransaction( - new RetryingTransactionHelper.RetryingTransactionCallback() - { - - public SessionUser execute() throws Throwable - { - authenticationComponent.setCurrentUser(userName); - return createUserEnvironment(session, userName, authenticationService.getCurrentTicket(session.getId()), true); - } - }); - } /** @@ -517,4 +483,32 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt { return serverConfiguration == null ? null : (SecurityConfigSection) serverConfiguration.getConfigSection(SecurityConfigSection.SectionName); } + + /** + * Writes link to login page and refresh tag which cause user + * to be redirected to the login page. + * + * @param resp HttpServletResponse + * @param httpSess HttpSession + * @throws IOException + */ + protected void writeLoginPageLink(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + if ( hasLoginPage()) + { + final PrintWriter out = resp.getWriter(); + out.println(""); + out.println(""); + out.println("

Please log in.

"); + out.println(""); + out.close(); + } + } + + + } diff --git a/source/java/org/alfresco/repo/webdav/auth/KerberosAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/KerberosAuthenticationFilter.java index cacd730d38..9f642a7df0 100644 --- a/source/java/org/alfresco/repo/webdav/auth/KerberosAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/KerberosAuthenticationFilter.java @@ -67,7 +67,7 @@ public class KerberosAuthenticationFilter extends BaseKerberosAuthenticationFilt { // Restart the login challenge process if validation fails - restartLoginChallenge(res, session); + restartLoginChallenge(req, res, session); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/webdav/auth/NTLMAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/NTLMAuthenticationFilter.java index 8a2a0a65d4..5ecafa1499 100644 --- a/source/java/org/alfresco/repo/webdav/auth/NTLMAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/NTLMAuthenticationFilter.java @@ -62,7 +62,7 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter { // Restart the login challenge process if validation fails - restartLoginChallenge(res, session); + restartLoginChallenge(req, res, session); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/webdav/auth/RemoteUserMapper.java b/source/java/org/alfresco/repo/webdav/auth/RemoteUserMapper.java new file mode 100644 index 0000000000..0684019a7b --- /dev/null +++ b/source/java/org/alfresco/repo/webdav/auth/RemoteUserMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.webdav.auth; + +import javax.servlet.http.HttpServletRequest; + +/** + * An interface for objects capable of extracting an externally authenticated user ID from an HTTP request. + * + * @author dward + */ +public interface RemoteUserMapper +{ + /** + * Gets an externally authenticated user ID from an HTTP request. + * + * @param request + * the request + * @return the user ID or null if the user is unauthenticated + */ + public String getRemoteUser(HttpServletRequest request); +} diff --git a/source/java/org/alfresco/repo/webservice/repository/AssociationQuery.java b/source/java/org/alfresco/repo/webservice/repository/AssociationQuery.java index c980e692bf..a44c7df70d 100644 --- a/source/java/org/alfresco/repo/webservice/repository/AssociationQuery.java +++ b/source/java/org/alfresco/repo/webservice/repository/AssociationQuery.java @@ -19,9 +19,11 @@ package org.alfresco.repo.webservice.repository; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.webservice.AbstractQuery; import org.alfresco.repo.webservice.Utils; import org.alfresco.repo.webservice.types.NamedValue; @@ -113,10 +115,8 @@ public class AssociationQuery extends AbstractQuery } } - int totalRows = assocRefs.size(); - ResultSet results = new ResultSet(); - ResultSetRow[] rows = new ResultSetRow[totalRows]; + List rows = new ArrayList(assocRefs.size()); int index = 0; NodeRef childNodeRef = null; @@ -130,42 +130,55 @@ public class AssociationQuery extends AbstractQuery { childNodeRef = assocRef.getTargetRef(); } - ResultSetRowNode rowNode = createResultSetRowNode(childNodeRef, nodeService); - - // create columns for all the properties of the node - // get the data for the row and build up the columns structure - Map props = nodeService.getProperties(childNodeRef); - NamedValue[] columns = new NamedValue[props.size()+2]; - int col = 0; - for (QName propName : props.keySet()) + + Map props = null; + try { - columns[col] = Utils.createNamedValue(dictionaryService, propName, props.get(propName)); - col++; + props = nodeService.getProperties(childNodeRef); + } + catch (AccessDeniedException e) + { + // user has no access to associated node } - // Now add the system columns containing the association details - columns[col] = new NamedValue(SYS_COL_ASSOC_TYPE, Boolean.FALSE, assocRef.getTypeQName().toString(), null); - - // Add one more column for the node's path - col++; - columns[col] = Utils.createNamedValue( - dictionaryService, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"), - nodeService.getPath(childNodeRef).toString()); - - ResultSetRow row = new ResultSetRow(); - row.setRowIndex(index); - row.setNode(rowNode); - row.setColumns(columns); + if (props != null) + { + ResultSetRowNode rowNode = createResultSetRowNode(childNodeRef, nodeService); - // add the row to the overall results - rows[index] = row; - index++; + // create columns for all the properties of the node + // get the data for the row and build up the columns structure + NamedValue[] columns = new NamedValue[props.size()+2]; + int col = 0; + for (QName propName : props.keySet()) + { + columns[col] = Utils.createNamedValue(dictionaryService, propName, props.get(propName)); + col++; + } + + // Now add the system columns containing the association details + columns[col] = new NamedValue(SYS_COL_ASSOC_TYPE, Boolean.FALSE, assocRef.getTypeQName().toString(), null); + + // Add one more column for the node's path + col++; + columns[col] = Utils.createNamedValue( + dictionaryService, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "path"), + nodeService.getPath(childNodeRef).toString()); + + ResultSetRow row = new ResultSetRow(); + row.setRowIndex(index); + row.setNode(rowNode); + row.setColumns(columns); + + // add the row to the overall results + rows.add(row); + index++; + } } // add the rows to the result set and set the total row count - results.setRows(rows); - results.setTotalRowCount(totalRows); + results.setRows(rows.toArray(new ResultSetRow[0])); + results.setTotalRowCount(rows.size()); return results; }