Hi,
I’m developing a web app embedding the Flowable engine using external forms and external identity/group management.
Upon submission of my custom form for a task, I would like to perform an authorization check over the user roles (retrieved externally), which should match any of the candidate groups specified for the task.
Anyway, I couldn’t find a way, having a task Id, to retrieve such information about the task definition inside the process.
Any idea?
Thanks, ciao.
Roberto
Hi Roberto,
There is an example how to check candidate groups:
org.flowable.examples.bpmn.usertask.taskcandidate.TaskCandidateTest
in flowable source.
Or you can use listener to test post complete conditions:
org.flowable.examples.bpmn.tasklistener.TaskListenerTest
Regards
Martin
Hi Martin,
looking at the test case you mention, I tried this kind of implementation:
public boolean canUserSubmitTask(String taskId, List<String> userGroups)
throws ProcessException {
return processEngine.getTaskService().createTaskQuery()
.taskId(taskId)
.taskCandidateGroupIn(userGroups)
.list()
.size() == 1;
}
Anyway, it looks like, once a task has been claimed by some user, the candidate groups list is cleared, so the query above returns no items.
I was expecting this and this is why I was asking about accessing a kind of “task definition” as opposed to the “task instance” object: I guess the list of candidate groups is kept in something like a task definition, regardless of who claimed any particular task instance.
To clarify the scenario, since I’m developing custom forms to submit any task, the taskId is sent as a form parameter.
I wish to avoid a user hacking the POST request and submitting a form changing the taskId with a different one.
When processing the form parameters on the server, I’d like to perform an authorizaiton check on the user’s roles matching the task candidate groups.
Another option could be to just check that the user name matches the task claimer, but this would prevent cases when the task must be completed by a different user in case of emergency (without first claiming the task).
Does this make sense and do you have any other idea?
BTW, I really like Flowable!
Thanks again, ciao.
Roberto
Hi Roberto,
I did a small test:
task = taskService.newTask();
task.setName("test");
taskService.saveTask(task);
taskService.addCandidateGroup(task.getId(), "sales");
taskService.addCandidateUser(task.getId(), "kermit");
assertNotNull(taskService.createTaskQuery().taskCandidateGroup("sales").singleResult());
assertNotNull(taskService.createTaskQuery().taskCandidateUser("kermit").singleResult());
taskService.claim(task.getId(), "kermit");
assertNull(taskService.createTaskQuery().taskCandidateGroup("sales").singleResult());
taskService.unclaim(task.getId());
assertNotNull(taskService.createTaskQuery().taskCandidateGroup("sales").singleResult());
When a task is claimed, it indicates that user works on the task and another user cannot complete it. When the task unclaimed it appears in the candidate groups query again.
If you want to have another query behaviour the easiest way is to implement custom or native query
http://www.flowable.org/docs/userguide/index.html#advanced.custom.sql.queries
http://www.flowable.org/docs/userguide/index.html#queryAPI
Regards
Martin
Hi Martin,
OK, then I’ll drop the scenario where a user can submit another user’s claimed task: she’ll first need to claim the task for herself.
It comes out the following code works well to perform an uthorization check under such conditions:
@Override
public boolean canUserSubmitTask(String taskId, String userName, List<String> userGroups)
throws ProcessException {
Task t = processEngine.getTaskService().createTaskQuery()
.taskId(taskId)
.singleResult();
return (t.getAssignee() != null && t.getAssignee().equals(userName)) ||
processEngine.getTaskService().createTaskQuery()
.taskId(taskId)
.taskCandidateGroupIn(userGroups)
.list()
.size() == 1;
}
Thanks for your help.
Ciao,
Roberto