RM-2130 (Check classification after method execution, filtering results where appropriate)

* Initial (early) commit to get feedback from the review
 * The "check" method will be changed later

+review RM @rwetherall

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/ENFORCE@105923 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Tuna Aksoy
2015-06-11 09:37:24 +00:00
parent bff94ee863
commit aa746dd474
6 changed files with 402 additions and 16 deletions

View File

@@ -1,11 +1,11 @@
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- Classified content model bootstrap -->
@@ -32,16 +32,40 @@
</list>
</property>
</bean>
<!-- Classification Method Interceptor -->
<bean id="classificationMethodInterceptor"
<bean id="classificationMethodInterceptor"
class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.ClassificationMethodInterceptor">
</bean>
<bean id="classificationMethodInterceptorPostProcessor"
<bean id="classificationMethodInterceptorPostProcessor"
class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.ClassificationMethodInterceptorPostProcessor" />
<bean id="basePostMethodInvocationProcessor"
abstract="true"
init-method="register">
<property name="classificationMethodInterceptor" ref="classificationMethodInterceptor" />
<property name="nodeService" ref="NodeService" />
<property name="dictionaryService" ref="DictionaryService" />
<property name="contentClassificationService" ref="ContentClassificationService" />
</bean>
<bean id="nodeRefPostMethodInvocationProcessor"
parent="basePostMethodInvocationProcessor"
class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.NodeRefPostMethodInvocationProcessor">
</bean>
<bean id="childAssociationRefPostMethodInvocationProcessor"
parent="basePostMethodInvocationProcessor"
class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.ChildAssociationRefPostMethodInvocationProcessor">
</bean>
<bean id="associationRefPostMethodInvocationProcessor"
parent="basePostMethodInvocationProcessor"
class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.AssociationRefPostMethodInvocationProcessor">
</bean>
<!-- Classification service DAO -->
<bean id="classificationServiceDAO" class="org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceDAO">

View File

