diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index 2a5bcbf55d..42692b4efe 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -658,6 +658,9 @@
+
+
+
diff --git a/source/java/org/alfresco/repo/importer/ImportNode.java b/source/java/org/alfresco/repo/importer/ImportNode.java
index a5c65b5c39..01e671dcf4 100644
--- a/source/java/org/alfresco/repo/importer/ImportNode.java
+++ b/source/java/org/alfresco/repo/importer/ImportNode.java
@@ -17,12 +17,14 @@
package org.alfresco.repo.importer;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.namespace.QName;
@@ -78,4 +80,14 @@ public interface ImportNode
*/
public Set getNodeAspects();
+ /**
+ * @return true => the node inherits permissions from its parent
+ */
+ public boolean getInheritPermissions();
+
+ /**
+ * @return the permissions applied to this node
+ */
+ public List getAccessControlEntries();
+
}
diff --git a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
index adc0f1738d..78eec9c2e9 100644
--- a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
+++ b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
@@ -36,6 +36,7 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.view.ImporterBinding;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.view.ImporterProgress;
@@ -477,6 +478,17 @@ public class ImporterBootstrap
logger.debug("Property " + property + " set to value " + value + " on node " + nodeRef);
}
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.view.ImporterProgress#permissionSet(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.security.AccessPermission)
+ */
+ public void permissionSet(NodeRef nodeRef, AccessPermission permission)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Permission " + permission.getPermission() + " set on node " + nodeRef + " (authority=" + permission.getAuthority() +
+ ", accessStatus=" + permission.getAccessStatus() + ")");
+ }
+
/* (non-Javadoc)
* @see org.alfresco.repo.importer.Progress#aspectAdded(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
@@ -485,7 +497,6 @@ public class ImporterBootstrap
if (logger.isDebugEnabled())
logger.debug("Added aspect " + aspect + " to node " + nodeRef);
}
-
}
/**
diff --git a/source/java/org/alfresco/repo/importer/ImporterComponent.java b/source/java/org/alfresco/repo/importer/ImporterComponent.java
index a0d873e818..eefa2a056f 100644
--- a/source/java/org/alfresco/repo/importer/ImporterComponent.java
+++ b/source/java/org/alfresco/repo/importer/ImporterComponent.java
@@ -51,6 +51,9 @@ import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.AccessStatus;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.view.ImportPackageHandler;
import org.alfresco.service.cmr.view.ImporterBinding;
import org.alfresco.service.cmr.view.ImporterException;
@@ -88,6 +91,7 @@ public class ImporterComponent
private SearchService searchService;
private ContentService contentService;
private RuleService ruleService;
+ private PermissionService permissionService;
// binding markers
private static final String START_BINDING_MARKER = "${";
@@ -159,6 +163,15 @@ public class ImporterComponent
{
this.ruleService = ruleService;
}
+
+ /**
+ * @param permissionService permissionService
+ */
+ public void setPermissionService(PermissionService permissionService)
+ {
+ this.permissionService = permissionService;
+ }
+
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterService#importView(java.io.InputStreamReader, org.alfresco.service.cmr.view.Location, java.util.Properties, org.alfresco.service.cmr.view.ImporterProgress)
@@ -875,6 +888,23 @@ public class ImporterComponent
}
}
}
+
+ /**
+ * Helper to report permission set progress
+ *
+ * @param nodeRef
+ * @param permissions
+ */
+ private void reportPermissionSet(NodeRef nodeRef, List permissions)
+ {
+ if (progress != null)
+ {
+ for (AccessPermission permission : permissions)
+ {
+ progress.permissionSet(nodeRef, permission);
+ }
+ }
+ }
/**
* Import strategy where imported nodes are always created regardless of whether a
@@ -950,24 +980,37 @@ public class ImporterComponent
// Create Node
ChildAssociationRef assocRef = nodeService.createNode(parentRef, assocType, childQName, nodeType.getName(), initialProperties);
+ NodeRef nodeRef = assocRef.getChildRef();
+
+ // Apply permissions
+ boolean inheritPermissions = node.getInheritPermissions();
+ if (!inheritPermissions)
+ {
+ permissionService.setInheritParentPermissions(nodeRef, false);
+ }
+ List permissions = node.getAccessControlEntries();
+ for (AccessPermission permission : permissions)
+ {
+ permissionService.setPermission(nodeRef, permission.getAuthority(), permission.getPermission(), permission.getAccessStatus().equals(AccessStatus.ALLOWED));
+ }
+
+ // Disable behaviour for the node until the complete node (and its children have been imported)
for (QName disabledBehaviour : disabledBehaviours)
{
behaviourFilter.enableBehaviour(disabledBehaviour);
}
-
- // Report creation
- NodeRef nodeRef = assocRef.getChildRef();
- reportNodeCreated(assocRef);
- reportPropertySet(nodeRef, initialProperties);
-
- // Disable behaviour for the node until the complete node (and its children have been imported)
for (QName disabledBehaviour : disabledBehaviours)
{
behaviourFilter.disableBehaviour(nodeRef, disabledBehaviour);
}
// TODO: Replace this with appropriate rule/action import handling
ruleService.disableRules(nodeRef);
-
+
+ // Report creation
+ reportNodeCreated(assocRef);
+ reportPropertySet(nodeRef, initialProperties);
+ reportPermissionSet(nodeRef, permissions);
+
// return newly created node reference
return nodeRef;
}
diff --git a/source/java/org/alfresco/repo/importer/ImporterComponentTest.java b/source/java/org/alfresco/repo/importer/ImporterComponentTest.java
index 0091ac0a2f..619d626c1a 100644
--- a/source/java/org/alfresco/repo/importer/ImporterComponentTest.java
+++ b/source/java/org/alfresco/repo/importer/ImporterComponentTest.java
@@ -25,6 +25,7 @@ import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.view.ImporterProgress;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
@@ -111,6 +112,11 @@ public class ImporterComponentTest extends BaseSpringTest
{
System.out.println("TestProgress: added aspect " + aspect + " to node ");
}
+
+ public void permissionSet(NodeRef nodeRef, AccessPermission permission)
+ {
+ System.out.println("TestProgress: added permission " + permission.getPermission() + " to node ");
+ }
}
diff --git a/source/java/org/alfresco/repo/importer/view/NodeContext.java b/source/java/org/alfresco/repo/importer/view/NodeContext.java
index 2ab5abf71f..37ce1100e8 100644
--- a/source/java/org/alfresco/repo/importer/view/NodeContext.java
+++ b/source/java/org/alfresco/repo/importer/view/NodeContext.java
@@ -35,6 +35,9 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.AccessStatus;
+import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.namespace.QName;
@@ -57,6 +60,10 @@ public class NodeContext extends ElementContext
private Map nodeProperties = new HashMap();
private Map propertyDatatypes = new HashMap();
+ // permissions
+ private boolean inherit = true;
+ private List accessControlEntries = new ArrayList();
+
/**
* Construct
@@ -148,6 +155,22 @@ public class NodeContext extends ElementContext
this.childName = childName;
}
+ /*
+ * @param inherit determines if node inherits permissions from parent
+ */
+ public void setInheritPermissions(boolean inherit)
+ {
+ this.inherit = inherit;
+ }
+
+ /**
+ * @return true => node inherits permissions from parent
+ */
+ public boolean getInheritPermissions()
+ {
+ return this.inherit;
+ }
+
/**
* Adds a collection property to the node
*
@@ -272,6 +295,32 @@ public class NodeContext extends ElementContext
return nodeAspects.keySet();
}
+ /**
+ * Adds an Access Control Entry
+ *
+ * @param accessStatus
+ * @param authority
+ * @param permission
+ */
+ public void addAccessControlEntry(AccessStatus accessStatus, String authority, String permission)
+ {
+ ACE ace = new ACE();
+ ace.accessStatus = accessStatus;
+ ace.authority = authority;
+ ace.permission = permission;
+ accessControlEntries.add(ace);
+ }
+
+ /**
+ * Gets the Access Control Entries
+ *
+ * @return access control entries
+ */
+ public List getAccessControlEntries()
+ {
+ return accessControlEntries;
+ }
+
/**
* Determine the type of definition (aspect, property, association) from the
* specified name
@@ -377,5 +426,51 @@ public class NodeContext extends ElementContext
return "NodeContext[childName=" + getChildName() + ",type=" + (typeDef == null ? "null" : typeDef.getName()) + ",nodeRef=" + nodeRef +
",aspects=" + nodeAspects.values() + ",parentContext=" + parentContext.toString() + "]";
}
+
+ /**
+ * Access Control Entry
+ */
+ private class ACE implements AccessPermission
+ {
+ private AccessStatus accessStatus;
+ private String authority;
+ private String permission;
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.security.AccessPermission#getPermission()
+ */
+ public String getPermission()
+ {
+ return permission;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.security.AccessPermission#getAccessStatus()
+ */
+ public AccessStatus getAccessStatus()
+ {
+ return accessStatus;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.security.AccessPermission#getAuthority()
+ */
+ public String getAuthority()
+ {
+ return authority;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.security.AccessPermission#getAuthorityType()
+ */
+ public AuthorityType getAuthorityType()
+ {
+ return null;
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/importer/view/ViewParser.java b/source/java/org/alfresco/repo/importer/view/ViewParser.java
index d9b1eaa64f..4da7c2072d 100644
--- a/source/java/org/alfresco/repo/importer/view/ViewParser.java
+++ b/source/java/org/alfresco/repo/importer/view/ViewParser.java
@@ -29,6 +29,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.view.ImporterException;
+import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
@@ -52,12 +53,19 @@ public class ViewParser implements Parser
private static final String VIEW_CHILD_NAME_ATTR = "childName";
private static final String VIEW_DATATYPE_ATTR = "datatype";
private static final String VIEW_ISNULL_ATTR = "isNull";
+ private static final String VIEW_INHERIT_PERMISSIONS_ATTR = "inherit";
+ private static final String VIEW_ACCESS_STATUS_ATTR = "access";
private static final QName VIEW_METADATA = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "metadata");
private static final QName VIEW_VALUE_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "value");
private static final QName VIEW_VALUES_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "values");
private static final QName VIEW_ASPECTS = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "aspects");
private static final QName VIEW_PROPERTIES = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "properties");
private static final QName VIEW_ASSOCIATIONS = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "associations");
+ private static final QName VIEW_ACL = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "acl");
+ private static final QName VIEW_ACE = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "ace");
+ private static final QName VIEW_AUTHORITY = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "authority");
+ private static final QName VIEW_PERMISSION = QName.createQName(NamespaceService.REPOSITORY_VIEW_1_0_URI, "permission");
+
// XML Pull Parser Factory
private XmlPullParserFactory factory;
@@ -170,7 +178,7 @@ public class ViewParser implements Parser
{
contextStack.push(new MetaDataContext(defName, (ElementContext)context));
}
- else if (defName.equals(VIEW_ASPECTS) || defName.equals(VIEW_PROPERTIES) || defName.equals(VIEW_ASSOCIATIONS))
+ else if (defName.equals(VIEW_ASPECTS) || defName.equals(VIEW_PROPERTIES) || defName.equals(VIEW_ASSOCIATIONS) || defName.equals(VIEW_ACL))
{
if (context instanceof NodeItemContext)
{
@@ -182,6 +190,12 @@ public class ViewParser implements Parser
}
NodeContext nodeContext = (NodeContext)context;
contextStack.push(new NodeItemContext(defName, nodeContext));
+
+ // process ACL specific attributes
+ if (defName.equals(VIEW_ACL))
+ {
+ processACL(xpp, contextStack);
+ }
}
else
{
@@ -259,6 +273,10 @@ public class ViewParser implements Parser
}
processStartChildAssoc(xpp, def, contextStack);
}
+ else if (itemName.equals(VIEW_ACL))
+ {
+ processAccessControlEntry(xpp, contextStack);
+ }
}
}
}
@@ -369,6 +387,122 @@ public class ViewParser implements Parser
logger.debug(indentLog("Processed aspect " + aspectDef.getName(), contextStack.size()));
}
+ /**
+ * Process ACL definition
+ *
+ * @param xpp
+ * @param contextStack
+ */
+ private void processACL(XmlPullParser xpp, Stack contextStack)
+ {
+ NodeContext context = peekNodeContext(contextStack);
+
+ String strInherit = xpp.getAttributeValue(NamespaceService.REPOSITORY_VIEW_1_0_URI, VIEW_INHERIT_PERMISSIONS_ATTR);
+ if (strInherit != null)
+ {
+ Boolean inherit = Boolean.valueOf(strInherit);
+ if (!inherit)
+ {
+ context.setInheritPermissions(false);
+ }
+ }
+ }
+
+ /**
+ * Process ACE definition
+ *
+ * @param xpp
+ * @param contextStack
+ * @throws XmlPullParserException
+ * @throws IOException
+ */
+ private void processAccessControlEntry(XmlPullParser xpp, Stack contextStack)
+ throws XmlPullParserException, IOException
+ {
+ NodeContext context = peekNodeContext(contextStack);
+
+ QName defName = getName(xpp);
+ if (!defName.equals(VIEW_ACE))
+ {
+ throw new ImporterException("Expected start element " + VIEW_ACE);
+ }
+
+ // extract Access Status
+ String access = xpp.getAttributeValue(NamespaceService.REPOSITORY_VIEW_1_0_URI, VIEW_ACCESS_STATUS_ATTR);
+ AccessStatus accessStatus = (access == null) ? AccessStatus.ALLOWED : AccessStatus.valueOf(AccessStatus.class, access);
+ if (accessStatus == null)
+ {
+ throw new ImporterException("Permission access status '" + access + "' is not recognised.");
+ }
+
+ // extract authority and permission
+ String authority = null;
+ String permission = null;
+ int eventType = xpp.next();
+ while (eventType != XmlPullParser.END_TAG)
+ {
+ if (eventType == XmlPullParser.START_TAG)
+ {
+ defName = getName(xpp);
+ if (defName.equals(VIEW_AUTHORITY))
+ {
+ eventType = xpp.next();
+ if (eventType != XmlPullParser.TEXT)
+ {
+ throw new ImporterException("Element " + VIEW_AUTHORITY + " must have a value");
+ }
+ authority = xpp.getText();
+ }
+ else if (defName.equals(VIEW_PERMISSION))
+ {
+ eventType = xpp.next();
+ if (eventType != XmlPullParser.TEXT)
+ {
+ throw new ImporterException("Element " + VIEW_PERMISSION + " must have a value");
+ }
+ permission = xpp.getText();
+ }
+ else
+ {
+ throw new ImporterException("Expected start element " + VIEW_AUTHORITY + " or " + VIEW_PERMISSION);
+ }
+
+ eventType = xpp.next();
+ if (eventType != XmlPullParser.END_TAG)
+ {
+ throw new ImporterException("Expected end element " + defName);
+ }
+ QName endDefName = getName(xpp);
+ if (!defName.equals(endDefName))
+ {
+ throw new ImporterException("Expected end element " + defName);
+ }
+ }
+
+ eventType = xpp.next();
+ }
+
+ // validate authority and permission
+ if (authority == null || authority.length() == 0)
+ {
+ throw new ImporterException("Authority must be specified");
+ }
+ if (permission == null || permission.length() == 0)
+ {
+ throw new ImporterException("Permisssion must be specified");
+ }
+
+ // extract end of ace
+ defName = getName(xpp);
+ if (!defName.equals(VIEW_ACE))
+ {
+ throw new ImporterException("Expected end element " + VIEW_ACE);
+ }
+
+ // update node context
+ context.addAccessControlEntry(accessStatus, authority, permission);
+ }
+
/**
* Process property definition
*
diff --git a/source/java/org/alfresco/service/cmr/view/ImporterProgress.java b/source/java/org/alfresco/service/cmr/view/ImporterProgress.java
index e3fd91dd24..8af53bf3ad 100644
--- a/source/java/org/alfresco/service/cmr/view/ImporterProgress.java
+++ b/source/java/org/alfresco/service/cmr/view/ImporterProgress.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.view;
import java.io.Serializable;
import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.namespace.QName;
@@ -57,6 +58,14 @@ public interface ImporterProgress
*/
public void propertySet(NodeRef nodeRef, QName property, Serializable value);
+ /**
+ * Report setting of a permission
+ *
+ * @param nodeRef the node ref
+ * @param permission the permission
+ */
+ public void permissionSet(NodeRef nodeRef, AccessPermission permission);
+
/**
* Report addition of an aspect
*
diff --git a/source/java/org/alfresco/tools/Import.java b/source/java/org/alfresco/tools/Import.java
index a226acb684..58aeb4ac7d 100644
--- a/source/java/org/alfresco/tools/Import.java
+++ b/source/java/org/alfresco/tools/Import.java
@@ -24,6 +24,7 @@ import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.FileImportPackageHandler;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.view.ImportPackageHandler;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.view.ImporterProgress;
@@ -299,6 +300,13 @@ public class Import extends Tool
{
}
+ /* (non-Javadoc)
+ * @see org.alfresco.service.cmr.view.ImporterProgress#permissionSet(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.security.AccessPermission)
+ */
+ public void permissionSet(NodeRef nodeRef, AccessPermission permission)
+ {
+ }
+
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterProgress#aspectAdded(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/