This is an automated email from the ASF dual-hosted git repository.
SbloodyS pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new a247ec5f94 [Fix-18559][API] Align workflow mutations with project
write permissions (#18561)
a247ec5f94 is described below
commit a247ec5f940afee5fb4eb73004872231d67bc794
Author: Wenjun Ruan <[email protected]>
AuthorDate: Wed Aug 19 14:44:18 2026 +0800
[Fix-18559][API] Align workflow mutations with project write permissions
(#18561)
---
.../api/service/impl/ExecutorServiceImpl.java | 35 +++----
.../api/service/impl/SchedulerServiceImpl.java | 30 +++---
.../service/impl/TaskDefinitionServiceImpl.java | 7 +-
.../api/service/impl/TaskInstanceServiceImpl.java | 14 +--
.../impl/WorkflowDefinitionServiceImpl.java | 53 +++++++----
.../service/impl/WorkflowInstanceServiceImpl.java | 17 +---
.../api/service/ExecutorServiceTest.java | 94 +++++++++++++++---
.../api/service/ProjectServiceTest.java | 15 +++
.../api/service/SchedulerServiceTest.java | 61 +++++++++++-
.../api/service/TaskDefinitionServiceImplTest.java | 22 ++++-
.../api/service/TaskInstanceServiceTest.java | 52 ++++++++--
.../api/service/WorkflowDefinitionServiceTest.java | 106 ++++++++++++++++++---
.../api/service/WorkflowInstanceServiceTest.java | 48 ++++++++--
13 files changed, 426 insertions(+), 128 deletions(-)
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java
index 8950462eaf..55ec3f3f86 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java
@@ -22,7 +22,6 @@ import static
org.apache.dolphinscheduler.common.constants.CommandKeyConstants.C
import static
org.apache.dolphinscheduler.common.constants.CommandKeyConstants.CMD_PARAM_START_NODES;
import static
org.apache.dolphinscheduler.common.constants.CommandKeyConstants.CMD_PARAM_SUB_WORKFLOW_DEFINITION_CODE;
-import org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant;
import org.apache.dolphinscheduler.api.dto.workflow.WorkflowBackFillRequest;
import org.apache.dolphinscheduler.api.dto.workflow.WorkflowTriggerRequest;
import
org.apache.dolphinscheduler.api.dto.workflowInstance.WorkflowExecuteResponse;
@@ -125,11 +124,8 @@ public class ExecutorServiceImpl extends BaseServiceImpl
implements ExecutorServ
@Override
@Transactional
public Integer triggerWorkflowDefinition(final WorkflowTriggerRequest
triggerRequest) {
- // check user access for project
- projectService.checkProjectAndAuthThrowException(
- triggerRequest.getLoginUser(),
- triggerRequest.getProjectCode(),
- ApiFuncIdentificationConstant.RERUN);
+ projectService.checkHasProjectWritePermissionThrowException(
+ triggerRequest.getLoginUser(),
triggerRequest.getProjectCode());
final TriggerWorkflowDTO triggerWorkflowDTO =
triggerWorkflowRequestTransformer.transform(triggerRequest);
// verify the workflow definition belongs to the URL's project
if (triggerWorkflowDTO.getWorkflowDefinition() == null
@@ -145,11 +141,8 @@ public class ExecutorServiceImpl extends BaseServiceImpl
implements ExecutorServ
@Override
@Transactional
public List<Integer> backfillWorkflowDefinition(final
WorkflowBackFillRequest workflowBackFillRequest) {
- // check user access for project
- projectService.checkProjectAndAuthThrowException(
- workflowBackFillRequest.getLoginUser(),
- workflowBackFillRequest.getProjectCode(),
- ApiFuncIdentificationConstant.RERUN);
+ projectService.checkHasProjectWritePermissionThrowException(
+ workflowBackFillRequest.getLoginUser(),
workflowBackFillRequest.getProjectCode());
final BackfillWorkflowDTO backfillWorkflowDTO =
backfillWorkflowRequestTransformer.transform(workflowBackFillRequest);
// verify the workflow definition belongs to the URL's project
@@ -233,11 +226,7 @@ public class ExecutorServiceImpl extends BaseServiceImpl
implements ExecutorServ
.queryOptionalById(workflowInstanceId)
.orElseThrow(() -> new
ServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST, workflowInstanceId));
- // check user access for project
- projectService.checkProjectAndAuthThrowException(
- loginUser,
- workflowInstance.getProjectCode(),
- ApiFuncIdentificationConstant.map.get(executeType));
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
workflowInstance.getProjectCode());
switch (executeType) {
case REPEAT_RUNNING:
@@ -295,9 +284,7 @@ public class ExecutorServiceImpl extends BaseServiceImpl
implements ExecutorServ
WorkflowExecuteResponse response = new WorkflowExecuteResponse();
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode,
-
ApiFuncIdentificationConstant.map.get(ExecuteType.EXECUTE_TASK));
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
WorkflowInstance workflowInstance =
processService.findWorkflowInstanceDetailById(workflowInstanceId)
.orElseThrow(() -> new
ServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST, workflowInstanceId));
@@ -382,10 +369,12 @@ public class ExecutorServiceImpl extends BaseServiceImpl
implements ExecutorServ
public void forceStartTaskInstance(User loginUser, int queueId) {
TaskGroupQueue taskGroupQueue =
taskGroupQueueMapper.selectById(queueId);
// check workflow instance exist
-
workflowInstanceDao.queryOptionalById(taskGroupQueue.getWorkflowInstanceId())
- .orElseThrow(
- () -> new
ServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST,
- taskGroupQueue.getWorkflowInstanceId()));
+ WorkflowInstance workflowInstance =
+
workflowInstanceDao.queryOptionalById(taskGroupQueue.getWorkflowInstanceId())
+ .orElseThrow(
+ () -> new
ServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST,
+
taskGroupQueue.getWorkflowInstanceId()));
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
workflowInstance.getProjectCode());
if (taskGroupQueue.getInQueue() == Flag.NO.getCode()) {
throw new ServiceException(Status.TASK_GROUP_QUEUE_ALREADY_START);
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
index 7b0ae201c9..ad74cf4b91 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SchedulerServiceImpl.java
@@ -18,7 +18,6 @@
package org.apache.dolphinscheduler.api.service.impl;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.PROJECT;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_ONLINE_OFFLINE;
import org.apache.dolphinscheduler.api.dto.ScheduleParam;
import org.apache.dolphinscheduler.api.enums.Status;
@@ -128,8 +127,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
Project project = projectDao.queryByCode(projectCode);
- // check project auth
- projectService.checkProjectAndAuthThrowException(loginUser, project,
null);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
// check workflow define release state
WorkflowDefinition workflowDefinition =
workflowDefinitionDao.queryByCode(workflowDefinitionCode).orElse(null);
@@ -205,8 +203,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
throw new ServiceException(Status.WORKFLOW_DEFINITION_NOT_EXIST,
workflowDefinitionCode);
}
Project project =
projectDao.queryByCode(workflowDefinition.getProjectCode());
- // check project auth
- this.projectService.checkProjectAndAuthThrowException(loginUser,
project, null);
+
this.projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
}
/**
@@ -240,8 +237,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
Project project = projectDao.queryByCode(projectCode);
- // check project auth
- projectService.checkProjectAndAuthThrowException(loginUser, project,
null);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
// check schedule exists
Schedule schedule = scheduleDao.queryById(id);
@@ -430,8 +426,7 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
String tenantCode,
long
environmentCode) {
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
null);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
// check schedule exists
Schedule schedule =
scheduleDao.queryByWorkflowDefinitionCode(workflowDefinitionCode);
@@ -455,8 +450,9 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
@Transactional
@Override
public void onlineScheduler(User loginUser, Long projectCode, Integer
schedulerId) {
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode, WORKFLOW_ONLINE_OFFLINE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
Schedule schedule = scheduleDao.queryById(schedulerId);
+ checkScheduleBelongsToProject(schedule, projectCode);
doOnlineScheduler(schedule);
}
@@ -492,8 +488,9 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
@Transactional
@Override
public void offlineScheduler(User loginUser, Long projectCode, Integer
schedulerId) {
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode, WORKFLOW_ONLINE_OFFLINE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
Schedule schedule = scheduleDao.queryById(schedulerId);
+ checkScheduleBelongsToProject(schedule, projectCode);
doOfflineScheduler(schedule);
}
@@ -521,6 +518,17 @@ public class SchedulerServiceImpl extends BaseServiceImpl
implements SchedulerSe
schedulerApi.deleteScheduleTask(project.getId(), schedule.getId());
}
+ private void checkScheduleBelongsToProject(Schedule schedule, long
projectCode) {
+ if (schedule == null) {
+ return;
+ }
+ WorkflowDefinition workflowDefinition =
+
workflowDefinitionDao.queryByCode(schedule.getWorkflowDefinitionCode()).orElse(null);
+ if (workflowDefinition == null || workflowDefinition.getProjectCode()
!= projectCode) {
+ throw new ServiceException(Status.SCHEDULE_NOT_EXISTS,
schedule.getId());
+ }
+ }
+
private Schedule updateSchedule(Schedule schedule, WorkflowDefinition
workflowDefinition,
String scheduleExpression, WarningType
warningType, int warningGroupId,
FailureStrategy failureStrategy, Priority
workflowInstancePriority,
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java
index 4828f9acd5..5c6be5f86c 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskDefinitionServiceImpl.java
@@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.api.service.impl;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_DEFINITION;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_VERSION_VIEW;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_SWITCH_TO_THIS_VERSION;
import static
org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager.checkTaskParameters;
import org.apache.dolphinscheduler.api.enums.Status;
@@ -502,8 +501,7 @@ public class TaskDefinitionServiceImpl extends
BaseServiceImpl implements TaskDe
@Override
public void switchVersion(User loginUser, long projectCode, long taskCode,
int version) {
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
WORKFLOW_SWITCH_TO_THIS_VERSION);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
if (processService.isTaskOnline(taskCode)) {
log.warn(
@@ -643,8 +641,7 @@ public class TaskDefinitionServiceImpl extends
BaseServiceImpl implements TaskDe
@Override
public void releaseTaskDefinition(User loginUser, long projectCode, long
code, ReleaseState releaseState) {
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
null);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
if (null == releaseState) {
throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR,
Constants.RELEASE_STATE);
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskInstanceServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskInstanceServiceImpl.java
index bbbd28737d..93e010e248 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskInstanceServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskInstanceServiceImpl.java
@@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.api.service.impl;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.FORCED_SUCCESS;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_INSTANCE;
import org.apache.dolphinscheduler.api.enums.Status;
@@ -196,8 +195,7 @@ public class TaskInstanceServiceImpl extends
BaseServiceImpl implements TaskInst
@Transactional
@Override
public void forceTaskSuccess(User loginUser, long projectCode, Integer
taskInstanceId) {
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode, FORCED_SUCCESS);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
TaskInstance task = taskInstanceDao.queryOptionalById(taskInstanceId)
.orElseThrow(() -> new
ServiceException(Status.TASK_INSTANCE_NOT_FOUND));
@@ -235,11 +233,10 @@ public class TaskInstanceServiceImpl extends
BaseServiceImpl implements TaskInst
Result result = new Result();
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
FORCED_SUCCESS);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
TaskInstance taskInstance = taskInstanceDao.queryById(taskInstanceId);
- if (taskInstance == null) {
+ if (taskInstance == null || taskInstance.getProjectCode() !=
projectCode) {
log.error("Task definition can not be found, projectCode:{},
taskInstanceId:{}.", projectCode,
taskInstanceId);
putMsg(result, Status.TASK_INSTANCE_NOT_FOUND);
@@ -259,11 +256,10 @@ public class TaskInstanceServiceImpl extends
BaseServiceImpl implements TaskInst
Result result = new Result();
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
FORCED_SUCCESS);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
TaskInstance taskInstance = taskInstanceDao.queryById(taskInstanceId);
- if (taskInstance == null) {
+ if (taskInstance == null || taskInstance.getProjectCode() !=
projectCode) {
log.error("Task definition can not be found, projectCode:{},
taskInstanceId:{}.", projectCode,
taskInstanceId);
putMsg(result, Status.TASK_INSTANCE_NOT_FOUND);
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java
index fecf8ec406..d777635ac1 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowDefinitionServiceImpl.java
@@ -22,9 +22,6 @@ import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationCon
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_BATCH_COPY;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_CREATE;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_DEFINITION;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_DEFINITION_DELETE;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_ONLINE_OFFLINE;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_SWITCH_TO_THIS_VERSION;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_TREE_VIEW;
import static
org.apache.dolphinscheduler.api.enums.Status.WORKFLOW_DEFINITION_NOT_EXIST;
import static
org.apache.dolphinscheduler.common.constants.CommandKeyConstants.CMD_PARAM_SUB_WORKFLOW_DEFINITION_CODE;
@@ -863,8 +860,7 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
.orElseThrow(() -> new
ServiceException(WORKFLOW_DEFINITION_NOT_EXIST, String.valueOf(code)));
Project project =
projectDao.queryByCode(workflowDefinition.getProjectCode());
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
WORKFLOW_DEFINITION_DELETE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
// Determine if the login user is the owner of the workflow definition
if (loginUser.getId() != workflowDefinition.getUserId() &&
loginUser.getUserType() != UserType.ADMIN_USER) {
@@ -1264,9 +1260,9 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
long projectCode,
String codes,
long targetProjectCode) {
- checkParams(loginUser, projectCode, codes, targetProjectCode,
WORKFLOW_BATCH_COPY);
+ checkParams(loginUser, projectCode, codes, targetProjectCode,
WORKFLOW_BATCH_COPY, false);
List<String> failedWorkflowList = new ArrayList<>();
- doBatchOperateWorkflowDefinition(loginUser, targetProjectCode,
failedWorkflowList, codes, true);
+ doBatchOperateWorkflowDefinition(loginUser, projectCode,
targetProjectCode, failedWorkflowList, codes, true);
checkBatchOperateResult(projectCode, targetProjectCode,
failedWorkflowList, true);
}
@@ -1285,24 +1281,29 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
long projectCode,
String codes,
long targetProjectCode) {
- checkParams(loginUser, projectCode, codes, targetProjectCode,
TASK_DEFINITION_MOVE);
+ checkParams(loginUser, projectCode, codes, targetProjectCode,
TASK_DEFINITION_MOVE, true);
if (projectCode == targetProjectCode) {
log.warn("Project code is same as target project code,
projectCode:{}.", projectCode);
return;
}
List<String> failedWorkflowList = new ArrayList<>();
- doBatchOperateWorkflowDefinition(loginUser, targetProjectCode,
failedWorkflowList, codes, false);
+ doBatchOperateWorkflowDefinition(loginUser, projectCode,
targetProjectCode, failedWorkflowList, codes, false);
checkBatchOperateResult(projectCode, targetProjectCode,
failedWorkflowList, false);
}
private void checkParams(User loginUser,
long projectCode,
String workflowDefinitionCodes,
- long targetProjectCode, String perm) {
+ long targetProjectCode,
+ String perm,
+ boolean requireSourceWritePermission) {
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
perm);
+ if (requireSourceWritePermission) {
+
projectService.checkHasProjectWritePermissionThrowException(loginUser, project);
+ } else {
+ projectService.checkProjectAndAuthThrowException(loginUser,
project, perm);
+ }
if (StringUtils.isEmpty(workflowDefinitionCodes)) {
log.error("Parameter workflowDefinitionCodes is empty, projectCode
is {}.", projectCode);
@@ -1311,12 +1312,14 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
if (projectCode != targetProjectCode) {
Project targetProject = projectDao.queryByCode(targetProjectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser,
targetProject, perm);
+
projectService.checkHasProjectWritePermissionThrowException(loginUser,
targetProject);
+ } else if (!requireSourceWritePermission) {
+
projectService.checkHasProjectWritePermissionThrowException(loginUser, project);
}
}
protected void doBatchOperateWorkflowDefinition(User loginUser,
+ long sourceProjectCode,
long targetProjectCode,
List<String>
failedWorkflowList,
String
workflowDefinitionCodes,
@@ -1324,13 +1327,16 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
Set<Long> definitionCodes =
Arrays.stream(workflowDefinitionCodes.split(Constants.COMMA)).map(Long::parseLong)
.collect(Collectors.toSet());
List<WorkflowDefinition> workflowDefinitionList =
workflowDefinitionDao.queryByCodes(definitionCodes);
- Set<Long> queryCodes =
-
workflowDefinitionList.stream().map(WorkflowDefinition::getCode).collect(Collectors.toSet());
+ List<WorkflowDefinition> sourceWorkflowDefinitionList =
workflowDefinitionList.stream()
+ .filter(workflowDefinition ->
workflowDefinition.getProjectCode() == sourceProjectCode)
+ .collect(Collectors.toList());
+ Set<Long> queryCodes =
sourceWorkflowDefinitionList.stream().map(WorkflowDefinition::getCode)
+ .collect(Collectors.toSet());
// definitionCodes - queryCodes
Set<Long> diffCode =
definitionCodes.stream().filter(code ->
!queryCodes.contains(code)).collect(Collectors.toSet());
diffCode.forEach(code -> failedWorkflowList.add(code + "[null]"));
- for (WorkflowDefinition workflowDefinition : workflowDefinitionList) {
+ for (WorkflowDefinition workflowDefinition :
sourceWorkflowDefinitionList) {
List<WorkflowTaskRelation> workflowTaskRelations =
workflowTaskRelationDao.queryByWorkflowDefinitionCode(workflowDefinition.getCode());
List<WorkflowTaskRelationLog> taskRelationList =
@@ -1563,8 +1569,7 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
public void switchWorkflowDefinitionVersion(User loginUser, long
projectCode, long code,
int version) {
Project project = projectDao.queryByCode(projectCode);
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
WORKFLOW_SWITCH_TO_THIS_VERSION);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
WorkflowDefinition workflowDefinition =
workflowDefinitionDao.queryByCode(code).orElse(null);
if (Objects.isNull(workflowDefinition) || projectCode !=
workflowDefinition.getProjectCode()) {
@@ -1737,10 +1742,13 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
@Transactional
@Override
public void onlineWorkflowDefinition(User loginUser, Long projectCode,
Long workflowDefinitionCode) {
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode, WORKFLOW_ONLINE_OFFLINE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
WorkflowDefinition workflowDefinition =
workflowDefinitionDao.queryByCode(workflowDefinitionCode)
.orElseThrow(() -> new
ServiceException(Status.WORKFLOW_DEFINITION_NOT_EXIST, workflowDefinitionCode));
+ if (projectCode != workflowDefinition.getProjectCode()) {
+ throw new ServiceException(Status.WORKFLOW_DEFINITION_NOT_EXIST,
workflowDefinitionCode);
+ }
if (ReleaseState.ONLINE.equals(workflowDefinition.getReleaseState())) {
// do nothing if the workflow is already online
@@ -1757,10 +1765,13 @@ public class WorkflowDefinitionServiceImpl extends
BaseServiceImpl implements Wo
@Transactional
@Override
public void offlineWorkflowDefinition(User loginUser, Long projectCode,
Long workflowDefinitionCode) {
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode, WORKFLOW_ONLINE_OFFLINE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
WorkflowDefinition workflowDefinition =
workflowDefinitionDao.queryByCode(workflowDefinitionCode)
.orElseThrow(() -> new
ServiceException(Status.WORKFLOW_DEFINITION_NOT_EXIST, workflowDefinitionCode));
+ if (projectCode != workflowDefinition.getProjectCode()) {
+ throw new ServiceException(Status.WORKFLOW_DEFINITION_NOT_EXIST,
workflowDefinitionCode);
+ }
if (ReleaseState.OFFLINE.equals(workflowDefinition.getReleaseState()))
{
// do nothing if the workflow is already offline
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java
index 7ae496636b..96cfde7061 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkflowInstanceServiceImpl.java
@@ -26,7 +26,6 @@ import static
org.apache.dolphinscheduler.common.constants.Constants.SUBWORKFLOW
import static org.apache.dolphinscheduler.common.utils.JSONUtils.parseObject;
import static
org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager.checkTaskParameters;
-import org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant;
import org.apache.dolphinscheduler.api.dto.gantt.GanttDto;
import org.apache.dolphinscheduler.api.dto.gantt.Task;
import
org.apache.dolphinscheduler.api.dto.workflowInstance.WorkflowInstanceTaskListDTO;
@@ -369,18 +368,14 @@ public class WorkflowInstanceServiceImpl extends
BaseServiceImpl implements Work
Boolean syncDefine,
String globalParams,
String locations, int
timeout) {
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser,
projectCode,
- ApiFuncIdentificationConstant.INSTANCE_UPDATE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
// check workflow instance exists
WorkflowInstance workflowInstance =
processService.findWorkflowInstanceDetailById(workflowInstanceId)
.orElseThrow(() -> new
ServiceException(WORKFLOW_INSTANCE_NOT_EXIST, workflowInstanceId));
// check workflow instance exists in project
- WorkflowDefinition workflowDefinition0 =
-
workflowDefinitionDao.queryByCode(workflowInstance.getWorkflowDefinitionCode()).orElse(null);
- if (workflowDefinition0 != null && projectCode !=
workflowDefinition0.getProjectCode()) {
- log.error("workflow definition does not exist, projectCode:{},
workflowDefinitionCode:{}.", projectCode,
- workflowInstance.getWorkflowDefinitionCode());
+ if (workflowInstance.getProjectCode() != projectCode) {
+ log.error("workflow instance does not exist, projectCode:{},
workflowInstanceId:{}.", projectCode,
+ workflowInstanceId);
throw new ServiceException(WORKFLOW_INSTANCE_NOT_EXIST,
workflowInstanceId);
}
// check workflow instance status
@@ -519,9 +514,7 @@ public class WorkflowInstanceServiceImpl extends
BaseServiceImpl implements Work
workflowInstance.getWorkflowDefinitionCode(),
workflowInstance.getWorkflowDefinitionVersion());
Project project =
projectDao.queryByCode(workflowDefinition.getProjectCode());
- // check user access for project
- projectService.checkProjectAndAuthThrowException(loginUser, project,
- ApiFuncIdentificationConstant.INSTANCE_DELETE);
+ projectService.checkHasProjectWritePermissionThrowException(loginUser,
project);
// check workflow instance status
if (!workflowInstance.getState().isFinalState()) {
log.warn("workflow Instance state is {} so can not delete workflow
instance, workflowInstanceId:{}.",
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java
index c8b8b6db12..d820926e9e 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java
@@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.api.service;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.RERUN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doNothing;
@@ -28,6 +27,7 @@ import static org.mockito.Mockito.when;
import org.apache.dolphinscheduler.api.dto.workflow.WorkflowBackFillRequest;
import org.apache.dolphinscheduler.api.dto.workflow.WorkflowTriggerRequest;
+import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
import
org.apache.dolphinscheduler.api.executor.workflow.BackfillWorkflowExecutorDelegate;
@@ -41,9 +41,17 @@ import
org.apache.dolphinscheduler.api.validator.workflow.BackfillWorkflowReques
import org.apache.dolphinscheduler.api.validator.workflow.TriggerWorkflowDTO;
import
org.apache.dolphinscheduler.api.validator.workflow.TriggerWorkflowDTOValidator;
import
org.apache.dolphinscheduler.api.validator.workflow.TriggerWorkflowRequestTransformer;
+import org.apache.dolphinscheduler.common.enums.TaskDependType;
import org.apache.dolphinscheduler.common.enums.UserType;
+import org.apache.dolphinscheduler.dao.entity.TaskGroupQueue;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.entity.WorkflowDefinition;
+import org.apache.dolphinscheduler.dao.entity.WorkflowInstance;
+import org.apache.dolphinscheduler.dao.mapper.TaskGroupQueueMapper;
+import org.apache.dolphinscheduler.dao.repository.WorkflowInstanceDao;
+import org.apache.dolphinscheduler.service.process.ProcessService;
+
+import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -85,6 +93,15 @@ public class ExecutorServiceTest {
@Mock
private BackfillWorkflowExecutorDelegate backfillWorkflowExecutorDelegate;
+ @Mock
+ private WorkflowInstanceDao workflowInstanceDao;
+
+ @Mock
+ private TaskGroupQueueMapper taskGroupQueueMapper;
+
+ @Mock
+ private ProcessService processService;
+
private User getLoginUser() {
User user = new User();
user.setId(1);
@@ -94,7 +111,7 @@ public class ExecutorServiceTest {
}
@Test
- public void testTriggerWorkflowDefinition_userHasNoProjectPermission() {
+ public void
testTriggerWorkflowDefinition_userHasNoProjectWritePermission() {
long projectCode = 100L;
long workflowDefinitionCode = 200L;
User loginUser = getLoginUser();
@@ -105,14 +122,14 @@ public class ExecutorServiceTest {
.workflowDefinitionCode(workflowDefinitionCode)
.build();
- doThrow(new ServiceException(Status.USER_NO_OPERATION_PROJECT_PERM,
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
loginUser.getUserName(), projectCode))
.when(projectService)
- .checkProjectAndAuthThrowException(loginUser,
projectCode, RERUN);
+
.checkHasProjectWritePermissionThrowException(loginUser, projectCode);
ServiceException ex = assertThrows(ServiceException.class,
() -> executorService.triggerWorkflowDefinition(request));
- assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM.getCode(),
ex.getCode());
+ assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
verify(triggerWorkflowRequestTransformer,
never()).transform(Mockito.any());
verify(triggerWorkflowDTOValidator, never()).validate(Mockito.any());
@@ -132,7 +149,7 @@ public class ExecutorServiceTest {
.build();
doNothing().when(projectService)
- .checkProjectAndAuthThrowException(loginUser, projectCode,
RERUN);
+ .checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
WorkflowDefinition workflowDefinition = new WorkflowDefinition();
workflowDefinition.setCode(workflowDefinitionCode);
@@ -151,7 +168,7 @@ public class ExecutorServiceTest {
}
@Test
- public void testBackfillWorkflowDefinition_userHasNoProjectPermission() {
+ public void
testBackfillWorkflowDefinition_userHasNoProjectWritePermission() {
long projectCode = 100L;
long workflowDefinitionCode = 200L;
User loginUser = getLoginUser();
@@ -162,14 +179,14 @@ public class ExecutorServiceTest {
.workflowDefinitionCode(workflowDefinitionCode)
.build();
- doThrow(new ServiceException(Status.USER_NO_OPERATION_PROJECT_PERM,
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
loginUser.getUserName(), projectCode))
.when(projectService)
- .checkProjectAndAuthThrowException(loginUser,
projectCode, RERUN);
+
.checkHasProjectWritePermissionThrowException(loginUser, projectCode);
ServiceException ex = assertThrows(ServiceException.class,
() -> executorService.backfillWorkflowDefinition(request));
- assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM.getCode(),
ex.getCode());
+ assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
verify(backfillWorkflowRequestTransformer,
never()).transform(Mockito.any());
verify(backfillWorkflowDTOValidator, never()).validate(Mockito.any());
@@ -189,7 +206,7 @@ public class ExecutorServiceTest {
.build();
doNothing().when(projectService)
- .checkProjectAndAuthThrowException(loginUser, projectCode,
RERUN);
+ .checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
WorkflowDefinition workflowDefinition = new WorkflowDefinition();
workflowDefinition.setCode(workflowDefinitionCode);
@@ -206,4 +223,59 @@ public class ExecutorServiceTest {
verify(backfillWorkflowDTOValidator, never()).validate(Mockito.any());
}
+
+ @Test
+ public void testControlWorkflowInstance_userHasNoProjectWritePermission() {
+ long projectCode = 100L;
+ int workflowInstanceId = 1;
+ User loginUser = getLoginUser();
+ WorkflowInstance workflowInstance = new WorkflowInstance();
+ workflowInstance.setProjectCode(projectCode);
+
when(workflowInstanceDao.queryOptionalById(workflowInstanceId)).thenReturn(Optional.of(workflowInstance));
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
+
+ ServiceException ex = assertThrows(ServiceException.class,
+ () -> executorService.controlWorkflowInstance(
+ loginUser, workflowInstanceId,
ExecuteType.REPEAT_RUNNING));
+
+ assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
+ Mockito.verifyNoInteractions(executorClient);
+ }
+
+ @Test
+ public void testExecuteTask_userHasNoProjectWritePermission() {
+ long projectCode = 100L;
+ User loginUser = getLoginUser();
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
+
+ ServiceException ex = assertThrows(ServiceException.class,
+ () -> executorService.executeTask(loginUser, projectCode, 1,
"1", TaskDependType.TASK_POST));
+
+ assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
+ Mockito.verifyNoInteractions(processService);
+ }
+
+ @Test
+ public void testForceStartTaskInstance_userHasNoProjectWritePermission() {
+ long projectCode = 100L;
+ int workflowInstanceId = 1;
+ int queueId = 2;
+ User loginUser = getLoginUser();
+ TaskGroupQueue taskGroupQueue = new TaskGroupQueue();
+ taskGroupQueue.setWorkflowInstanceId(workflowInstanceId);
+ WorkflowInstance workflowInstance = new WorkflowInstance();
+ workflowInstance.setProjectCode(projectCode);
+
when(taskGroupQueueMapper.selectById(queueId)).thenReturn(taskGroupQueue);
+
when(workflowInstanceDao.queryOptionalById(workflowInstanceId)).thenReturn(Optional.of(workflowInstance));
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
+
+ ServiceException ex = assertThrows(ServiceException.class,
+ () -> executorService.forceStartTaskInstance(loginUser,
queueId));
+
+ assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
+ verify(taskGroupQueueMapper, never()).updateById(Mockito.any());
+ }
}
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
index 66fbbebe75..988c83784a 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
@@ -31,9 +31,11 @@ import
org.apache.dolphinscheduler.api.service.impl.BaseServiceImpl;
import org.apache.dolphinscheduler.api.service.impl.ProjectServiceImpl;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.Project;
+import org.apache.dolphinscheduler.dao.entity.ProjectUser;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.entity.WorkflowDefinition;
import org.apache.dolphinscheduler.dao.repository.ProjectDao;
@@ -170,6 +172,19 @@ public class ProjectServiceTest {
() ->
projectService.checkHasProjectWritePermissionThrowException(loginUser,
project));
Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
noWriteEx.getCode());
+ // USER_NO_WRITE_PROJECT_PERM: read-only project member
+ ProjectUser projectUser = new ProjectUser();
+ projectUser.setPerm(Constants.READ_PERMISSION);
+ Mockito.when(projectUserDao.queryProjectRelation(project.getId(),
loginUser.getId())).thenReturn(projectUser);
+ ServiceException readOnlyEx =
Assertions.assertThrows(ServiceException.class,
+ () ->
projectService.checkHasProjectWritePermissionThrowException(loginUser,
project));
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
readOnlyEx.getCode());
+
+ // success: project member with write permission
+ projectUser.setPerm(Constants.DEFAULT_ADMIN_PERMISSION);
+ Assertions.assertDoesNotThrow(
+ () ->
projectService.checkHasProjectWritePermissionThrowException(loginUser,
project));
+
// success: admin
loginUser.setUserType(UserType.ADMIN_USER);
Assertions.assertDoesNotThrow(
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java
index 3c9a9dedc6..67572905ac 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SchedulerServiceTest.java
@@ -303,16 +303,17 @@ public class SchedulerServiceTest extends
BaseServiceTestTool {
// error project permissions
Mockito.when(workflowDefinitionDao.queryByCode(processDefinitionCode))
.thenReturn(Optional.of(this.getProcessDefinition()));
-
Mockito.when(projectDao.queryByCode(projectCode)).thenReturn(this.getProject());
- Mockito.doThrow(new
ServiceException(Status.USER_NO_OPERATION_PROJECT_PERM)).when(projectService)
- .checkProjectAndAuthThrowException(user, this.getProject(),
null);
+ Project project = this.getProject();
+ Mockito.when(projectDao.queryByCode(projectCode)).thenReturn(project);
+ Mockito.doThrow(new
ServiceException(Status.USER_NO_WRITE_PROJECT_PERM)).when(projectService)
+ .checkHasProjectWritePermissionThrowException(user, project);
exception = Assertions.assertThrows(ServiceException.class,
() -> schedulerService.deleteSchedulesById(user, scheduleId));
-
Assertions.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM.getCode(),
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
((ServiceException) exception).getCode());
// error delete mapper
-
Mockito.doNothing().when(projectService).checkProjectAndAuthThrowException(user,
this.getProject(), null);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
Mockito.when(scheduleDao.deleteById(scheduleId)).thenReturn(false);
exception = Assertions.assertThrows(ServiceException.class,
() -> schedulerService.deleteSchedulesById(user, scheduleId));
@@ -323,6 +324,56 @@ public class SchedulerServiceTest extends
BaseServiceTestTool {
Assertions.assertDoesNotThrow(() ->
schedulerService.deleteSchedulesById(user, scheduleId));
}
+ @Test
+ public void testReadOnlyUserCannotChangeSchedule() {
+ Project project = this.getProject();
+ Mockito.when(projectDao.queryByCode(projectCode)).thenReturn(project);
+ Mockito.doThrow(new
ServiceException(Status.USER_NO_WRITE_PROJECT_PERM)).when(projectService)
+ .checkHasProjectWritePermissionThrowException(user, project);
+ Mockito.doThrow(new
ServiceException(Status.USER_NO_WRITE_PROJECT_PERM)).when(projectService)
+ .checkHasProjectWritePermissionThrowException(user,
projectCode);
+
+ Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.insertSchedule(
+ user, projectCode, processDefinitionCode,
scheduleExpression(null), WarningType.NONE, 0,
+ FailureStrategy.CONTINUE, Priority.MEDIUM, "default",
"tenantCode", environmentCode));
+ Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.updateSchedule(
+ user, projectCode, scheduleId,
scheduleExpression(null), WarningType.NONE, 0,
+ FailureStrategy.CONTINUE, Priority.MEDIUM, "default",
"tenantCode", environmentCode));
+ Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.updateScheduleByWorkflowDefinitionCode(
+ user, projectCode, processDefinitionCode,
scheduleExpression(null), WarningType.NONE, 0,
+ FailureStrategy.CONTINUE, Priority.MEDIUM, "default",
"tenantCode", environmentCode));
+ Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.onlineScheduler(user, projectCode,
scheduleId));
+ Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.offlineScheduler(user, projectCode,
scheduleId));
+
+ Mockito.verify(scheduleDao, Mockito.never()).insert(Mockito.any());
+ Mockito.verify(scheduleDao, Mockito.never()).updateById(Mockito.any());
+ }
+
+ @Test
+ public void testProjectCodeCannotAuthorizeScheduleFromAnotherProject() {
+ Schedule schedule = this.getSchedule();
+ WorkflowDefinition workflowDefinition = this.getProcessDefinition();
+ workflowDefinition.setProjectCode(2L);
+ Mockito.when(scheduleDao.queryById(scheduleId)).thenReturn(schedule);
+ Mockito.when(workflowDefinitionDao.queryByCode(processDefinitionCode))
+ .thenReturn(Optional.of(workflowDefinition));
+
+ ServiceException onlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.onlineScheduler(user, projectCode,
scheduleId));
+ ServiceException offlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> schedulerService.offlineScheduler(user, projectCode,
scheduleId));
+
+ Assertions.assertEquals(Status.SCHEDULE_NOT_EXISTS.getCode(),
onlineEx.getCode());
+ Assertions.assertEquals(Status.SCHEDULE_NOT_EXISTS.getCode(),
offlineEx.getCode());
+ Mockito.verify(scheduleDao, Mockito.never()).updateById(Mockito.any());
+ Mockito.verifyNoInteractions(schedulerApi);
+ }
+
private Project getProject() {
Project project = new Project();
project.setId(1);
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskDefinitionServiceImplTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskDefinitionServiceImplTest.java
index c749e77e70..d85ee6ef3f 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskDefinitionServiceImplTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskDefinitionServiceImplTest.java
@@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.api.service;
import static
org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowsServiceException;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_DEFINITION;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_SWITCH_TO_THIS_VERSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -169,8 +168,7 @@ public class TaskDefinitionServiceImplTest {
public void switchVersion() {
Project project = getProject();
when(projectDao.queryByCode(PROJECT_CODE)).thenReturn(project);
- Mockito.doNothing().when(projectService)
- .checkProjectAndAuthThrowException(user, project,
WORKFLOW_SWITCH_TO_THIS_VERSION);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
when(taskDefinitionLogMapper.queryByDefinitionCodeAndVersion(TASK_CODE,
VERSION))
.thenReturn(new TaskDefinitionLog());
@@ -255,7 +253,7 @@ public class TaskDefinitionServiceImplTest {
public void testReleaseTaskDefinition() {
when(projectDao.queryByCode(PROJECT_CODE)).thenReturn(getProject());
Project project = getProject();
-
Mockito.doNothing().when(projectService).checkProjectAndAuthThrowException(user,
project, null);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
// check task dose not exist
assertThrowsServiceException(Status.TASK_DEFINE_NOT_EXIST,
@@ -287,6 +285,22 @@ public class TaskDefinitionServiceImplTest {
ReleaseState.getEnum(2)));
}
+ @Test
+ public void testReadOnlyUserCannotChangeTaskDefinition() {
+ Project project = getProject();
+ when(projectDao.queryByCode(PROJECT_CODE)).thenReturn(project);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
+
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
+ () -> taskDefinitionService.switchVersion(user, PROJECT_CODE,
TASK_CODE, VERSION));
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
+ () -> taskDefinitionService.releaseTaskDefinition(
+ user, PROJECT_CODE, TASK_CODE, ReleaseState.ONLINE));
+
+ Mockito.verifyNoInteractions(taskDefinitionDao,
taskDefinitionLogMapper);
+ }
+
@Test
public void testUpdateDag() {
User loginUser = getLoginUser();
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskInstanceServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskInstanceServiceTest.java
index a977a3a6c1..d7f5771121 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskInstanceServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TaskInstanceServiceTest.java
@@ -18,7 +18,6 @@
package org.apache.dolphinscheduler.api.service;
import static
org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowsServiceException;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.FORCED_SUCCESS;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_INSTANCE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -336,17 +335,19 @@ public class TaskInstanceServiceTest {
public void testForceTaskSuccess_withNoPermission() {
User user = getAdminUser();
TaskInstance task = getTaskInstance();
- doThrow(new
ServiceException(Status.USER_NO_OPERATION_PROJECT_PERM)).when(projectService)
- .checkProjectAndAuthThrowException(user,
task.getProjectCode(), FORCED_SUCCESS);
- assertThrowsServiceException(Status.USER_NO_OPERATION_PROJECT_PERM,
+ doThrow(new
ServiceException(Status.USER_NO_WRITE_PROJECT_PERM)).when(projectService)
+ .checkHasProjectWritePermissionThrowException(user,
task.getProjectCode());
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
() -> taskInstanceService.forceTaskSuccess(user,
task.getProjectCode(), task.getId()));
+ Mockito.verifyNoInteractions(taskInstanceDao);
}
@Test
public void testForceTaskSuccess_withTaskInstanceNotFound() {
User user = getAdminUser();
TaskInstance task = getTaskInstance();
-
doNothing().when(projectService).checkProjectAndAuthThrowException(user,
task.getProjectCode(), FORCED_SUCCESS);
+ doNothing().when(projectService)
+ .checkHasProjectWritePermissionThrowException(user,
task.getProjectCode());
when(taskInstanceDao.queryOptionalById(task.getId())).thenReturn(Optional.empty());
assertThrowsServiceException(Status.TASK_INSTANCE_NOT_FOUND,
() -> taskInstanceService.forceTaskSuccess(user,
task.getProjectCode(), task.getId()));
@@ -356,7 +357,8 @@ public class TaskInstanceServiceTest {
public void testForceTaskSuccess_withWorkflowInstanceNotFound() {
User user = getAdminUser();
TaskInstance task = getTaskInstance();
-
doNothing().when(projectService).checkProjectAndAuthThrowException(user,
task.getProjectCode(), FORCED_SUCCESS);
+ doNothing().when(projectService)
+ .checkHasProjectWritePermissionThrowException(user,
task.getProjectCode());
when(taskInstanceDao.queryOptionalById(task.getId())).thenReturn(Optional.of(task));
when(workflowInstanceDao.queryOptionalById(task.getWorkflowInstanceId())).thenReturn(Optional.empty());
@@ -371,7 +373,7 @@ public class TaskInstanceServiceTest {
TaskInstance task = getTaskInstance();
WorkflowInstance workflowInstance = getProcessInstance();
workflowInstance.setState(WorkflowExecutionStatus.RUNNING_EXECUTION);
-
doNothing().when(projectService).checkProjectAndAuthThrowException(user,
projectCode, FORCED_SUCCESS);
+
doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
projectCode);
when(taskInstanceDao.queryOptionalById(task.getId())).thenReturn(Optional.of(task));
when(workflowInstanceDao.queryOptionalById(task.getWorkflowInstanceId()))
.thenReturn(Optional.of(workflowInstance));
@@ -388,7 +390,8 @@ public class TaskInstanceServiceTest {
TaskInstance task = getTaskInstance();
WorkflowInstance workflowInstance = getProcessInstance();
workflowInstance.setState(WorkflowExecutionStatus.FAILURE);
-
doNothing().when(projectService).checkProjectAndAuthThrowException(user,
task.getProjectCode(), FORCED_SUCCESS);
+ doNothing().when(projectService)
+ .checkHasProjectWritePermissionThrowException(user,
task.getProjectCode());
when(taskInstanceDao.queryOptionalById(task.getId())).thenReturn(Optional.of(task));
when(workflowInstanceDao.queryOptionalById(task.getWorkflowInstanceId()))
.thenReturn(Optional.of(workflowInstance));
@@ -398,4 +401,37 @@ public class TaskInstanceServiceTest {
() -> taskInstanceService.forceTaskSuccess(user,
task.getProjectCode(), task.getId()));
}
+ @Test
+ public void testReadOnlyUserCannotSavepointOrStopTask() {
+ long projectCode = 1L;
+ User user = getAdminUser();
+ Project project = getProject(projectCode);
+ when(projectDao.queryByCode(projectCode)).thenReturn(project);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
+
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
+ () -> taskInstanceService.taskSavePoint(user, projectCode, 1));
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
+ () -> taskInstanceService.stopTask(user, projectCode, 1));
+ Mockito.verifyNoInteractions(taskInstanceDao);
+ }
+
+ @Test
+ public void testProjectCodeCannotAuthorizeTaskFromAnotherProject() {
+ long projectCode = 1L;
+ User user = getAdminUser();
+ Project project = getProject(projectCode);
+ TaskInstance taskInstance = getTaskInstance();
+ taskInstance.setProjectCode(2L);
+ when(projectDao.queryByCode(projectCode)).thenReturn(project);
+
when(taskInstanceDao.queryById(taskInstance.getId())).thenReturn(taskInstance);
+
+ Result savepointResult = taskInstanceService.taskSavePoint(user,
projectCode, taskInstance.getId());
+ Result stopResult = taskInstanceService.stopTask(user, projectCode,
taskInstance.getId());
+
+ Assertions.assertEquals(Status.TASK_INSTANCE_NOT_FOUND.getCode(),
savepointResult.getCode());
+ Assertions.assertEquals(Status.TASK_INSTANCE_NOT_FOUND.getCode(),
stopResult.getCode());
+ }
+
}
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowDefinitionServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowDefinitionServiceTest.java
index 3ea6da8fb3..b26d0da000 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowDefinitionServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowDefinitionServiceTest.java
@@ -17,11 +17,9 @@
package org.apache.dolphinscheduler.api.service;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_DEFINITION_MOVE;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_BATCH_COPY;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_CREATE;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_DEFINITION;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_DEFINITION_DELETE;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_TREE_VIEW;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -469,14 +467,14 @@ public class WorkflowDefinitionServiceTest extends
BaseServiceTestTool {
Assertions.assertEquals(Status.PROJECT_NOT_FOUND.getCode(),
ex.getCode());
// project check auth success, target project name not equal project
name
- Mockito.doNothing().when(projectService)
- .checkProjectAndAuthThrowException(user, project,
WORKFLOW_BATCH_COPY);
Project project1 = getProject(projectCodeOther);
when(projectDao.queryByCode(projectCodeOther)).thenReturn(project1);
Mockito.doNothing().when(projectService)
.checkProjectAndAuthThrowException(user, project1,
WORKFLOW_BATCH_COPY);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
WorkflowDefinition definition = getWorkflowDefinition();
+ definition.setProjectCode(projectCodeOther);
List<WorkflowDefinition> workflowDefinitionList = new ArrayList<>();
workflowDefinitionList.add(definition);
Set<Long> definitionCodes = new HashSet<>();
@@ -503,10 +501,8 @@ public class WorkflowDefinitionServiceTest extends
BaseServiceTestTool {
Project project2 = getProject(projectCodeOther);
when(projectDao.queryByCode(projectCodeOther)).thenReturn(project2);
- Mockito.doNothing().when(projectService)
- .checkProjectAndAuthThrowException(user, project1,
TASK_DEFINITION_MOVE);
- Mockito.doNothing().when(projectService)
- .checkProjectAndAuthThrowException(user, project2,
TASK_DEFINITION_MOVE);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project1);
+
Mockito.doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project2);
WorkflowDefinition definition = getWorkflowDefinition();
definition.setVersion(1);
@@ -531,6 +527,91 @@ public class WorkflowDefinitionServiceTest extends
BaseServiceTestTool {
user, projectCode, String.valueOf(processDefinitionCode),
projectCodeOther));
}
+ @Test
+ public void
testBatchCopyWorkflowDefinitionRequiresTargetProjectWritePermission() {
+ Project sourceProject = getProject(projectCode);
+ Project targetProject = getProject(projectCodeOther);
+ when(projectDao.queryByCode(projectCode)).thenReturn(sourceProject);
+
when(projectDao.queryByCode(projectCodeOther)).thenReturn(targetProject);
+ doNothing().when(projectService)
+ .checkProjectAndAuthThrowException(user, sourceProject,
WORKFLOW_BATCH_COPY);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(user,
targetProject);
+
+ ServiceException ex = Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.batchCopyWorkflowDefinition(
+ user, projectCode,
String.valueOf(processDefinitionCode), projectCodeOther));
+
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
ex.getCode());
+ verify(workflowDefinitionDao,
Mockito.never()).queryByCodes(Mockito.anySet());
+ }
+
+ @Test
+ public void
testBatchMoveWorkflowDefinitionRejectsDefinitionOutsideSourceProject() {
+ Project sourceProject = getProject(projectCode);
+ Project targetProject = getProject(projectCodeOther);
+ when(projectDao.queryByCode(projectCode)).thenReturn(sourceProject);
+
when(projectDao.queryByCode(projectCodeOther)).thenReturn(targetProject);
+
doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
sourceProject);
+
doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
targetProject);
+
+ WorkflowDefinition definition = getWorkflowDefinition();
+ definition.setProjectCode(3L);
+
when(workflowDefinitionDao.queryByCodes(Collections.singleton(processDefinitionCode)))
+ .thenReturn(Collections.singletonList(definition));
+
+ ServiceException ex = Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.batchMoveWorkflowDefinition(
+ user, projectCode,
String.valueOf(processDefinitionCode), projectCodeOther));
+
+
Assertions.assertEquals(Status.MOVE_WORKFLOW_DEFINITION_ERROR.getCode(),
ex.getCode());
+ verify(workflowTaskRelationDao,
Mockito.never()).queryByWorkflowDefinitionCode(Mockito.anyLong());
+ }
+
+ @Test
+ public void testReadOnlyUserCannotSwitchOrReleaseWorkflowDefinition() {
+ Project project = getProject(projectCode);
+ when(projectDao.queryByCode(projectCode)).thenReturn(project);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(user,
projectCode);
+
+ ServiceException switchEx =
Assertions.assertThrows(ServiceException.class,
+ () ->
workflowDefinitionService.switchWorkflowDefinitionVersion(
+ user, projectCode, processDefinitionCode, 1));
+ ServiceException onlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.onlineWorkflowDefinition(
+ user, projectCode, processDefinitionCode));
+ ServiceException offlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.offlineWorkflowDefinition(
+ user, projectCode, processDefinitionCode));
+
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
switchEx.getCode());
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
onlineEx.getCode());
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
offlineEx.getCode());
+ verify(workflowDefinitionDao,
Mockito.never()).updateById(Mockito.any());
+ }
+
+ @Test
+ public void
testProjectCodeCannotAuthorizeWorkflowDefinitionFromAnotherProject() {
+ WorkflowDefinition workflowDefinition = getWorkflowDefinition();
+ workflowDefinition.setProjectCode(projectCodeOther);
+ when(workflowDefinitionDao.queryByCode(processDefinitionCode))
+ .thenReturn(Optional.of(workflowDefinition));
+
+ ServiceException onlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.onlineWorkflowDefinition(
+ user, projectCode, processDefinitionCode));
+ ServiceException offlineEx =
Assertions.assertThrows(ServiceException.class,
+ () -> workflowDefinitionService.offlineWorkflowDefinition(
+ user, projectCode, processDefinitionCode));
+
+
Assertions.assertEquals(Status.WORKFLOW_DEFINITION_NOT_EXIST.getCode(),
onlineEx.getCode());
+
Assertions.assertEquals(Status.WORKFLOW_DEFINITION_NOT_EXIST.getCode(),
offlineEx.getCode());
+ verify(workflowDefinitionDao,
Mockito.never()).updateById(Mockito.any());
+ }
+
@Test
public void deleteWorkflowDefinitionByCodeTest() {
when(projectDao.queryByCode(projectCode)).thenReturn(getProject(projectCode));
@@ -545,15 +626,14 @@ public class WorkflowDefinitionServiceTest extends
BaseServiceTestTool {
// project check auth fail
when(workflowDefinitionDao.queryByCode(6L)).thenReturn(Optional.of(getWorkflowDefinition()));
- doThrow(new
ServiceException(Status.PROJECT_NOT_FOUND)).when(projectService)
- .checkProjectAndAuthThrowException(user, project,
WORKFLOW_DEFINITION_DELETE);
+ doThrow(new
ServiceException(Status.USER_NO_WRITE_PROJECT_PERM)).when(projectService)
+ .checkHasProjectWritePermissionThrowException(user, project);
exception = Assertions.assertThrows(ServiceException.class,
() ->
workflowDefinitionService.deleteWorkflowDefinitionByCode(user, 6L));
- Assertions.assertEquals(Status.PROJECT_NOT_FOUND.getCode(),
((ServiceException) exception).getCode());
+ Assertions.assertEquals(Status.USER_NO_WRITE_PROJECT_PERM.getCode(),
((ServiceException) exception).getCode());
// project check auth success, instance not exist
-
doNothing().when(projectService).checkProjectAndAuthThrowException(user,
project,
- WORKFLOW_DEFINITION_DELETE);
+
doNothing().when(projectService).checkHasProjectWritePermissionThrowException(user,
project);
when(workflowDefinitionDao.queryByCode(1L)).thenReturn(Optional.empty());
exception = Assertions.assertThrows(ServiceException.class,
() ->
workflowDefinitionService.deleteWorkflowDefinitionByCode(user, 1L));
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java
index 88e9051ffb..b066cad2a8 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkflowInstanceServiceTest.java
@@ -18,7 +18,6 @@
package org.apache.dolphinscheduler.api.service;
import static
org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowsServiceException;
-import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.INSTANCE_UPDATE;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.WORKFLOW_INSTANCE;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
@@ -531,21 +530,22 @@ public class WorkflowInstanceServiceTest {
User loginUser = getAdminUser();
Project project = getProject(projectCode);
- // project auth fail
+ // project write permission fail
when(projectDao.queryByCode(projectCode)).thenReturn(project);
- doThrow(new ServiceException(Status.PROJECT_NOT_FOUND, projectCode))
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
projectCode))
.when(projectService)
- .checkProjectAndAuthThrowException(loginUser, projectCode,
INSTANCE_UPDATE);
- assertThrowsServiceException(Status.PROJECT_NOT_FOUND,
+ .checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
() ->
workflowInstanceService.updateWorkflowInstance(loginUser, projectCode, 1,
shellJson, taskJson, "2020-02-21 00:00:00", true, "",
"", 0));
// process instance null
WorkflowInstance workflowInstance = getProcessInstance();
+ workflowInstance.setProjectCode(projectCode);
when(projectDao.queryByCode(projectCode)).thenReturn(project);
doNothing()
.when(projectService)
- .checkProjectAndAuthThrowException(loginUser, projectCode,
INSTANCE_UPDATE);
+ .checkHasProjectWritePermissionThrowException(loginUser,
projectCode);
when(processService.findWorkflowInstanceDetailById(1)).thenReturn(Optional.empty());
assertThrowsServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST,
() ->
workflowInstanceService.updateWorkflowInstance(loginUser, projectCode, 1,
@@ -617,6 +617,20 @@ public class WorkflowInstanceServiceTest {
}
}
+ @Test
+ public void testUpdateWorkflowInstanceWithMismatchedProjectCode() {
+ long projectCode = 1L;
+ User loginUser = getAdminUser();
+ WorkflowInstance workflowInstance = getProcessInstance();
+ workflowInstance.setProjectCode(2L);
+
when(processService.findWorkflowInstanceDetailById(1)).thenReturn(Optional.of(workflowInstance));
+
+ assertThrowsServiceException(Status.WORKFLOW_INSTANCE_NOT_EXIST,
+ () ->
workflowInstanceService.updateWorkflowInstance(loginUser, projectCode, 1,
+ shellJson, taskJson, "2020-02-21 00:00:00", true, "",
"", 0));
+ Mockito.verifyNoInteractions(workflowDefinitionDao);
+ }
+
@Test
public void testQueryParentInstanceBySubId() {
long projectCode = 1L;
@@ -701,6 +715,28 @@ public class WorkflowInstanceServiceTest {
Assertions.assertDoesNotThrow(() ->
workflowInstanceService.deleteWorkflowInstanceById(loginUser, 1));
}
+ @Test
+ public void testReadOnlyUserCannotDeleteWorkflowInstance() {
+ long projectCode = 1L;
+ User loginUser = getAdminUser();
+ WorkflowInstance workflowInstance = getProcessInstance();
+ workflowInstance.setWorkflowDefinitionCode(46L);
+ workflowInstance.setWorkflowDefinitionVersion(1);
+ WorkflowDefinitionLog workflowDefinitionLog = new
WorkflowDefinitionLog();
+ workflowDefinitionLog.setProjectCode(projectCode);
+ Project project = getProject(projectCode);
+
when(processService.findWorkflowInstanceDetailById(1)).thenReturn(Optional.of(workflowInstance));
+ when(workflowDefinitionLogMapper.queryByDefinitionCodeAndVersion(46L,
1))
+ .thenReturn(workflowDefinitionLog);
+ when(projectDao.queryByCode(projectCode)).thenReturn(project);
+ doThrow(new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM))
+
.when(projectService).checkHasProjectWritePermissionThrowException(loginUser,
project);
+
+ assertThrowsServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
+ () ->
workflowInstanceService.deleteWorkflowInstanceById(loginUser, 1));
+ Mockito.verify(processService,
Mockito.never()).deleteWorkflowInstanceById(Mockito.anyInt());
+ }
+
@Test
public void testViewVariables() {
long projectCode = 1L;