mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-2130 (Check classification after method execution, filtering results where appropriate)
+review RM-94 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/ENFORCE@106639 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -88,7 +88,7 @@ public class SecurityClearanceServiceImpl extends ServiceBaseImpl implements Sec
|
||||
*/
|
||||
private SecurityClearance getUserSecurityClearance(final String userName)
|
||||
{
|
||||
final NodeRef personNode = personService.getPerson(userName, true);
|
||||
final NodeRef personNode = personService.getPerson(userName, false);
|
||||
final PersonInfo personInfo = personService.getPerson(personNode);
|
||||
|
||||
ClearanceLevel clearanceLevel = ClearanceLevelManager.NO_CLEARANCE;
|
||||
|
@@ -1,246 +1,129 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
|
||||
import static org.codehaus.plexus.util.StringUtils.isNotBlank;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.alfresco.jlan.server.filesys.AccessDeniedException;
|
||||
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.classification.interceptor.processor.PostMethodInvocationProcessorRegistry;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.AlfrescoTransactionSupport;
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Classification method interceptor
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ClassificationMethodInterceptor implements MethodInterceptor, ApplicationContextAware
|
||||
{
|
||||
/** Logger */
|
||||
private static Logger LOG = Logger.getLogger(ClassificationMethodInterceptor.class);
|
||||
|
||||
private static final String KEY_PROCESSING = GUID.generate();
|
||||
|
||||
/** application context */
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* @param applicationContext application context
|
||||
* @throws BeansException
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
protected AuthenticationUtil getAuthenticationUtil()
|
||||
{
|
||||
return (AuthenticationUtil)applicationContext.getBean("rm.authenticationUtil");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link ContentClassificationService} content classification service
|
||||
*/
|
||||
protected ContentClassificationService getContentClassificationService()
|
||||
{
|
||||
return (ContentClassificationService)applicationContext.getBean("contentClassificationService");
|
||||
}
|
||||
|
||||
protected AlfrescoTransactionSupport getAlfrescoTransactionSupport()
|
||||
{
|
||||
return (AlfrescoTransactionSupport)applicationContext.getBean("rm.alfrescoTransactionSupport");
|
||||
}
|
||||
|
||||
protected RetryingTransactionHelper getRetryingTransactionHelper()
|
||||
{
|
||||
return ((TransactionService)applicationContext.getBean("transactionService")).getRetryingTransactionHelper();
|
||||
}
|
||||
|
||||
protected ClassificationServiceBootstrap getClassificationServiceBootstrap()
|
||||
{
|
||||
return (ClassificationServiceBootstrap)applicationContext.getBean("classificationServiceBootstrap");
|
||||
}
|
||||
|
||||
protected NodeService getNodeService()
|
||||
{
|
||||
return (NodeService)applicationContext.getBean("dbNodeService");
|
||||
}
|
||||
|
||||
protected DictionaryService getDictionaryService()
|
||||
{
|
||||
return (DictionaryService)applicationContext.getBean("dictionaryService");
|
||||
}
|
||||
|
||||
protected PostMethodInvocationProcessorRegistry getPostMethodInvocationProcessorRegistry()
|
||||
{
|
||||
return (PostMethodInvocationProcessorRegistry)applicationContext.getBean("postMethodInvocationProcessorRegistry");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the current user is cleared to see the items passed as parameters to the current
|
||||
* method invocation.
|
||||
*
|
||||
* @param invocation method invocation
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public NodeRef checkClassification(final MethodInvocation invocation)
|
||||
{
|
||||
// do in transaction
|
||||
return getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
||||
{
|
||||
public NodeRef execute() throws Throwable
|
||||
{
|
||||
NodeRef result = null;
|
||||
|
||||
// ensure classification service has been bootstrapped
|
||||
if (getClassificationServiceBootstrap().isInitialised())
|
||||
{
|
||||
// check that we are not already processing a classification check
|
||||
Object value = getAlfrescoTransactionSupport().getResource(KEY_PROCESSING);
|
||||
if (value == null)
|
||||
{
|
||||
Method method = invocation.getMethod();
|
||||
Class[] params = method.getParameterTypes();
|
||||
|
||||
int position = 0;
|
||||
for (Class param : params)
|
||||
{
|
||||
// if the param is a node reference
|
||||
if (NodeRef.class.isAssignableFrom(param))
|
||||
{
|
||||
// mark the transaction as processing a classification check
|
||||
getAlfrescoTransactionSupport().bindResource(KEY_PROCESSING, Boolean.TRUE);
|
||||
try
|
||||
{
|
||||
// get the value of the parameter
|
||||
NodeRef testNodeRef = (NodeRef) invocation.getArguments()[position];
|
||||
|
||||
// if node exists then see if the current user has clearance
|
||||
result = checkNode(testNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// clear the transaction as processed a classification check
|
||||
getAlfrescoTransactionSupport().unbindResource(KEY_PROCESSING);
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
private boolean isUserValid()
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
// check that we have an authenticated user and that they aren't "system"
|
||||
if (isNotBlank(getAuthenticationUtil().getFullyAuthenticatedUser()) &&
|
||||
!getAuthenticationUtil().isRunAsUserTheSystemUser())
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeRef checkNode(NodeRef testNodeRef) throws AccessDeniedException
|
||||
{
|
||||
NodeRef result = testNodeRef;
|
||||
|
||||
if (getNodeService().exists(testNodeRef) &&
|
||||
getDictionaryService().isSubClass(getNodeService().getType(testNodeRef), TYPE_CONTENT) &&
|
||||
!getContentClassificationService().hasClearance(testNodeRef))
|
||||
{
|
||||
// FIXME
|
||||
result = null;
|
||||
//throw new AccessDeniedException("You do not have clearance!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable
|
||||
{
|
||||
// FIXME
|
||||
//NodeRef preInvocation = null;
|
||||
Object postInvocation = null;
|
||||
|
||||
boolean isUserValid = isUserValid();
|
||||
|
||||
// pre method invocation check
|
||||
if (isUserValid)
|
||||
{
|
||||
// FIXME
|
||||
//preInvocation = checkClassification(invocation);
|
||||
//checkClassification(invocation);
|
||||
}
|
||||
|
||||
// method proceed
|
||||
postInvocation = invocation.proceed();
|
||||
|
||||
// post method invocation processing
|
||||
if (isUserValid && postInvocation != null)
|
||||
{
|
||||
Class<? extends Object> clazz = postInvocation.getClass();
|
||||
BasePostMethodInvocationProcessor processor = getPostMethodInvocationProcessorRegistry().getProcessor(clazz);
|
||||
|
||||
if (processor != null)
|
||||
{
|
||||
postInvocation = processor.process(postInvocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("No post method invocation processor found for '" + clazz + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
return postInvocation;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.alfresco.repo.security.authentication.AuthenticationUtil.getFullyAuthenticatedUser;
|
||||
import static org.alfresco.repo.security.authentication.AuthenticationUtil.isRunAsUserTheSystemUser;
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.PostMethodInvocationProcessor;
|
||||
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.PreMethodInvocationProcessor;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
/**
|
||||
* Classification method interceptor
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @author Tuna Aksoy
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ClassificationMethodInterceptor implements MethodInterceptor
|
||||
{
|
||||
/** Pre method invocation processor */
|
||||
private PreMethodInvocationProcessor preMethodInvocationProcessor;
|
||||
|
||||
/** Post method invocation processor */
|
||||
private PostMethodInvocationProcessor postMethodInvocationProcessor;
|
||||
|
||||
/**
|
||||
* @return the preMethodInvocationProcessor
|
||||
*/
|
||||
protected PreMethodInvocationProcessor getPreMethodInvocationProcessor()
|
||||
{
|
||||
return this.preMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the postMethodInvocationProcessor
|
||||
*/
|
||||
protected PostMethodInvocationProcessor getPostMethodInvocationProcessor()
|
||||
{
|
||||
return this.postMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param postMethodInvocationProcessor the postMethodInvocationProcessor to set
|
||||
*/
|
||||
public void setPostMethodInvocationProcessor(PostMethodInvocationProcessor postMethodInvocationProcessor)
|
||||
{
|
||||
this.postMethodInvocationProcessor = postMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param preMethodInvocationProcessor the preMethodInvocationProcessor to set
|
||||
*/
|
||||
public void setPreMethodInvocationProcessor(PreMethodInvocationProcessor preMethodInvocationProcessor)
|
||||
{
|
||||
this.preMethodInvocationProcessor = preMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable
|
||||
{
|
||||
mandatory("invocation", invocation);
|
||||
|
||||
Object result = null;
|
||||
|
||||
boolean canProceed = true;
|
||||
boolean isUserValid = isUserValid();
|
||||
|
||||
if (isUserValid)
|
||||
{
|
||||
//FIXME!!!
|
||||
// Pre method invocation processing
|
||||
//canProceed = getPreMethodInvocationProcessor().process(invocation);
|
||||
}
|
||||
|
||||
if (canProceed)
|
||||
{
|
||||
// Method invocation
|
||||
result = invocation.proceed();
|
||||
|
||||
// Post method invocation processing
|
||||
if (isUserValid && result != null)
|
||||
{
|
||||
result = getPostMethodInvocationProcessor().process(result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we have an authenticated user and that they aren't "System"
|
||||
*
|
||||
* @return <code>true</code> if we have an authenticated user and that they aren't "System", <code>false</code> otherwise.
|
||||
*/
|
||||
private boolean isUserValid()
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (isNotBlank(getFullyAuthenticatedUser()) && !isRunAsUserTheSystemUser())
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -32,17 +32,17 @@ import org.springframework.beans.factory.support.ManagedList;
|
||||
* <p>
|
||||
* Bean factory post processor that inspects available beans and adds the classification method interceptor
|
||||
* to all public services.
|
||||
*
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 3.0.a
|
||||
*/
|
||||
public class ClassificationMethodInterceptorPostProcessor implements BeanFactoryPostProcessor
|
||||
{
|
||||
private static final String PROP_INTERCEPTOR_NAMES = "interceptorNames";
|
||||
private static final String TYPE_PROXY_FACTORY_BEAN = "ProxyFactoryBean";
|
||||
private static final String TYPE_PROXY_FACTORY_BEAN = "ProxyFactoryBean";
|
||||
private static final String POSTFIX_SERVICE = "Service";
|
||||
private static final String BEAN_NAME_CLASSIFICATION_METHOD_INTERCEPTOR = "classificationMethodInterceptor";
|
||||
|
||||
|
||||
/**
|
||||
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
|
||||
*/
|
||||
@@ -56,27 +56,27 @@ public class ClassificationMethodInterceptorPostProcessor implements BeanFactory
|
||||
{
|
||||
// get bean definition
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(bean);
|
||||
|
||||
|
||||
// only modify proxy factory beans that follow the public service naming postfix convention
|
||||
if (beanDefinition.getBeanClassName() != null &&
|
||||
if (beanDefinition.getBeanClassName() != null &&
|
||||
beanDefinition.getBeanClassName().endsWith(TYPE_PROXY_FACTORY_BEAN) &&
|
||||
bean.endsWith(POSTFIX_SERVICE))
|
||||
{
|
||||
{
|
||||
// get the property values for the bean definition
|
||||
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
|
||||
if (propertyValues.contains(PROP_INTERCEPTOR_NAMES))
|
||||
{
|
||||
// get the current list of interceptor names
|
||||
PropertyValue value = propertyValues.getPropertyValue(PROP_INTERCEPTOR_NAMES);
|
||||
PropertyValue value = propertyValues.getPropertyValue(PROP_INTERCEPTOR_NAMES);
|
||||
ManagedList<RuntimeBeanNameReference> list = (ManagedList<RuntimeBeanNameReference>)value.getValue();
|
||||
if (!list.isEmpty())
|
||||
{
|
||||
// add reference to classification method interceptor
|
||||
RuntimeBeanNameReference beanReference = new RuntimeBeanNameReference(BEAN_NAME_CLASSIFICATION_METHOD_INTERCEPTOR);
|
||||
list.add(beanReference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
|
||||
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -54,23 +52,24 @@ public abstract class AbstractPostMethodInvocationProcessor extends BasePostMeth
|
||||
@Override
|
||||
public <T> T process(T object)
|
||||
{
|
||||
mandatory("object", object);
|
||||
T result = object;
|
||||
|
||||
T result = null;
|
||||
|
||||
if (isCollection(object))
|
||||
if (result != null)
|
||||
{
|
||||
Collection collection = ((Collection) object);
|
||||
if (!collection.isEmpty())
|
||||
if (isCollection(result))
|
||||
{
|
||||
checkObjectClass(collection.iterator().next());
|
||||
result = (T) processCollection(collection);
|
||||
Collection collection = ((Collection) result);
|
||||
if (!collection.isEmpty())
|
||||
{
|
||||
checkObjectClass(collection.iterator().next());
|
||||
result = (T) processCollection(collection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
checkObjectClass(result);
|
||||
result = processSingleElement(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
checkObjectClass(object);
|
||||
result = (T) processSingleElement(object);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@@ -23,7 +23,6 @@ import static org.alfresco.model.ContentModel.TYPE_CONTENT;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.ClassificationMethodInterceptor;
|
||||
import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.ClassificationPostMethodInvocationException.NotSupportedClassTypeException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -37,9 +36,6 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
*/
|
||||
public abstract class BasePostMethodInvocationProcessor
|
||||
{
|
||||
/** Classification method interceptor */
|
||||
private ClassificationMethodInterceptor classificationMethodInterceptor;
|
||||
|
||||
/** Node service */
|
||||
private NodeService nodeService;
|
||||
|
||||
@@ -49,16 +45,8 @@ public abstract class BasePostMethodInvocationProcessor
|
||||
/** Content classification service */
|
||||
private ContentClassificationService contentClassificationService;
|
||||
|
||||
/** Post method invocation processor registry */
|
||||
private PostMethodInvocationProcessorRegistry postMethodInvocationProcessorRegistry;
|
||||
|
||||
/**
|
||||
* @return the classificationMethodInterceptor
|
||||
*/
|
||||
protected ClassificationMethodInterceptor getClassificationMethodInterceptor()
|
||||
{
|
||||
return this.classificationMethodInterceptor;
|
||||
}
|
||||
/** Post method invocation processor */
|
||||
private PostMethodInvocationProcessor postMethodInvocationProcessor;
|
||||
|
||||
/**
|
||||
* @return the nodeService
|
||||
@@ -85,19 +73,11 @@ public abstract class BasePostMethodInvocationProcessor
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the postMethodInvocationProcessorRegistry
|
||||
* @return the postMethodInvocationProcessor
|
||||
*/
|
||||
protected PostMethodInvocationProcessorRegistry getPostMethodInvocationProcessorRegistry()
|
||||
protected PostMethodInvocationProcessor getPostMethodInvocationProcessor()
|
||||
{
|
||||
return this.postMethodInvocationProcessorRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classificationMethodInterceptor the classificationMethodInterceptor to set
|
||||
*/
|
||||
public void setClassificationMethodInterceptor(ClassificationMethodInterceptor classificationMethodInterceptor)
|
||||
{
|
||||
this.classificationMethodInterceptor = classificationMethodInterceptor;
|
||||
return this.postMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,11 +105,11 @@ public abstract class BasePostMethodInvocationProcessor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param postMethodInvocationProcessorRegistry the postMethodInvocationProcessorRegistry to set
|
||||
* @param postMethodInvocationProcessor the postMethodInvocationProcessor to set
|
||||
*/
|
||||
public void setPostMethodInvocationProcessorRegistry(PostMethodInvocationProcessorRegistry postMethodInvocationProcessorRegistry)
|
||||
public void setPostMethodInvocationProcessor(PostMethodInvocationProcessor postMethodInvocationProcessor)
|
||||
{
|
||||
this.postMethodInvocationProcessorRegistry = postMethodInvocationProcessorRegistry;
|
||||
this.postMethodInvocationProcessor = postMethodInvocationProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +132,7 @@ public abstract class BasePostMethodInvocationProcessor
|
||||
*/
|
||||
public void register()
|
||||
{
|
||||
getPostMethodInvocationProcessorRegistry().register(this);
|
||||
getPostMethodInvocationProcessor().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -71,7 +71,7 @@ public class ChildAssociationRefPostMethodInvocationProcessor extends AbstractPo
|
||||
@Override
|
||||
public Boolean apply(ChildAssociationRef childAssociationRef)
|
||||
{
|
||||
return process(childAssociationRef) != null;
|
||||
return processSingleElement(childAssociationRef) != null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -18,8 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor;
|
||||
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
@@ -34,29 +32,29 @@ public abstract class CollectionPostMethodInvocationProcessor extends BasePostMe
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.BasePostMethodInvocationProcessor#process(java.lang.Object)
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
@Override
|
||||
public <T> T process(T object)
|
||||
{
|
||||
mandatory("object", object);
|
||||
T result = object;
|
||||
|
||||
Object result = object;
|
||||
Collection collection = ((Collection) object);
|
||||
|
||||
if (!collection.isEmpty())
|
||||
if (result != null)
|
||||
{
|
||||
Iterator iterator = collection.iterator();
|
||||
if (iterator.hasNext())
|
||||
Collection collection = ((Collection) result);
|
||||
if (!collection.isEmpty())
|
||||
{
|
||||
Class<? extends Object> clazz = iterator.next().getClass();
|
||||
BasePostMethodInvocationProcessor processor = getPostMethodInvocationProcessorRegistry().getProcessor(clazz);
|
||||
if (processor != null)
|
||||
Iterator iterator = collection.iterator();
|
||||
if (iterator.hasNext())
|
||||
{
|
||||
result = processor.process(object);
|
||||
BasePostMethodInvocationProcessor processor = getPostMethodInvocationProcessor().getProcessor(iterator.next());
|
||||
if (processor != null)
|
||||
{
|
||||
result = processor.process(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (T) result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,10 @@ import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Registry for post method invocation processors
|
||||
@@ -29,8 +33,11 @@ import java.util.Map;
|
||||
* @author Tuna Aksoy
|
||||
* @since 3.0
|
||||
*/
|
||||
public class PostMethodInvocationProcessorRegistry
|
||||
public class PostMethodInvocationProcessor
|
||||
{
|
||||
/** Logger */
|
||||
private static Logger LOG = Logger.getLogger(PostMethodInvocationProcessor.class);
|
||||
|
||||
/** Post method invocation processors */
|
||||
private Map<Class<?>, BasePostMethodInvocationProcessor> processors = new HashMap<Class<?>, BasePostMethodInvocationProcessor>();
|
||||
|
||||
@@ -51,7 +58,7 @@ public class PostMethodInvocationProcessorRegistry
|
||||
*
|
||||
* @return the processors Available processors
|
||||
*/
|
||||
public Map<Class<?>, BasePostMethodInvocationProcessor> getProcessors()
|
||||
private Map<Class<?>, BasePostMethodInvocationProcessor> getProcessors()
|
||||
{
|
||||
return this.processors;
|
||||
}
|
||||
@@ -59,24 +66,52 @@ public class PostMethodInvocationProcessorRegistry
|
||||
/**
|
||||
* Gets the processor from the available processors
|
||||
*
|
||||
* @param clazz The runtime class of the post invocation object
|
||||
* @param object The post invocation object
|
||||
* @return The suitable processor for the given class
|
||||
*/
|
||||
public BasePostMethodInvocationProcessor getProcessor(Class<? extends Object> clazz)
|
||||
protected BasePostMethodInvocationProcessor getProcessor(Object object)
|
||||
{
|
||||
mandatory("clazz", clazz);
|
||||
mandatory("object", object);
|
||||
|
||||
BasePostMethodInvocationProcessor result = null;
|
||||
Class<? extends Object> clazz = object.getClass();
|
||||
|
||||
for (Map.Entry<Class<?>, BasePostMethodInvocationProcessor> processor : getProcessors().entrySet())
|
||||
Set<Entry<Class<?>, BasePostMethodInvocationProcessor>> processorsEntrySet = getProcessors().entrySet();
|
||||
for (Map.Entry<Class<?>, BasePostMethodInvocationProcessor> processorEntry : processorsEntrySet)
|
||||
{
|
||||
if (processor.getKey().isAssignableFrom(clazz))
|
||||
if (processorEntry.getKey().isAssignableFrom(clazz))
|
||||
{
|
||||
result = processor.getValue();
|
||||
result = processorEntry.getValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given object
|
||||
*
|
||||
* @param object The object to process
|
||||
* @return The processed object
|
||||
*/
|
||||
public <T> T process(T object)
|
||||
{
|
||||
T result = object;
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
BasePostMethodInvocationProcessor processor = getProcessor(result);
|
||||
if (processor != null)
|
||||
{
|
||||
result = processor.process(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("No processor found for '" + result + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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 java.lang.Boolean.TRUE;
|
||||
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
|
||||
import static org.alfresco.util.GUID.generate;
|
||||
import static org.alfresco.util.ParameterCheck.mandatory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
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.util.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* Pre method invocation processor
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @author Tuna Aksoy
|
||||
* @since 3.0
|
||||
*/
|
||||
public class PreMethodInvocationProcessor implements ApplicationContextAware
|
||||
{
|
||||
private static final String KEY_PROCESSING = generate();
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
protected ContentClassificationService getContentClassificationService()
|
||||
{
|
||||
return (ContentClassificationService)applicationContext.getBean("contentClassificationService");
|
||||
}
|
||||
|
||||
protected AlfrescoTransactionSupport getAlfrescoTransactionSupport()
|
||||
{
|
||||
return (AlfrescoTransactionSupport)applicationContext.getBean("rm.alfrescoTransactionSupport");
|
||||
}
|
||||
|
||||
protected RetryingTransactionHelper getRetryingTransactionHelper()
|
||||
{
|
||||
return ((TransactionService)applicationContext.getBean("transactionService")).getRetryingTransactionHelper();
|
||||
}
|
||||
|
||||
protected ClassificationServiceBootstrap getClassificationServiceBootstrap()
|
||||
{
|
||||
return (ClassificationServiceBootstrap)applicationContext.getBean("classificationServiceBootstrap");
|
||||
}
|
||||
|
||||
protected NodeService getNodeService()
|
||||
{
|
||||
return (NodeService)applicationContext.getBean("dbNodeService");
|
||||
}
|
||||
|
||||
protected DictionaryService getDictionaryService()
|
||||
{
|
||||
return (DictionaryService)applicationContext.getBean("dictionaryService");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user is cleared to see the items
|
||||
* passed as parameters to the current method invocation.
|
||||
*
|
||||
* @param invocation The current method invocation
|
||||
* @return <code>true</code> if the user is cleared to see the items, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean process(final MethodInvocation invocation)
|
||||
{
|
||||
mandatory("invocation", invocation);
|
||||
|
||||
// do in transaction
|
||||
return getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Boolean>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Boolean execute() throws Throwable
|
||||
{
|
||||
Boolean result = true;
|
||||
|
||||
// ensure classification service has been bootstrapped
|
||||
if (getClassificationServiceBootstrap().isInitialised())
|
||||
{
|
||||
// check that we are not already processing a classification check
|
||||
Object value = getAlfrescoTransactionSupport().getResource(KEY_PROCESSING);
|
||||
if (value == null)
|
||||
{
|
||||
Method method = invocation.getMethod();
|
||||
Class[] params = method.getParameterTypes();
|
||||
|
||||
int position = 0;
|
||||
for (Class param : params)
|
||||
{
|
||||
// if the param is a node reference
|
||||
if (NodeRef.class.isAssignableFrom(param))
|
||||
{
|
||||
// mark the transaction as processing a classification check
|
||||
getAlfrescoTransactionSupport().bindResource(KEY_PROCESSING, TRUE);
|
||||
try
|
||||
{
|
||||
// get the value of the parameter
|
||||
NodeRef testNodeRef = (NodeRef) invocation.getArguments()[position];
|
||||
|
||||
// if node exists then see if the current user has clearance
|
||||
result = isNodeCleared(testNodeRef);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// clear the transaction as processed a classification check
|
||||
getAlfrescoTransactionSupport().unbindResource(KEY_PROCESSING);
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given node exists, if it is a content and if
|
||||
* the currently logged in user is cleared to see it.
|
||||
*
|
||||
* @param nodeRef Node reference to check
|
||||
* @return <code>true</code> if the node passes the checks, <code>false</code> otherwise
|
||||
*/
|
||||
private boolean isNodeCleared(NodeRef nodeRef)
|
||||
{
|
||||
boolean result = true;
|
||||
|
||||
if (getNodeService().exists(nodeRef) &&
|
||||
getDictionaryService().isSubClass(getNodeService().getType(nodeRef), TYPE_CONTENT) &&
|
||||
!getContentClassificationService().hasClearance(nodeRef))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user