mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
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:
@@ -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">
|
||||||
|
@@ -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.
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user