More touch ups to AVM permissions stuff. ACLs are properly copied on write.

OrphanReaper cleans up ACLs.  Tests of same.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3710 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-09-06 20:53:38 +00:00
parent 920c487867
commit 17284e4dae
13 changed files with 111 additions and 10 deletions

View File

@@ -149,6 +149,9 @@
<property name="transactionService"> <property name="transactionService">
<ref bean="transactionComponent"/> <ref bean="transactionComponent"/>
</property> </property>
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean> </bean>
<bean id="avmRepository" class="org.alfresco.repo.avm.AVMRepository"> <bean id="avmRepository" class="org.alfresco.repo.avm.AVMRepository">

View File

@@ -21,9 +21,12 @@ import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; 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.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.hibernate.DbAccessControlListImpl;
import org.alfresco.service.namespace.QName; 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. * Set a property on a node. Overwrite it if it exists.
* @param name The name of the property. * @param name The name of the property.

View File

@@ -26,6 +26,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import org.alfresco.model.ContentModel; 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.AVMStoreDescriptor;
import org.alfresco.service.cmr.avm.LayeringDescriptor; import org.alfresco.service.cmr.avm.LayeringDescriptor;
import org.alfresco.service.cmr.avm.VersionDescriptor; 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; import org.alfresco.service.namespace.QName;
/** /**
@@ -2255,4 +2258,34 @@ public class AVMServiceTest extends AVMServiceTestBase
fail(); 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<AccessPermission> 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();
}
}
} }

View File

@@ -115,6 +115,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other); copyProperties(other);
copyAspects(other); copyAspects(other);
copyACLs(other);
} }
/** /**
@@ -149,6 +150,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other); copyProperties(other);
copyAspects(other); copyAspects(other);
copyACLs(other);
} }
/** /**
@@ -173,6 +175,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(dir); copyProperties(dir);
copyAspects(dir); copyAspects(dir);
copyACLs(dir);
} }
/** /**

View File

@@ -55,6 +55,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other); copyProperties(other);
copyAspects(other); copyAspects(other);
copyACLs(other);
} }
/** /**
@@ -89,7 +90,8 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
getBasicAttributes(), getBasicAttributes(),
getContentData(lPath), getContentData(lPath),
indirect.getProperties(), indirect.getProperties(),
AVMContext.fgInstance.fAVMAspectNameDAO.get(indirect)); AVMContext.fgInstance.fAVMAspectNameDAO.get(indirect),
indirect.getAcl());
newMe.setAncestor(this); newMe.setAncestor(this);
return newMe; return newMe;
} }

View File

@@ -20,9 +20,12 @@ package org.alfresco.repo.avm;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.transaction.TransactionUtil; import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.apache.log4j.Logger; 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 * This is the background thread for reaping no longer referenced nodes
@@ -38,6 +41,11 @@ public class OrphanReaper implements Runnable
*/ */
private TransactionService fTransactionService; private TransactionService fTransactionService;
/**
* The Session Factory
*/
private SessionFactory fSessionFactory;
/** /**
* Inactive base sleep interval. * Inactive base sleep interval.
*/ */
@@ -130,6 +138,15 @@ public class OrphanReaper implements Runnable
fTransactionService = transactionService; 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. * Set the maximum size of the queue of purgeable nodes.
* @param queueLength The max length. * @param queueLength The max length.
@@ -282,6 +299,14 @@ public class OrphanReaper implements Runnable
AVMContext.fgInstance.fAVMNodePropertyDAO.deleteAll(node); AVMContext.fgInstance.fAVMNodePropertyDAO.deleteAll(node);
// Get rid of all aspects belonging to this node. // Get rid of all aspects belonging to this node.
AVMContext.fgInstance.fAVMAspectNameDAO.delete(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. // Extra work for directories.
if (node.getType() == AVMNodeType.PLAIN_DIRECTORY || if (node.getType() == AVMNodeType.PLAIN_DIRECTORY ||
node.getType() == AVMNodeType.LAYERED_DIRECTORY) node.getType() == AVMNodeType.LAYERED_DIRECTORY)

View File

@@ -74,6 +74,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other); copyProperties(other);
copyAspects(other); copyAspects(other);
copyACLs(other);
} }
/** /**

View File

@@ -20,6 +20,7 @@ package org.alfresco.repo.avm;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.cmr.avm.AVMException; import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
@@ -92,6 +93,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
AVMContext.fgInstance.fAVMNodeDAO.flush(); AVMContext.fgInstance.fAVMNodeDAO.flush();
copyProperties(other); copyProperties(other);
copyAspects(other); copyAspects(other);
copyACLs(other);
} }
/** /**
@@ -105,7 +107,8 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
BasicAttributes attrs, BasicAttributes attrs,
ContentData content, ContentData content,
Map<QName, PropertyValue> props, Map<QName, PropertyValue> props,
List<AVMAspectName> aspects) List<AVMAspectName> aspects,
DbAccessControlList acl)
{ {
super(store.getAVMRepository().issueID(), store); super(store.getAVMRepository().issueID(), store);
setContentData(content); setContentData(content);
@@ -121,6 +124,10 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
newName.setNode(this); newName.setNode(this);
AVMContext.fgInstance.fAVMAspectNameDAO.save(newName); AVMContext.fgInstance.fAVMAspectNameDAO.save(newName);
} }
if (acl != null)
{
setAcl(acl.getCopy());
}
} }
/** /**

View File

@@ -74,4 +74,10 @@ public interface DbAccessControlList
* @return Returns the new entry * @return Returns the new entry
*/ */
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed); public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
/**
* Make a copy of this ACL (persistently)
* @return The copy.
*/
public DbAccessControlList getCopy();
} }

View File

@@ -78,7 +78,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
public void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl) public void setAccessControlList(NodeRef nodeRef, DbAccessControlList acl)
{ {
Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); Object [] avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
int version = (Integer)avmVersionPath[1]; int version = (Integer)avmVersionPath[0];
if (version >= 0) if (version >= 0)
{ {
throw new InvalidNodeRefException("Read Only Node.", nodeRef); throw new InvalidNodeRefException("Read Only Node.", nodeRef);

View File

@@ -231,4 +231,20 @@ public class DbAccessControlListImpl extends LifecycleAdapter
// done // done
return accessControlEntry; 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;
}
} }

View File

@@ -77,12 +77,6 @@ public class NodeAccessControlListDAO extends HibernateDaoSupport implements Acc
{ {
throw new InvalidNodeRefException(nodeRef); throw new InvalidNodeRefException(nodeRef);
} }
DbAccessControlList oldAcl = node.getAccessControlList();
if (oldAcl != null)
{
node.setAccessControlList(null);
this.getHibernateTemplate().delete(oldAcl);
}
node.setAccessControlList(acl); node.setAccessControlList(acl);
} }
} }

View File

@@ -38,7 +38,6 @@ import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.repo.transaction.TransactionalDao; import org.alfresco.repo.transaction.TransactionalDao;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; 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.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;