mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged DEV to HEAD (4.2)
54623: ALF-19234: An Editor (probably also Collaborator) can take ownership of a document (probably also folders) - The new "ACL_ITEM" cad was implemented. Now we check TakeOwnership permission if cm:owner property is going to change when NodeService.addProperties(), NodeService.addAspect(), NodeService.setProperties(), NodeService.setProperty() methods were invoked. Also testTakeOwnershipPermission test was added to check if we can take document ownership through NodeService without appropriate permissions. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@55167 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -18,11 +18,13 @@
|
||||
*/
|
||||
package org.alfresco.repo.security.permissions.impl.acegi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
@@ -31,6 +33,7 @@ import net.sf.acegisecurity.ConfigAttribute;
|
||||
import net.sf.acegisecurity.ConfigAttributeDefinition;
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
@@ -40,6 +43,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.OwnableService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -57,7 +61,9 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
private static Log log = LogFactory.getLog(ACLEntryVoter.class);
|
||||
|
||||
private static final String ACL_NODE = "ACL_NODE";
|
||||
|
||||
|
||||
private static final String ACL_ITEM = "ACL_ITEM";
|
||||
|
||||
private static final String ACL_PRI_CHILD_ASSOC_ON_CHILD = "ACL_PRI_CHILD_ASSOC_ON_CHILD";
|
||||
|
||||
private static final String ACL_PARENT = "ACL_PARENT";
|
||||
@@ -74,6 +80,8 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
|
||||
private NodeService nodeService;
|
||||
|
||||
private OwnableService ownableService;
|
||||
|
||||
private AuthorityService authorityService;
|
||||
|
||||
private Set<QName> abstainForClassQNames = new HashSet<QName>();
|
||||
@@ -137,6 +145,15 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
return nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ownable service
|
||||
* @return the ownable service
|
||||
*/
|
||||
public OwnableService getOwnableService()
|
||||
{
|
||||
return ownableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node service
|
||||
* @param nodeService
|
||||
@@ -146,6 +163,15 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ownable service
|
||||
* @param nodeService
|
||||
*/
|
||||
public void setOwnableService(OwnableService ownableService)
|
||||
{
|
||||
this.ownableService = ownableService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication service
|
||||
* @param authenticationService
|
||||
@@ -207,6 +233,7 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
{
|
||||
if ((attribute.getAttribute() != null)
|
||||
&& (attribute.getAttribute().startsWith(ACL_NODE)
|
||||
|| attribute.getAttribute().startsWith(ACL_ITEM)
|
||||
|| attribute.getAttribute().startsWith(ACL_PRI_CHILD_ASSOC_ON_CHILD)
|
||||
|| attribute.getAttribute().startsWith(ACL_PARENT)
|
||||
|| attribute.getAttribute().equals(ACL_ALLOW)
|
||||
@@ -416,6 +443,65 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef");
|
||||
}
|
||||
}
|
||||
else if (cad.typeString.equals(ACL_ITEM))
|
||||
{
|
||||
if (NodeRef.class.isAssignableFrom(params[cad.parameter[0]]))
|
||||
{
|
||||
if (Map.class.isAssignableFrom(params[1]) || Map.class.isAssignableFrom(params[2]))
|
||||
{
|
||||
Map<QName, Serializable> properties = (Map<QName, Serializable>) (Map.class.isAssignableFrom(params[1]) ? getArgument(invocation, 1) : getArgument(invocation, 2));
|
||||
if (properties != null && properties.containsKey(ContentModel.PROP_OWNER))
|
||||
{
|
||||
testNodeRef = getArgument(invocation, cad.parameter[0]);
|
||||
|
||||
boolean isChanged = !properties.get(ContentModel.PROP_OWNER).toString().equals(ownableService.getOwner(testNodeRef));
|
||||
|
||||
if (!isChanged)
|
||||
{
|
||||
testNodeRef = null;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
if (nodeService.exists(testNodeRef))
|
||||
{
|
||||
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("\tPermission test on non-existing node " + testNodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (QName.class.isAssignableFrom(params[1]) && params[2] != null)
|
||||
{
|
||||
testNodeRef = getArgument(invocation, cad.parameter[0]);
|
||||
boolean isChanged = !getArgument(invocation, 2).toString().equals(ownableService.getOwner(testNodeRef));
|
||||
|
||||
if (!isChanged)
|
||||
{
|
||||
testNodeRef = null;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
if (nodeService.exists(testNodeRef))
|
||||
{
|
||||
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("\tPermission test on non-existing node " + testNodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ACLEntryVoterException("The specified parameter is not a Item");
|
||||
}
|
||||
}
|
||||
else if (cad.typeString.equals(ACL_PARENT))
|
||||
{
|
||||
// There is no point having parent permissions for store
|
||||
@@ -573,14 +659,14 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
}
|
||||
typeString = st.nextToken();
|
||||
|
||||
if (!(typeString.equals(ACL_NODE) || typeString.equals(ACL_PRI_CHILD_ASSOC_ON_CHILD)
|
||||
if (!(typeString.equals(ACL_NODE) || typeString.equals(ACL_ITEM) || typeString.equals(ACL_PRI_CHILD_ASSOC_ON_CHILD)
|
||||
|| typeString.equals(ACL_PARENT) || typeString.equals(ACL_ALLOW) || typeString.equals(ACL_METHOD) || typeString
|
||||
.equals(ACL_DENY)))
|
||||
{
|
||||
throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_PARENT or ACL_ALLOW");
|
||||
throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_ITEM, ACL_PARENT or ACL_ALLOW");
|
||||
}
|
||||
|
||||
if (typeString.equals(ACL_NODE) || typeString.equals(ACL_PRI_CHILD_ASSOC_ON_CHILD)
|
||||
if (typeString.equals(ACL_NODE) || typeString.equals(ACL_ITEM) || typeString.equals(ACL_PRI_CHILD_ASSOC_ON_CHILD)
|
||||
|| typeString.equals(ACL_PARENT))
|
||||
{
|
||||
int count = st.countTokens();
|
||||
|
Reference in New Issue
Block a user