From a6ab82152dc08540abf8e6716c78fea97c41b142 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Fri, 3 Jul 2015 14:41:53 +0000 Subject: [PATCH] RM-2129 (Check classification before method execution) +review RM-117 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@107676 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../classified-content-context.xml | 3 +- .../ClassificationEnforcementException.java | 43 ++++++++++ .../PreMethodInvocationProcessor.java | 45 ++++++---- ...ionEnforcementPreMethodInvocationTest.java | 82 ++++++++++++------- 4 files changed, 126 insertions(+), 47 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/ClassificationEnforcementException.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/classified-content-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/classified-content-context.xml index 939558bd7a..15cd6eecba 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/classified-content-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/classified-content-context.xml @@ -43,7 +43,8 @@ + class="org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.PreMethodInvocationProcessor" + init-method="init"> . + */ +package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; + +import org.alfresco.error.AlfrescoRuntimeException; + +/** + * Classification enforcement exception + * + * @author Tuna Aksoy + * @since 3.0 + */ +public class ClassificationEnforcementException extends AlfrescoRuntimeException +{ + /** Serial version uid */ + private static final long serialVersionUID = -1546218007029075883L; + + /** + * Constructor + * + * @param key The key of the exception to be localized + */ + public ClassificationEnforcementException(String key) + { + super(key); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/PreMethodInvocationProcessor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/PreMethodInvocationProcessor.java index b74e636a55..c823bcccf6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/PreMethodInvocationProcessor.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/interceptor/processor/PreMethodInvocationProcessor.java @@ -18,15 +18,14 @@ */ package org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor; -import static com.google.common.collect.Lists.newArrayList; import static org.alfresco.model.ContentModel.TYPE_CONTENT; import static org.alfresco.util.ParameterCheck.mandatory; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService; -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; @@ -44,6 +43,9 @@ import org.springframework.context.ApplicationContextAware; */ public class PreMethodInvocationProcessor implements ApplicationContextAware { + /** List of method names to check before invocation */ + private List methodNames = new ArrayList<>(); + /** Application context */ private ApplicationContext applicationContext; @@ -86,6 +88,29 @@ public class PreMethodInvocationProcessor implements ApplicationContextAware return (DictionaryService) applicationContext.getBean("dictionaryService"); } + /** + * Returns a list of method names to check before invocation + * + * @return List of method names to check before invocation + */ + protected List getMethodNames() + { + return this.methodNames; + } + + /** + * Init method to populate the list of method names which will be checked before invocation + */ + public void init() + { + getMethodNames().add("NodeService.setProperty"); + getMethodNames().add("NodeService.setProperties"); + //getMethodNames().add("NodeService.getProperty"); + getMethodNames().add("NodeService.getProperties"); + getMethodNames().add("FileFolderService.copy"); + getMethodNames().add("FileFolderService.move"); + } + /** * Checks if the current user is cleared to see the items * passed as parameters to the current method invocation. @@ -114,20 +139,6 @@ public class PreMethodInvocationProcessor implements ApplicationContextAware } } - /** - * Returns a list of method names to check before invocation - * - * @return List of method names to check before invocation - */ - private List getMethodNames() - { - return newArrayList( - "NodeService.setProperty", - //"NodeService.getProperty", - "FileFolderService.copy" - ); - } - /** * Checks if the given node exists, if it is a content and if * the currently logged in user is cleared to see it. @@ -141,7 +152,7 @@ public class PreMethodInvocationProcessor implements ApplicationContextAware getDictionaryService().isSubClass(getNodeService().getType(nodeRef), TYPE_CONTENT) && !getContentClassificationService().hasClearance(nodeRef)) { - throw new AccessDeniedException("The method '" + name + "' was called, but you are not cleared for the node."); + throw new ClassificationEnforcementException("The method '" + name + "' was called, but you are not cleared for the node."); } } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/ClassificationEnforcementPreMethodInvocationTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/ClassificationEnforcementPreMethodInvocationTest.java index e3fb80a663..2f232d0e8a 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/ClassificationEnforcementPreMethodInvocationTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/interceptor/ClassificationEnforcementPreMethodInvocationTest.java @@ -22,9 +22,14 @@ import static com.google.common.collect.Sets.newHashSet; import static org.alfresco.repo.site.SiteModel.SITE_MANAGER; import static org.alfresco.util.GUID.generate; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.classification.interceptor.processor.ClassificationEnforcementException; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; -import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; /** * Classification enforcement pre method invocation test @@ -34,10 +39,6 @@ import org.alfresco.service.cmr.repository.NodeRef; */ public class ClassificationEnforcementPreMethodInvocationTest extends BaseRMTestCase { - private String testUser; - private static final String LEVEL1 = "level1"; - private static final String REASON = "Test Reason 1"; - /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isCollaborationSiteTest() */ @@ -51,16 +52,22 @@ public class ClassificationEnforcementPreMethodInvocationTest extends BaseRMTest { /** * Given that I am a site manager and not cleared to see a document - * When I try to set a property on that document an exception will be thrown - * and I try to copy that document an exception will be thrown + * When I try to + * - set a property on that document + * - set properties on that document + * - get property from that document + * - copy the document + * - move document + * Then a classification exception will be thrown */ doBehaviourDrivenTest(new BehaviourDrivenTest() { + private String testUser; + private static final String LEVEL1 = "level1"; + private static final String REASON = "Test Reason 1"; private NodeRef folder1; private NodeRef folder2; - private NodeRef doc1; - private NodeRef doc2; - private String propertyValue = generate(); + private NodeRef doc; /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase.BehaviourDrivenTest#given() @@ -74,10 +81,9 @@ public class ClassificationEnforcementPreMethodInvocationTest extends BaseRMTest folder1 = fileFolderService.create(documentLibrary, generate(), TYPE_FOLDER).getNodeRef(); folder2 = fileFolderService.create(documentLibrary, generate(), TYPE_FOLDER).getNodeRef(); - doc1 = fileFolderService.create(folder1, generate(), TYPE_CONTENT).getNodeRef(); - doc2 = fileFolderService.create(folder1, generate(), TYPE_CONTENT).getNodeRef(); + doc = fileFolderService.create(folder1, generate(), TYPE_CONTENT).getNodeRef(); - contentClassificationService.classifyContent(LEVEL1, generate(), generate(), newHashSet(REASON), doc1); + contentClassificationService.classifyContent(LEVEL1, generate(), generate(), newHashSet(REASON), doc); } /** @@ -86,40 +92,58 @@ public class ClassificationEnforcementPreMethodInvocationTest extends BaseRMTest @Override public void when() throws Exception { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - nodeService.setProperty(doc2, PROP_ADDRESSEE, propertyValue); - return null; - } - }, testUser); - - doTestInTransaction(new FailureTest(AccessDeniedException.class) + doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) { @Override public void run() throws Exception { - nodeService.setProperty(doc1, PROP_ADDRESSEE, propertyValue); + nodeService.setProperty(doc, PROP_ADDRESSEE, generate()); } }, testUser); -// doTestInTransaction(new FailureTest(AccessDeniedException.class) + doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) + { + @Override + public void run() + { + Map properties = new HashMap(); + nodeService.setProperties(doc, properties); + } + }, testUser); + +// doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) // { // @Override // public void run() throws Exception // { -// nodeService.getProperty(doc1, PROP_ADDRESSEE); +// nodeService.getProperty(doc, PROP_ADDRESSEE); // } // }, testUser); - doTestInTransaction(new FailureTest(AccessDeniedException.class) + doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) { @Override public void run() throws Exception { - fileFolderService.copy(doc1, folder2, null); + nodeService.getProperties(doc); + } + }, testUser); + + doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) + { + @Override + public void run() throws Exception + { + fileFolderService.copy(doc, folder2, null); + } + }, testUser); + + doTestInTransaction(new FailureTest(ClassificationEnforcementException.class) + { + @Override + public void run() throws Exception + { + fileFolderService.move(doc, folder2, null); } }, testUser); }