diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml
index f7d2ad3c0e..24ae6c6266 100644
--- a/config/alfresco/avm-services-context.xml
+++ b/config/alfresco/avm-services-context.xml
@@ -149,6 +149,9 @@
+
+
+
diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java
index de8bc9da2f..526cfafe83 100644
--- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java
@@ -21,9 +21,12 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.repo.domain.hibernate.DbAccessControlListImpl;
import org.alfresco.service.namespace.QName;
/**
@@ -328,6 +331,15 @@ public abstract class AVMNodeImpl implements AVMNode, Serializable
}
}
+ protected void copyACLs(AVMNode other)
+ {
+ DbAccessControlList acl = other.getAcl();
+ if (acl != null)
+ {
+ setAcl(acl.getCopy());
+ }
+ }
+
/**
* Set a property on a node. Overwrite it if it exists.
* @param name The name of the property.
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index ce60bb1f53..c26a9e7309 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -26,6 +26,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import org.alfresco.model.ContentModel;
@@ -36,6 +37,8 @@ import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.avm.LayeringDescriptor;
import org.alfresco.service.cmr.avm.VersionDescriptor;
+import org.alfresco.service.cmr.security.AccessPermission;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
/**
@@ -2255,4 +2258,34 @@ public class AVMServiceTest extends AVMServiceTestBase
fail();
}
}
+
+ /**
+ * Test ACLs.
+ */
+ public void testACLs()
+ {
+ try
+ {
+ setupBasicTree();
+ PermissionService perm = (PermissionService)fContext.getBean("PermissionService");
+ perm.setPermission(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"),
+ PermissionService.ADMINISTRATOR_AUTHORITY,
+ PermissionService.ALL_PERMISSIONS,
+ true);
+ fService.createSnapshot("main");
+ fService.getFileOutputStream("main:/a/b/c/foo").close();
+ Set perms =
+ perm.getPermissions(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"));
+ for (AccessPermission permission : perms)
+ {
+ System.out.println(permission);
+ }
+ assertTrue(perms.size() > 0);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
index 4de69afef6..107f14d645 100644
--- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java
@@ -115,6 +115,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other);
copyAspects(other);
+ copyACLs(other);
}
/**
@@ -149,6 +150,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other);
copyAspects(other);
+ copyACLs(other);
}
/**
@@ -173,6 +175,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(dir);
copyAspects(dir);
+ copyACLs(dir);
}
/**
diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
index 88b297278f..db3da7b683 100644
--- a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java
@@ -55,6 +55,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other);
copyAspects(other);
+ copyACLs(other);
}
/**
@@ -89,7 +90,8 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getBasicAttributes(),
getContentData(lPath),
indirect.getProperties(),
- AVMContext.fgInstance.fAVMAspectNameDAO.get(indirect));
+ AVMContext.fgInstance.fAVMAspectNameDAO.get(indirect),
+ indirect.getAcl());
newMe.setAncestor(this);
return newMe;
}
diff --git a/source/java/org/alfresco/repo/avm/OrphanReaper.java b/source/java/org/alfresco/repo/avm/OrphanReaper.java
index bef0793a6c..716f83a972 100644
--- a/source/java/org/alfresco/repo/avm/OrphanReaper.java
+++ b/source/java/org/alfresco/repo/avm/OrphanReaper.java
@@ -20,9 +20,12 @@ package org.alfresco.repo.avm;
import java.util.LinkedList;
import java.util.List;
+import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.service.transaction.TransactionService;
import org.apache.log4j.Logger;
+import org.hibernate.SessionFactory;
+import org.springframework.orm.hibernate3.HibernateTemplate;
/**
* This is the background thread for reaping no longer referenced nodes
@@ -38,6 +41,11 @@ public class OrphanReaper implements Runnable
*/
private TransactionService fTransactionService;
+ /**
+ * The Session Factory
+ */
+ private SessionFactory fSessionFactory;
+
/**
* Inactive base sleep interval.
*/
@@ -130,6 +138,15 @@ public class OrphanReaper implements Runnable
fTransactionService = transactionService;
}
+ /**
+ * Set the hibernate session factory. (For Spring.)
+ * @param sessionFactory
+ */
+ public void setSessionFactory(SessionFactory sessionFactory)
+ {
+ fSessionFactory = sessionFactory;
+ }
+
/**
* Set the maximum size of the queue of purgeable nodes.
* @param queueLength The max length.
@@ -282,6 +299,14 @@ public class OrphanReaper implements Runnable
AVMContext.fgInstance.fAVMNodePropertyDAO.deleteAll(node);
// Get rid of all aspects belonging to this node.
AVMContext.fgInstance.fAVMAspectNameDAO.delete(node);
+ // Get rid of ACL.
+ DbAccessControlList acl = node.getAcl();
+ node.setAcl(null);
+ if (acl != null)
+ {
+ acl.deleteEntries();
+ (new HibernateTemplate(fSessionFactory)).delete(acl);
+ }
// Extra work for directories.
if (node.getType() == AVMNodeType.PLAIN_DIRECTORY ||
node.getType() == AVMNodeType.LAYERED_DIRECTORY)
diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java
index f034bfdcde..13b16591f9 100644
--- a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java
@@ -74,6 +74,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other);
copyAspects(other);
+ copyACLs(other);
}
/**
diff --git a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
index d7545c69f4..f8442ff1b9 100644
--- a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
+++ b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java
@@ -20,6 +20,7 @@ package org.alfresco.repo.avm;
import java.util.List;
import java.util.Map;
+import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -92,6 +93,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other);
copyAspects(other);
+ copyACLs(other);
}
/**
@@ -105,7 +107,8 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
BasicAttributes attrs,
ContentData content,
Map props,
- List aspects)
+ List aspects,
+ DbAccessControlList acl)
{
super(store.getAVMRepository().issueID(), store);
setContentData(content);
@@ -121,6 +124,10 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
newName.setNode(this);
AVMContext.fgInstance.fAVMAspectNameDAO.save(newName);
}
+ if (acl != null)
+ {
+ setAcl(acl.getCopy());
+ }
}
/**
diff --git a/source/java/org/alfresco/repo/domain/DbAccessControlList.java b/source/java/org/alfresco/repo/domain/DbAccessControlList.java
index c815337253..327ed47347 100644
--- a/source/java/org/alfresco/repo/domain/DbAccessControlList.java
+++ b/source/java/org/alfresco/repo/domain/DbAccessControlList.java
@@ -74,4 +74,10 @@ public interface DbAccessControlList
* @return Returns the new entry
*/
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
+
+ /**
+ * Make a copy of this ACL (persistently)
+ * @return The copy.
+ */
+ public DbAccessControlList getCopy();
}
diff --git a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
index 71cd7305ec..7291d9ce99 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
@@ -78,7 +78,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
public void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl)
{
Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
- int version = (Integer)avmVersionPath[1];
+ int version = (Integer)avmVersionPath[0];
if (version >= 0)
{
throw new InvalidNodeRefException("Read Only Node.", nodeRef);
diff --git a/source/java/org/alfresco/repo/domain/hibernate/DbAccessControlListImpl.java b/source/java/org/alfresco/repo/domain/hibernate/DbAccessControlListImpl.java
index 3785861274..7139d6a8bc 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/DbAccessControlListImpl.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/DbAccessControlListImpl.java
@@ -231,4 +231,20 @@ public class DbAccessControlListImpl extends LifecycleAdapter
// done
return accessControlEntry;
}
+
+ /**
+ * Make a copy of this ACL.
+ * @return The copy.
+ */
+ public DbAccessControlList getCopy()
+ {
+ DbAccessControlList newAcl =
+ new DbAccessControlListImpl();
+ getSession().save(newAcl);
+ for (DbAccessControlEntry entry : entries)
+ {
+ newAcl.newEntry(entry.getPermission(), entry.getAuthority(), entry.isAllowed());
+ }
+ return newAcl;
+ }
}
diff --git a/source/java/org/alfresco/repo/domain/hibernate/NodeAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/NodeAccessControlListDAO.java
index 4cfcf87d8b..12720cb699 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/NodeAccessControlListDAO.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/NodeAccessControlListDAO.java
@@ -77,12 +77,6 @@ public class NodeAccessControlListDAO extends HibernateDaoSupport implements Acc
{
throw new InvalidNodeRefException(nodeRef);
}
- DbAccessControlList oldAcl = node.getAccessControlList();
- if (oldAcl != null)
- {
- node.setAccessControlList(null);
- this.getHibernateTemplate().delete(oldAcl);
- }
node.setAccessControlList(acl);
}
}
diff --git a/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java
index 47ffabb5cf..8e2a68ccfb 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/PermissionsDaoComponentImpl.java
@@ -38,7 +38,6 @@ import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;