From c9ba4bc66e1fd4d0a705085a92871e6c21693560 Mon Sep 17 00:00:00 2001 From: Mark Rogers Date: Tue, 22 Jul 2014 15:47:20 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud) 76582: Merged V4.2-BUG-FIX (4.2.4) to HEAD-BUG-FIX (5.0/Cloud) 76493: MNT-11670: Merged DEV to V4.2-BUG-FIX (4.2.4) 73830: MNT-11670: Unable to end a workflow when a timer is triggered and a rule is configured on a target folder - Save current user info when rule is added to the pending execution. Then it can be used during rule execution if security context is empty. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@77648 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/repo/rule/RuleServiceImpl.java | 36 ++++++++++++- .../repo/rule/RuleServiceImplTest.java | 51 ++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/source/java/org/alfresco/repo/rule/RuleServiceImpl.java b/source/java/org/alfresco/repo/rule/RuleServiceImpl.java index ad5b34e9d7..b15ab810ae 100644 --- a/source/java/org/alfresco/repo/rule/RuleServiceImpl.java +++ b/source/java/org/alfresco/repo/rule/RuleServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2012 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -1033,6 +1033,7 @@ public class RuleServiceImpl this.disabledRules.contains(rule) == false) { PendingRuleData pendingRuleData = new PendingRuleData(actionableNodeRef, actionedUponNodeRef, rule, executeAtEnd); + pendingRuleData.setRunAsUser(AuthenticationUtil.getRunAsUser()); List pendingRules = (List) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING); @@ -1134,8 +1135,28 @@ public class RuleServiceImpl * * @param pendingRule the pending rule data object */ + private void executePendingRule(final PendingRuleData pendingRule) + { + if (AuthenticationUtil.getRunAsAuthentication() == null && pendingRule.getRunAsUser() != null) + { + // MNT-11670: runAsUser was set previously + AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + { + public Void doWork() throws Exception + { + executePendingRuleImpl(pendingRule); + return null; + } + }, pendingRule.getRunAsUser()); + } + else + { + executePendingRuleImpl(pendingRule); + } + } + @SuppressWarnings("unchecked") - private void executePendingRule(PendingRuleData pendingRule) + private void executePendingRuleImpl(PendingRuleData pendingRule) { Set executedRules = (Set) AlfrescoTransactionSupport.getResource(KEY_RULES_EXECUTED); @@ -1408,6 +1429,7 @@ public class RuleServiceImpl { private NodeRef actionedUponNodeRef; private boolean executeAtEnd = false; + private String runAsUserName = null; public PendingRuleData(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule, boolean executeAtEnd) { @@ -1426,6 +1448,16 @@ public class RuleServiceImpl return this.executeAtEnd; } + public String getRunAsUser() + { + return this.runAsUserName; + } + + public void setRunAsUser(String runAsUserName) + { + this.runAsUserName = runAsUserName; + } + @Override public int hashCode() { diff --git a/source/test-java/org/alfresco/repo/rule/RuleServiceImplTest.java b/source/test-java/org/alfresco/repo/rule/RuleServiceImplTest.java index a363fb69f9..9cf176d72c 100644 --- a/source/test-java/org/alfresco/repo/rule/RuleServiceImplTest.java +++ b/source/test-java/org/alfresco/repo/rule/RuleServiceImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2013 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -1187,4 +1187,53 @@ public class RuleServiceImplTest extends BaseRuleTest this.nodeService.deleteNode(folder2NodeRef); txn.commit(); } + + /** + * MNT-11670 + */ + public void testRuleExecutionWhenSecurityContextIsEmpty() throws Exception + { + // Create parent and child folders + NodeRef parentNodeRef = this.nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("parentnode" + GUID.generate()), ContentModel.TYPE_FOLDER) + .getChildRef(); + + // rule is created and added to pending execution by any user + assertNotNull(AuthenticationUtil.getFullyAuthenticatedUser()); + + // Create rule for child node + Rule testRule = new Rule(); + testRule.setRuleTypes(Collections.singletonList(RuleType.INBOUND)); + testRule.setTitle("RuleServiceTest" + GUID.generate()); + testRule.setDescription(DESCRIPTION); + testRule.applyToChildren(true); + Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME); + action.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE); + testRule.setAction(action); + this.ruleService.saveRule(parentNodeRef, testRule); + assertNotNull("Rule was not saved", testRule.getNodeRef()); + + // Search rules + List rules = this.ruleService.getRules(parentNodeRef, true, testRule.getRuleTypes().get(0)); + assertNotNull("No rules found", rules); + assertTrue("Created rule is not found", new HashSet(rules).contains(testRule)); + + // New node + NodeRef actionedUponNodeRef = this.nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("actioneduponnode" + GUID.generate()), + ContentModel.TYPE_CONTENT).getChildRef(); + + // Queue the rule to be executed later and execute pending rules + if (this.nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE)) + { + this.nodeService.removeAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE); + } + ((RuntimeRuleService) ruleService).addRulePendingExecution(parentNodeRef, actionedUponNodeRef, testRule); + + // no security context in case of the issue + AuthenticationUtil.clearCurrentSecurityContext(); + assertNull(AuthenticationUtil.getFullyAuthenticatedUser()); + assertNull(AuthenticationUtil.getRunAsUser()); + + ((RuntimeRuleService) ruleService).executePendingRules(); + assertTrue("Pending rule was not executed", this.nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE)); + } }