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;