@@ -18,13 +18,16 @@
*/
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor;
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
import static org.codehaus.plexus.util.StringUtils.isNotBlank;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceBootstrap;
import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor;
import org.alfresco.module.org_alfresco_module_rm.util.AlfrescoTransactionSupport;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
@@ -37,6 +40,7 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.GUID;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -49,6 +53,12 @@ import org.springframework.context.ApplicationContextAware;
*/
public class ClassificationMethodInterceptor implements MethodInterceptor, ApplicationContextAware
{
/** Logger */
private static Logger LOG = Logger.getLogger(ClassificationMethodInterceptor.class);
/** Post method invocation processors */
private Map<Class<?>, BasePostMethodInvocationProcessor> processors = new HashMap<Class<?>, BasePostMethodInvocationProcessor>();
private static final String KEY_PROCESSING = GUID.generate();
/** application context */
@@ -72,7 +82,7 @@ public class ClassificationMethodInterceptor implements MethodInterceptor, Appli
/**
* @return {@link ContentClassificationService} content classification service
*/
protected ContentClassificationService getContentClassificaitonService()
protected ContentClassificationService getContentClassificationService()
{
return (ContentClassificationService)applicationContext.getBean("contentClassificationService");
}
@@ -102,6 +112,16 @@ public class ClassificationMethodInterceptor implements MethodInterceptor, Appli
return (DictionaryService)applicationContext.getBean("dictionaryService");
}
/**
* Registers the post method invocation processors
*
* @param object The object to register
*/
public void register(BasePostMethodInvocationProcessor object)
{
processors.put(object.getClassName(), object);
}
/**
* Check that the current user is cleared to see the items passed as parameters to the current
* method invocation.
@@ -176,8 +196,8 @@ public class ClassificationMethodInterceptor implements MethodInterceptor, Appli
private void checkNode(NodeRef testNodeRef)
{
if (getNodeService().exists(testNodeRef) &&
getDictionaryService().isSubClass(getNodeService().getType(testNodeRef), ContentModel.TYPE_CONTENT) &&
!getContentClassificaitonService().hasClearance(testNodeRef))
getDictionaryService().isSubClass(getNodeService().getType(testNodeRef), TYPE_CONTENT) &&
!getContentClassificationService().hasClearance(testNodeRef))
{
// throw exception
throw new AccessDeniedException("You do not have clearance!");
@@ -192,19 +212,28 @@ public class ClassificationMethodInterceptor implements MethodInterceptor, Appli
{
boolean isValidUser = validUser();
// pre method invocation check
if (isValidUser)
{
// pre method invocation check
checkClassification(invocation);
}
// method proceed
Object result = invocation.proceed();
if (isValidUser)
// post method invocation processing
if (isValidUser && result != null)
{
// post method invocation processing
// TODO
Class<? extends Object> clazz = result.getClass();
BasePostMethodInvocationProcessor processor = processors.get(clazz);
if (processor != null)
{
processor.process(result);
}
else
{
LOG.warn("No post method invocation processor found for '" + clazz + "'.");
}
}
return result;

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import static org.alfresco.util.ParameterCheck.mandatory;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* AssociationRef Post Method Invocation Processor
*
* @author Tuna Aksoy
* @since 3.0
*/
public class AssociationRefPostMethodInvocationProcessor extends BasePostMethodInvocationProcessor
{
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#getClassName()
*/
@Override
public Class<AssociationRef> getClassName()
{
return AssociationRef.class;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/
@Override
public <T> T process(T object)
{
mandatory("object", object);
AssociationRef associationRef = ((AssociationRef) object);
NodeRef sourceRef = associationRef.getSourceRef();
check(sourceRef);
NodeRef targetRef = associationRef.getTargetRef();
check(targetRef);
return object;
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.ClassificationMethodInterceptor;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
/**
* Base class for post method invocation processors
*
* @author Tuna Aksoy
* @since 3.0
*/
public abstract class BasePostMethodInvocationProcessor
{
/** Classification method interceptor */
private ClassificationMethodInterceptor classificationMethodInterceptor;
/** Node service */
private NodeService nodeService;
/** Dictionary service */
private DictionaryService dictionaryService;
/** Content classification service */
private ContentClassificationService contentClassificationService;
/**
* @return the classificationMethodInterceptor
*/
protected ClassificationMethodInterceptor getClassificationMethodInterceptor()
{
return this.classificationMethodInterceptor;
}
/**
* @return the nodeService
*/
protected NodeService getNodeService()
{
return this.nodeService;
}
/**
* @return the dictionaryService
*/
protected DictionaryService getDictionaryService()
{
return this.dictionaryService;
}
/**
* @return the contentClassificationService
*/
protected ContentClassificationService getContentClassificationService()
{
return this.contentClassificationService;
}
/**
* @param classificationMethodInterceptor the classificationMethodInterceptor to set
*/
public void setClassificationMethodInterceptor(ClassificationMethodInterceptor classificationMethodInterceptor)
{
this.classificationMethodInterceptor = classificationMethodInterceptor;
}
/**
* @param nodeService the nodeService to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param dictionaryService the dictionaryService to set
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* @param contentClassificationService the contentClassificationService to set
*/
public void setContentClassificationService(ContentClassificationService contentClassificationService)
{
this.contentClassificationService = contentClassificationService;
}
/**
* Performs checks on the given object and throws exception if not all checks pass
*
* @param object The object to check
* @return The given object
*/
public abstract <T extends Object> T process(T object);
/**
* Gets the class name
*
* @return The class name
*/
public abstract Class<?> getClassName();
/**
* Registers the post method invocation processors
*/
public void register()
{
getClassificationMethodInterceptor().register(this);
}
/**
* Performs checks on the given node:
*
* <ul>
* <li>Does the node exist</li>
* <li>Is it a content</li>
* <li>Is the logged in user cleared to see the it.</li>
* </ul>
*
* @param nodeRef Node reference
*/
protected void check(NodeRef nodeRef)
{
if (getNodeService().exists(nodeRef) &&
getDictionaryService().isSubClass(getNodeService().getType(nodeRef), ContentModel.TYPE_CONTENT) &&
!getContentClassificationService().hasClearance(nodeRef))
{
// throw exception
throw new AccessDeniedException("You do not have clearance!");
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import static org.alfresco.util.ParameterCheck.mandatory;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* ChildAssociationRef Post Method Invocation Processor
*
* @author Tuna Aksoy
* @since 3.0
*/
public class ChildAssociationRefPostMethodInvocationProcessor extends BasePostMethodInvocationProcessor
{
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#getClassName()
*/
@Override
public Class<ChildAssociationRef> getClassName()
{
return ChildAssociationRef.class;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/
@Override
public <T> T process(T object)
{
mandatory("object", object);
ChildAssociationRef childAssociationRef = ((ChildAssociationRef) object);
NodeRef childRef = childAssociationRef.getChildRef();
check(childRef);
NodeRef parentRef = childAssociationRef.getParentRef();
check(parentRef);
return object;
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
import static org.alfresco.util.ParameterCheck.mandatory;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* NodeRef Post Method Invocation Processor
*
* @author Tuna Aksoy
* @since 3.0
*/
public class NodeRefPostMethodInvocationProcessor extends BasePostMethodInvocationProcessor
{
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#getClassName()
*/
@Override
public Class<NodeRef> getClassName()
{
return NodeRef.class;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
*/
@Override
public <T> T process(T object)
{
mandatory("object", object);
check(((NodeRef) object));
return object;
}
}