From 621e6949deacd31547d95cd0f974d3511f60436b Mon Sep 17 00:00:00 2001 From: Frederik Heremans Date: Tue, 2 Oct 2012 12:48:40 +0000 Subject: [PATCH] ALF-16098: Authenticated execution of asynchronous executions (introduced in Activiti 5.10) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42261 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/workflow/adhoc.bpmn20.xml | 4 +- .../workflow/invitation-moderated.bpmn20.xml | 2 +- .../workflow/invitation-nominated.bpmn20.xml | 2 +- .../workflow/parallel-review-group.bpmn20.xml | 2 +- .../workflow/parallel-review.bpmn20.xml | 2 +- .../workflow/publish-web-content.bpmn20.xml | 2 +- .../workflow/review-pooled.bpmn20.xml | 2 +- config/alfresco/workflow/review.bpmn20.xml | 2 +- .../AlfrescoProcessEngineConfiguration.java | 23 +++-- .../AuthenticatedAsyncJobHandler.java | 94 +++++++++++++++++++ .../AuthenticatedTimerJobHandler.java | 2 +- .../repo/workflow/activiti/adhoc.bpmn20.xml | 2 +- .../activiti/testAdhoc.bpmn20.xml | 2 +- .../activiti/testCustomActiviti.bpmn20.xml | 2 +- .../activiti/testDiagram.bpmn20.xml | 2 +- .../activiti/testJob.bpmn20.xml | 2 +- .../activiti/testReview.bpmn20.xml | 2 +- .../activiti/testSignalling.bpmn20.xml | 2 +- .../activiti/testTimer.bpmn20.xml | 2 +- .../activiti/testTimerTransaction.bpmn20.xml | 2 +- .../activiti/testTransaction.bpmn20.xml | 2 +- 21 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 source/java/org/alfresco/repo/workflow/activiti/AuthenticatedAsyncJobHandler.java diff --git a/config/alfresco/workflow/adhoc.bpmn20.xml b/config/alfresco/workflow/adhoc.bpmn20.xml index 3463b52825..288d61796e 100644 --- a/config/alfresco/workflow/adhoc.bpmn20.xml +++ b/config/alfresco/workflow/adhoc.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + @@ -15,7 +15,7 @@ targetRef='adhocTask' /> + activiti:formKey="wf:adhocTask" activiti:async="true"> diff --git a/config/alfresco/workflow/invitation-moderated.bpmn20.xml b/config/alfresco/workflow/invitation-moderated.bpmn20.xml index a1f75b44fc..3cef517ef2 100644 --- a/config/alfresco/workflow/invitation-moderated.bpmn20.xml +++ b/config/alfresco/workflow/invitation-moderated.bpmn20.xml @@ -4,7 +4,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/invitation-nominated.bpmn20.xml b/config/alfresco/workflow/invitation-nominated.bpmn20.xml index 239a411f20..6c820d5678 100644 --- a/config/alfresco/workflow/invitation-nominated.bpmn20.xml +++ b/config/alfresco/workflow/invitation-nominated.bpmn20.xml @@ -4,7 +4,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/parallel-review-group.bpmn20.xml b/config/alfresco/workflow/parallel-review-group.bpmn20.xml index a82c0f4e0a..85f959852a 100644 --- a/config/alfresco/workflow/parallel-review-group.bpmn20.xml +++ b/config/alfresco/workflow/parallel-review-group.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/parallel-review.bpmn20.xml b/config/alfresco/workflow/parallel-review.bpmn20.xml index 8a6528ec4e..7d325b4ccc 100644 --- a/config/alfresco/workflow/parallel-review.bpmn20.xml +++ b/config/alfresco/workflow/parallel-review.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/publish-web-content.bpmn20.xml b/config/alfresco/workflow/publish-web-content.bpmn20.xml index 5a3d5a2138..398795bc5e 100644 --- a/config/alfresco/workflow/publish-web-content.bpmn20.xml +++ b/config/alfresco/workflow/publish-web-content.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/review-pooled.bpmn20.xml b/config/alfresco/workflow/review-pooled.bpmn20.xml index 1cd89036c8..c31ed07330 100644 --- a/config/alfresco/workflow/review-pooled.bpmn20.xml +++ b/config/alfresco/workflow/review-pooled.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/config/alfresco/workflow/review.bpmn20.xml b/config/alfresco/workflow/review.bpmn20.xml index 0263c5dfb9..595630373a 100644 --- a/config/alfresco/workflow/review.bpmn20.xml +++ b/config/alfresco/workflow/review.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> - + diff --git a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java index 72610b1912..57bc8c9da1 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java +++ b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java @@ -21,7 +21,9 @@ package org.alfresco.repo.workflow.activiti; import java.util.List; +import org.activiti.engine.impl.jobexecutor.AsyncContinuationJobHandler; import org.activiti.engine.impl.jobexecutor.JobHandler; +import org.activiti.engine.impl.jobexecutor.TimerCatchIntermediateEventJobHandler; import org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler; import org.activiti.engine.impl.variable.SerializableType; import org.activiti.engine.impl.variable.VariableType; @@ -56,12 +58,21 @@ public class AlfrescoProcessEngineConfiguration extends SpringProcessEngineConfi { super.initJobExecutor(); - // Get the existing timer-job handler and wrap - // with one that is alfresco-authentication aware - JobHandler jobHandler = jobHandlers.get(TimerExecuteNestedActivityJobHandler.TYPE); - JobHandler wrappingJobHandler = new AuthenticatedTimerJobHandler(jobHandler); - - jobHandlers.put(TimerExecuteNestedActivityJobHandler.TYPE, wrappingJobHandler); + // Wrap timer-job handler to handle authentication + JobHandler timerJobHandler = jobHandlers.get(TimerExecuteNestedActivityJobHandler.TYPE); + JobHandler wrappingTimerJobHandler = new AuthenticatedTimerJobHandler(timerJobHandler); + jobHandlers.put(TimerExecuteNestedActivityJobHandler.TYPE, wrappingTimerJobHandler); + + // Wrap async-job handler to handle authentication + JobHandler asyncJobHandler = jobHandlers.get(AsyncContinuationJobHandler.TYPE); + JobHandler wrappingAsyncJobHandler = new AuthenticatedAsyncJobHandler(asyncJobHandler); + jobHandlers.put(AsyncContinuationJobHandler.TYPE, wrappingAsyncJobHandler); + + // Wrap intermediate-timer-job handler to handle authentication + JobHandler intermediateJobHandler = jobHandlers.get(TimerCatchIntermediateEventJobHandler.TYPE); + JobHandler wrappingIntermediateJobHandler = new AuthenticatedAsyncJobHandler(intermediateJobHandler); + jobHandlers.put(TimerCatchIntermediateEventJobHandler.TYPE, wrappingIntermediateJobHandler); + } public void setCustomTypes(List customTypes) diff --git a/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedAsyncJobHandler.java b/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedAsyncJobHandler.java new file mode 100644 index 0000000000..6c92485dfc --- /dev/null +++ b/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedAsyncJobHandler.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2011 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 . + */ + +package org.alfresco.repo.workflow.activiti; + +import org.activiti.engine.impl.interceptor.CommandContext; +import org.activiti.engine.impl.jobexecutor.JobHandler; +import org.activiti.engine.impl.persistence.entity.ExecutionEntity; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.workflow.WorkflowConstants; + +/** + * An {@link JobHandler} which executes activiti jobs authenticated against Alfresco. + * The job is executed as the process-initiator. If initiator is not available, system user is used. + * + * It wraps another JobHandler to which the actual execution is delegated to. + * + * @author Frederik Heremans + * @since 4.2 + */ +public class AuthenticatedAsyncJobHandler implements JobHandler +{ + private JobHandler wrappedHandler; + + public AuthenticatedAsyncJobHandler(JobHandler jobHandler) + { + if (jobHandler == null) + { + throw new IllegalArgumentException("JobHandler to delegate to is required"); + } + this.wrappedHandler = jobHandler; + } + + @Override + public void execute(final String configuration, final ExecutionEntity execution, + final CommandContext commandContext) + { + // Get initiator + String userName = AuthenticationUtil.runAsSystem(new RunAsWork() { + + @Override + public String doWork() throws Exception { + ActivitiScriptNode ownerNode = (ActivitiScriptNode) execution.getVariable(WorkflowConstants.PROP_INITIATOR); + if(ownerNode != null && ownerNode.exists()) + { + return (String) ownerNode.getProperties().get(ContentModel.PROP_USERNAME); + } + return null; + } + }); + + + // When no initiator is set, use system user to run job + if (userName == null) + { + userName = AuthenticationUtil.getSystemUserName(); + } + + // Execute job + AuthenticationUtil.runAs(new RunAsWork() + { + @SuppressWarnings("synthetic-access") + public Void doWork() throws Exception + { + wrappedHandler.execute(configuration, execution, commandContext); + return null; + } + }, userName); + } + + @Override + public String getType() + { + return wrappedHandler.getType(); + } +} diff --git a/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedTimerJobHandler.java b/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedTimerJobHandler.java index 1f4c767a58..09938c48ef 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedTimerJobHandler.java +++ b/source/java/org/alfresco/repo/workflow/activiti/AuthenticatedTimerJobHandler.java @@ -82,7 +82,7 @@ public class AuthenticatedTimerJobHandler implements JobHandler userName = AuthenticationUtil.getSystemUserName(); } -// Execute timer + // Execute timer AuthenticationUtil.runAs(new RunAsWork() { @SuppressWarnings("synthetic-access") diff --git a/source/java/org/alfresco/repo/workflow/activiti/adhoc.bpmn20.xml b/source/java/org/alfresco/repo/workflow/activiti/adhoc.bpmn20.xml index f714516143..b50f6d9134 100644 --- a/source/java/org/alfresco/repo/workflow/activiti/adhoc.bpmn20.xml +++ b/source/java/org/alfresco/repo/workflow/activiti/adhoc.bpmn20.xml @@ -8,7 +8,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testAdhoc.bpmn20.xml b/source/test-resources/activiti/testAdhoc.bpmn20.xml index 278444077a..d8a44f24d1 100644 --- a/source/test-resources/activiti/testAdhoc.bpmn20.xml +++ b/source/test-resources/activiti/testAdhoc.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testCustomActiviti.bpmn20.xml b/source/test-resources/activiti/testCustomActiviti.bpmn20.xml index f219523b86..62e3503e3e 100644 --- a/source/test-resources/activiti/testCustomActiviti.bpmn20.xml +++ b/source/test-resources/activiti/testCustomActiviti.bpmn20.xml @@ -1,6 +1,6 @@ - + Custom activiti, created to test that the priority is automatically set to an allowed value e.g. change from 50 to 2. diff --git a/source/test-resources/activiti/testDiagram.bpmn20.xml b/source/test-resources/activiti/testDiagram.bpmn20.xml index d750e92e5d..52e5b5a34e 100644 --- a/source/test-resources/activiti/testDiagram.bpmn20.xml +++ b/source/test-resources/activiti/testDiagram.bpmn20.xml @@ -6,7 +6,7 @@ xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> - + diff --git a/source/test-resources/activiti/testJob.bpmn20.xml b/source/test-resources/activiti/testJob.bpmn20.xml index 081645f776..45dd9a4947 100644 --- a/source/test-resources/activiti/testJob.bpmn20.xml +++ b/source/test-resources/activiti/testJob.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testReview.bpmn20.xml b/source/test-resources/activiti/testReview.bpmn20.xml index f590b5f034..910cf40fe7 100644 --- a/source/test-resources/activiti/testReview.bpmn20.xml +++ b/source/test-resources/activiti/testReview.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testSignalling.bpmn20.xml b/source/test-resources/activiti/testSignalling.bpmn20.xml index 5568457f67..dd030be95b 100644 --- a/source/test-resources/activiti/testSignalling.bpmn20.xml +++ b/source/test-resources/activiti/testSignalling.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testTimer.bpmn20.xml b/source/test-resources/activiti/testTimer.bpmn20.xml index d15f9a1844..9c0f5b7d6d 100644 --- a/source/test-resources/activiti/testTimer.bpmn20.xml +++ b/source/test-resources/activiti/testTimer.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testTimerTransaction.bpmn20.xml b/source/test-resources/activiti/testTimerTransaction.bpmn20.xml index 00e820d04e..dfae7a0c77 100644 --- a/source/test-resources/activiti/testTimerTransaction.bpmn20.xml +++ b/source/test-resources/activiti/testTimerTransaction.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - + diff --git a/source/test-resources/activiti/testTransaction.bpmn20.xml b/source/test-resources/activiti/testTransaction.bpmn20.xml index f7e1d72a30..98fbd93acf 100644 --- a/source/test-resources/activiti/testTransaction.bpmn20.xml +++ b/source/test-resources/activiti/testTransaction.bpmn20.xml @@ -5,7 +5,7 @@ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> - +