org.activiti.app.service.runtime.PermissionService.java Source code

Java tutorial

Introduction

Here is the source code for org.activiti.app.service.runtime.PermissionService.java

Source

/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.activiti.app.service.runtime;

import java.util.ArrayList;
import java.util.List;

import org.activiti.app.service.exception.NotFoundException;
import org.activiti.app.service.exception.NotPermittedException;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.ExtensionElement;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.UserTask;
import org.activiti.content.api.ContentItem;
import org.activiti.editor.language.json.converter.util.CollectionUtils;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.idm.api.Group;
import org.activiti.idm.api.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Centralized service for all permission-checks.
 * 
 * @author Frederik Heremans
 */
@Service
@Transactional
public class PermissionService {

    @Autowired
    protected TaskService taskService;

    @Autowired
    protected RuntimeService runtimeService;

    @Autowired
    protected RepositoryService repositoryService;

    @Autowired
    protected HistoryService historyService;

    @Autowired
    protected IdentityService identityService;

    /**
     * Check if the given user is allowed to read the task.
     */
    public HistoricTaskInstance validateReadPermissionOnTask(User user, String taskId) {

        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery().taskId(taskId)
                .taskInvolvedUser(String.valueOf(user.getId())).list();

        if (CollectionUtils.isNotEmpty(tasks)) {
            return tasks.get(0);
        }

        // Task is maybe accessible through groups of user
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
        historicTaskInstanceQuery.taskId(taskId);

        List<String> groupIds = getGroupIdsForUser(user);
        if (!groupIds.isEmpty()) {
            historicTaskInstanceQuery.taskCandidateGroupIn(getGroupIdsForUser(user));
        }

        tasks = historicTaskInstanceQuery.list();
        if (CollectionUtils.isNotEmpty(tasks)) {
            return tasks.get(0);
        }

        // Last resort: user has access to proc inst -> can see task
        tasks = historyService.createHistoricTaskInstanceQuery().taskId(taskId).list();
        if (CollectionUtils.isNotEmpty(tasks)) {
            HistoricTaskInstance task = tasks.get(0);
            if (task != null && task.getProcessInstanceId() != null) {
                boolean hasReadPermissionOnProcessInstance = hasReadPermissionOnProcessInstance(user,
                        task.getProcessInstanceId());
                if (hasReadPermissionOnProcessInstance) {
                    return task;
                }
            }
        }
        throw new NotPermittedException("User is not allowed to work with task " + taskId);
    }

    private List<String> getGroupIdsForUser(User user) {
        List<String> groupIds = new ArrayList<String>();
        for (Group group : identityService.createGroupQuery().groupMember(user.getId()).list()) {
            groupIds.add(String.valueOf(group.getId()));
        }
        return groupIds;
    }

    public boolean isTaskOwnerOrAssignee(User user, String taskId) {
        return isTaskOwnerOrAssignee(user, taskService.createTaskQuery().taskId(taskId).singleResult());
    }

    public boolean isTaskOwnerOrAssignee(User user, Task task) {
        String currentUser = String.valueOf(user.getId());
        return currentUser.equals(task.getAssignee()) || currentUser.equals(task.getOwner());
    }

    public boolean validateIfUserIsInitiatorAndCanCompleteTask(User user, Task task) {
        boolean canCompleteTask = false;
        if (task.getProcessInstanceId() != null) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId()).singleResult();
            if (historicProcessInstance != null
                    && StringUtils.isNotEmpty(historicProcessInstance.getStartUserId())) {
                String processInstanceStartUserId = historicProcessInstance.getStartUserId();
                if (String.valueOf(user.getId()).equals(processInstanceStartUserId)) {
                    BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
                    FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
                    if (flowElement != null && flowElement instanceof UserTask) {
                        UserTask userTask = (UserTask) flowElement;
                        List<ExtensionElement> extensionElements = userTask.getExtensionElements()
                                .get("initiator-can-complete");
                        if (CollectionUtils.isNotEmpty(extensionElements)) {
                            String value = extensionElements.get(0).getElementText();
                            if (StringUtils.isNotEmpty(value) && Boolean.valueOf(value)) {
                                canCompleteTask = true;
                            }
                        }
                    }
                }
            }
        }
        return canCompleteTask;
    }

    public boolean isInvolved(User user, String taskId) {
        return historyService.createHistoricTaskInstanceQuery().taskId(taskId)
                .taskInvolvedUser(String.valueOf(user.getId())).count() == 1;
    }

    /**
     * Check if the given user is allowed to read the process instance.
     */
    public boolean hasReadPermissionOnProcessInstance(User user, String processInstanceId) {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        return hasReadPermissionOnProcessInstance(user, historicProcessInstance, processInstanceId);
    }

    /**
     * Check if the given user is allowed to read the process instance.
     */
    public boolean hasReadPermissionOnProcessInstance(User user, HistoricProcessInstance historicProcessInstance,
            String processInstanceId) {
        if (historicProcessInstance == null) {
            throw new NotFoundException("Process instance not found for id " + processInstanceId);
        }

        // Start user check
        if (historicProcessInstance.getStartUserId() != null
                && historicProcessInstance.getStartUserId().equals(user.getId())) {
            return true;
        }

        // check if the user is involved in the task
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService
                .createHistoricProcessInstanceQuery();
        historicProcessInstanceQuery.processInstanceId(processInstanceId);
        historicProcessInstanceQuery.involvedUser(user.getId());
        if (historicProcessInstanceQuery.count() > 0) {
            return true;
        }

        // Visibility: check if there are any tasks for the current user
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
        historicTaskInstanceQuery.processInstanceId(processInstanceId);
        historicTaskInstanceQuery.taskInvolvedUser(user.getId());
        if (historicTaskInstanceQuery.count() > 0) {
            return true;
        }

        List<String> groupIds = getGroupIdsForUser(user);
        if (!groupIds.isEmpty()) {
            historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
            historicTaskInstanceQuery.processInstanceId(processInstanceId).taskCandidateGroupIn(groupIds);
            return historicTaskInstanceQuery.count() > 0;
        }

        return false;
    }

    public boolean canAddRelatedContentToTask(User user, String taskId) {
        validateReadPermissionOnTask(user, taskId);
        return true;
    }

    public boolean canAddRelatedContentToProcessInstance(User user, String processInstanceId) {
        return hasReadPermissionOnProcessInstance(user, processInstanceId);
    }

    public boolean canDownloadContent(User currentUserObject, ContentItem content) {
        if (content.getTaskId() != null) {
            validateReadPermissionOnTask(currentUserObject, content.getTaskId());
            return true;
        } else if (content.getProcessInstanceId() != null) {
            return hasReadPermissionOnProcessInstance(currentUserObject, content.getProcessInstanceId());
        } else {
            return false;
        }
    }

    public boolean hasWritePermissionOnRelatedContent(User user, ContentItem content) {
        if (content.getProcessInstanceId() != null) {
            return hasReadPermissionOnProcessInstance(user, content.getProcessInstanceId());
        } else {
            if (content.getCreatedBy() != null) {
                return content.getCreatedBy().equals(user.getId());
            } else {
                return false;
            }
        }
    }

    public boolean canDeleteProcessInstance(User currentUser, HistoricProcessInstance processInstance) {
        boolean canDelete = false;
        if (processInstance.getStartUserId() != null) {
            try {
                Long starterId = Long.parseLong(processInstance.getStartUserId());
                canDelete = starterId.equals(currentUser.getId());
            } catch (NumberFormatException nfe) {
                // Ignore illegal starter id value
            }
        }

        return canDelete;
    }

}