How to restrict the start of process

Is there any way to restrict, which user can start a process?

Because I was playing with the UI modeler and created an app, with 2 groups, but anyone that can log in in to the workflow task, can start any process I have delpoyed.

Can you please tell me how to do that?

Thank you, best regards from Mexico.

I have the same problem, but also the fact that all processes are presented to all users, even if they are not part of it.

Is there any solution to these two problems?

Thank you

Hi,

There is an option to define candidate starter users and groups in the BPMN XML:

http://www.flowable.org/docs/userguides/userguide/index.html#security

We don’t support it yet from the task app, but this could be implemented if there’s request from the community. Please raise a Github issue so it can be tracked.

Best regards,

Tijs

This feature would be very useful

Hi there Tijs.

Well today I was seeing some code and the interaction between the flowable 6 modeler app and flowable 6 modeler rest app.

I know now how its working the integration, but I need a little help.

Im going to implement a field for a property called “potential starter”,

so the first step is to add a property value to the shape in Oryx editor,

any clue in how to achieve this? , because the code of Orix editor is really huge.

I want to add the porperty to the start shape, after that I will work with the backend for generate the xml directives that you posted at the link and save the data.

Your suggestions will be very apreciatted.

Thanks.

Hi,

It starts with changing the stencilset_bpmn,json file in the flowable-ui-modeler-logic module (src/main/resource). You can add the “potential starter” property in that JSON definition and add the property to Diagram element (because it’s a property of the process element not the start event in BPMN XML). Nothing needs to be changed in Oryx for this.

Then you would to change the flowable-json-converter module to read the new JSON property and translate it into the candidateStarterUsers and candidateStarterGroups on the Process element in the flowable-bpmn-model module. The translation to BPMN XML is already implemented for these properties.

Best regards,

Tijs

I already make the changes in the stencilset_bpmn,json the result is the next:
{
“name” : “process_potentialstarter”,
“properties” : [ {
“id” : “process_potentialstarter”,
“type” : “String”,
“title” : “Process potential starter”,
“value” : “”,
“description” : “Which user or group, can start the process?”,
“popular” : true
} ]
}

after that I have added a new constant in the StencilConstants.Java

final String PROPERTY_PROCESS_POTENTIALSTARTER = “process_potentialstarter”;

In the clas BPMJson Converter.java I have added the next lines:

            process.setCandidateStarterGroups(JsonConverterUtil.getPropertyValueAsList(PROPERTY_PROCESS_POTENTIALSTARTER, shapeNode));
            process.setCandidateStarterUsers(JsonConverterUtil.getPropertyValueAsList(PROPERTY_PROCESS_POTENTIALSTARTER, shapeNode));

This is the correct aproach to glue all the parts of the app?

I cant see the new field.

thanks

Ok, the pronlem was that I was using diferent names that the package standard names on the properties and I didnt add the package names to Diagram object in json.

Now im able to see the field and save the data

Thats the result, now im working on make test tothe restriction that I setup in the BpmJsonConverter.Java at his method called convertToBpmnModel() where I set the values that the user provides on the UI , Here is my code if works for anyone

////codigo sibok666
    String userStarter=BpmnJsonConverterUtil.getPropertyValueAsString(PROPERTY_PROCESS_POTENTIALSTARTERUSER, modelNode);
    String groupStarter=BpmnJsonConverterUtil.getPropertyValueAsString(PROPERTY_PROCESS_POTENTIALSTARTERGROUP, modelNode);
    List<String> usuariosIniciadores=new ArrayList();
    List<String> gruposIniciadores=new ArrayList();
    
    String arregloUsuarios[]=userStarter.split(",");

    String arregloGrupos[]=groupStarter.split(",");

    for(int i=0;i<arregloUsuarios.length;i++){
    	usuariosIniciadores.add(arregloUsuarios[i]);
    }
    for(int i=0;i<arregloGrupos.length;i++){
    	gruposIniciadores.add(arregloGrupos[i]);
    }
////codigo sibok666

After that in the same class when create a process instance I set the values.

            Process process = new Process();
            process.setId(pool.getProcessRef());
            process.setName(pool.getName());
            process.setExecutable(pool.isExecutable());
            ///codigo sibok666
            process.setCandidateStarterGroups(gruposIniciadores);
            process.setCandidateStarterUsers(usuariosIniciadores);
            ///codigo sibok666

Im going to test and I will tell you how the thing is going.

Best regards from Mexico

Hi Tijs, I hope you can help me.

Today I was working with the task-app, for only get the list of processes that the user can execute.

I have added this lines at the FlowablProcessDefinitionService.Java, at the method getProcessDefinitions

Next are the lines I added:

    User currentUser = SecurityUtils.getCurrentUserObject();
    String userId=currentUser.getId();
    definitionQuery.startableByUser(userId).list();
    List<ProcessDefinition> definitions = definitionQuery.list();

But I get the next exception:

06:14:02,174 [http-nio-8080-exec-8] INFO org.flowable.engine.impl.app.AppDeployer - Processing app resource aaa.app
06:15:39,514 [http-nio-8080-exec-3] ERROR org.flowable.engine.common.impl.interceptor.AbstractCommandContext - Error while closing command context
org.apache.ibatis.exceptions.PersistenceException:

Error querying database. Cause: java.lang.NullPointerException

Cause: java.lang.NullPointerException

And the nullpointer is for this property: authorizationUserId

How can I set this?

Im very closo to finish I ho I can get some help.

Thank you.

Best regards from Mexico

Hi,

Can you share the full stack trace?

Best regards,

Tijs

Ater doing some test, I was cappable of restrict the user wich start the process, I think the problem in the line:

definitionQuery.startableByUser(userId).list();

Was that need access to LDAP Configuration wich im not using.

So I solved the problem in the next way, I think is not an elegant solution but solves my problem and I hope to help somebody else, here is the code:

public ResultListDataRepresentation getProcessDefinitions(Boolean latest, String deploymentKey) {

    ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
    
    if (deploymentKey != null) {
        Deployment deployment = repositoryService.createDeploymentQuery().deploymentKey(deploymentKey).latest().singleResult();

        if (deployment != null) {
            definitionQuery.deploymentId(deployment.getId());
        } else {
            return new ResultListDataRepresentation(new ArrayList<ProcessDefinitionRepresentation>());
        }

    } else {

        if (latest != null && latest) {
            definitionQuery.latestVersion();
        }
    }
    ///sibok666 code
    ///getting logged user
    User currentUser = SecurityUtils.getCurrentUserObject();
    String userId=currentUser.getId();
    ///getting all the processes of the app
    List<ProcessDefinition> definitions = definitionQuery.list();
    List<ProcessDefinition> definitionsFiltered=new ArrayList();
    ///getting the groups by user
    List<RemoteGroup> listaGruposXUsuario=remoteIdmService.getUser(userId).getGroups();
    
    for(ProcessDefinition pd:definitions){
     BpmnModel bpmnModel=repositoryService.getBpmnModel(pd.getId());
     List<Process> listaProcesos=bpmnModel.getProcesses();
     	for(Process p:listaProcesos){
     		///get the new properties of restriction added in the modeler app by process
     		List<String> listaGrupos=p.getCandidateStarterGroups();
     		List<String> listaUsuarios=p.getCandidateStarterUsers();
     		///checking if user is contained as potential user
     		if(listaUsuarios.contains(userId)){
     			definitionsFiltered.add(pd);
     		}
     		///comparing the groups of the user and the groups defined in the modeler app
     		//if the gruops are the same and dont exist in the current list of process so we addit to the response
     		for(String g:listaGrupos){
     			for(RemoteGroup rg: listaGruposXUsuario){
     				if(rg.getId().equals(g)){
     					if(!definitionsFiltered.contains(pd)){
     						definitionsFiltered.add(pd);
     					}
     				}
     			}
     		}
     	}
    }
    ///sibok666
    
    ResultListDataRepresentation result = new ResultListDataRepresentation(convertDefinitionList(definitionsFiltered));
    return result;
}

That’s not the case. The startableByUser does try to retrieve the groups from the remote IDM service I guess. Does it maybe fail there? The solution you came up with works as well of course.

Best regards,

Tijs

Hi,

I created a project using Flowable, with four groups of users.

I define, in the model, that only one of the groups should start the process, but when I run the app, it lets any of the groups start the process.

How can I solve this problem?

Thank you in advance

Hi,

By default the Flowable task app doesn’t restrict the access to processes. From an API level this is available, so it can be added of course.

Best regards,

Tijs

http://www.flowable.org/docs/userguide/index.html#security is the link nowadays.

Hi,

This is also something I would like as well. I’d be willing to complete the implementation in the flowable-task app if that would help.

@Sibok666 @tijs Its a bit hard to follow the current status of this. It seems that it has been implemented in the modeler and in the process Engine, but not in the flowable-task front/backend. Does this sound correct?

If I was to implement this I Think a filter based on the potential user/Group when listing process definitions to start and a permission check when actually starting a process would suffice.

Please let me know if you’d like me to proceed and I can take a look during this week.

Regards,
Paul

I have taken a closer look at this and there are two problems when implementing in the flowable-task app.

1 - IdmIdentityService is null

When setting org.flowable.engine.impl.ProcessDefinitionQueryImpl#startableByUser(String userId) to a non-null value when making the Query a lookup is made to ProcessDefinitionQueryImpl#getAuthorizationGroups() and this makes use of the CandidateManager#getGroupsForCandidateUser(String candidateUser) method.

In the flowable-task app this is the class org.flowable.engine.DefaultCandidateManager. The implementation then makes use of the IdentityService and IdmIdentityService which is null - causing the null pointer exception reported above by @Sibok666

A simple solution to this is to provide an alternative CandidateManager implementation using the RemoteIdmService instead of the IdentityService.

(I Think a better solution would be if RemoteIdmService was an implementation of IdmIdentityService and registered within the process Engine - but this would be a lot more work).

2 - No potential starter user/group in the process definition means no-one can start.

The next problem after fixing the above error is how we handle processes which have not set a potential starter user/Group.
As the ProcessDefinitionQueryImpl#startableByUser(String userId) is currently implemented, if we provide a value then that user or one of their Groups must be defined as a potential starter. Otherwise the process definition is filtered out.
However, this implies that a process without a potential starter defined will always be filtered out and not be startable by anyone. Is this the correct behvaiour? Or should no potential starter being defined allow the process to be available to everyone?
(And use a special ‘no-one’ Group for processes that should not be startable by anyone).

Without fixing this issue, when users run flowable-task, if no potential starter has been defined the process definition will not be displayed. I can imagine this will cause a lot of confusion to new users of flowable, as its not a field they will likely use immediately in the modeller. This would also require that every process has a potential starter defined which seems unnecessarily difficult.

Any thoughts on the above points? particularily number 2?

Regards,
Paul

Yes, you are correct on both points.

Imo, a process definition without a potential starter should be startable by everyone, that’s also the way that’s backwards compatible with the existing functionality.

If you need help with this, feel free to reach out here. The changes shouldn’t be extremely complex, I hope.

Hi,

I have now made the changes and created a pull request https://github.com/flowable/flowable-engine/pull/516 containing them.
I have outlined what I have done in the pull request. Please let me know if they require any additional Changes.

Regards,
Paul

Thanks, Paul! We’ll review it soon and discuss it further in the issue.