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
This commit is contained in:
Mark Rogers
2014-07-22 15:47:20 +00:00
parent 92bae9b4e2
commit c9ba4bc66e
2 changed files with 84 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2012 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -1033,6 +1033,7 @@ public class RuleServiceImpl
this.disabledRules.contains(rule) == false) this.disabledRules.contains(rule) == false)
{ {
PendingRuleData pendingRuleData = new PendingRuleData(actionableNodeRef, actionedUponNodeRef, rule, executeAtEnd); PendingRuleData pendingRuleData = new PendingRuleData(actionableNodeRef, actionedUponNodeRef, rule, executeAtEnd);
pendingRuleData.setRunAsUser(AuthenticationUtil.getRunAsUser());
List<PendingRuleData> pendingRules = List<PendingRuleData> pendingRules =
(List<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING); (List<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING);
@@ -1134,8 +1135,28 @@ public class RuleServiceImpl
* *
* @param pendingRule the pending rule data object * @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<Void>()
{
public Void doWork() throws Exception
{
executePendingRuleImpl(pendingRule);
return null;
}
}, pendingRule.getRunAsUser());
}
else
{
executePendingRuleImpl(pendingRule);
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void executePendingRule(PendingRuleData pendingRule) private void executePendingRuleImpl(PendingRuleData pendingRule)
{ {
Set<ExecutedRuleData> executedRules = Set<ExecutedRuleData> executedRules =
(Set<ExecutedRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_EXECUTED); (Set<ExecutedRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_EXECUTED);
@@ -1408,6 +1429,7 @@ public class RuleServiceImpl
{ {
private NodeRef actionedUponNodeRef; private NodeRef actionedUponNodeRef;
private boolean executeAtEnd = false; private boolean executeAtEnd = false;
private String runAsUserName = null;
public PendingRuleData(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule, boolean executeAtEnd) public PendingRuleData(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule, boolean executeAtEnd)
{ {
@@ -1426,6 +1448,16 @@ public class RuleServiceImpl
return this.executeAtEnd; return this.executeAtEnd;
} }
public String getRunAsUser()
{
return this.runAsUserName;
}
public void setRunAsUser(String runAsUserName)
{
this.runAsUserName = runAsUserName;
}
@Override @Override
public int hashCode() public int hashCode()
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2013 Alfresco Software Limited. * Copyright (C) 2005-2014 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -1187,4 +1187,53 @@ public class RuleServiceImplTest extends BaseRuleTest
this.nodeService.deleteNode(folder2NodeRef); this.nodeService.deleteNode(folder2NodeRef);
txn.commit(); 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<Rule> rules = this.ruleService.getRules(parentNodeRef, true, testRule.getRuleTypes().get(0));
assertNotNull("No rules found", rules);
assertTrue("Created rule is not found", new HashSet<Rule>(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));
}
} }