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
This commit is contained in:
Frederik Heremans
2012-10-02 12:48:40 +00:00
parent dcce548a8d
commit 621e6949de
21 changed files with 131 additions and 26 deletions

View File

@@ -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<VariableType> customTypes)

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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<String>() {
@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<Void>()
{
@SuppressWarnings("synthetic-access")
public Void doWork() throws Exception
{
wrappedHandler.execute(configuration, execution, commandContext);
return null;
}
}, userName);
}
@Override
public String getType()
{
return wrappedHandler.getType();
}
}

View File

@@ -82,7 +82,7 @@ public class AuthenticatedTimerJobHandler implements JobHandler
userName = AuthenticationUtil.getSystemUserName();
}
// Execute timer
// Execute timer
AuthenticationUtil.runAs(new RunAsWork<Void>()
{
@SuppressWarnings("synthetic-access")

View File

@@ -8,7 +8,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:activiti="http://activiti.org/bpmn">
<process id="adhoc" name="Adhoc Process">
<process isExecutable="true" id="adhoc" name="Adhoc Process">
<startEvent id="start"
activiti:formKey="adhocStart.form" />