Deleting IdentityLinks: PARTICIPANT and CANDIDATE

Hi there. I found some issue with the way that deleting an identity link is handled.
I would like to understand what the logic is how it works:
Here is the implementation that I found in the engine:

org.flowable.identitylink.service.impl.persistence.entity.IdentityLinkEntityManagerImpl

@Override
public List<IdentityLinkEntity> deleteTaskIdentityLink(String taskId, List<IdentityLinkEntity> currentIdentityLinks, String userId, String groupId, String type) {
    List<IdentityLinkEntity> identityLinks = findIdentityLinkByTaskUserGroupAndType(taskId, userId, groupId, type);

    List<IdentityLinkEntity> removedIdentityLinkEntities = new ArrayList<>();
    List<String> identityLinkIds = new ArrayList<>();
    for (IdentityLinkEntity identityLink : identityLinks) {
        delete(identityLink);
        identityLinkIds.add(identityLink.getId());
        removedIdentityLinkEntities.add(identityLink);
    }

    // fix deleteCandidate() in create TaskListener
    if (currentIdentityLinks != null) {
        for (IdentityLinkEntity identityLinkEntityA : currentIdentityLinks) {
            if (IdentityLinkType.CANDIDATE.equals(identityLinkEntityA.getType()) &&
                    !identityLinkIds.contains(identityLinkEntityA.getId())) {

                if ((userId != null && userId.equals(identityLinkEntityA.getUserId()))
                        || (groupId != null && groupId.equals(identityLinkEntityA.getGroupId()))) {

                    delete(identityLinkEntityA);
                    removedIdentityLinkEntities.add(identityLinkEntityA);

                }
            }
        }
    }
    
    return removedIdentityLinkEntities;
}

From what I can see the identity link is deleted as requested and then also the candidate is deleted.

This is strange to me. I have a task with a candidate user1 , then if the user is added as a participant and then removed as a participant, that user is no longer a candidate. This is causing some problems in our application, because we allow any candidate to claim a task, but some other user can add the user1 as a participant then remove them again later. After that, the user1 can no longer claim the task.

What is the reasoning behind this?

Looking at the code, it looks indeed that the deletion of any identity link with a certain userId/groupId cascades to deleting the candidate identity link.

The comment

// fix deleteCandidate() in create TaskListener

seems to indicate that this is deliberate, so I removed the bit under the comment and ran the test suite. Indeed, flowable-engine/modules/flowable-engine/src/test/java/org/flowable/engine/test/api/task/TaskIdentityLinksTest.java at main · flowable/flowable-engine · GitHub fails in that case.

Looking at the test and code, this does look like a bug. Candidate is kinda like meta-information, there should be no reason to remove it anyways. Bugfix has been pushed to master: Fix task identity link unneeded candidate cascading delete · flowable/flowable-engine@84545e7 · GitHub

Thank you for that :slight_smile: