This is an automated email from the ASF dual-hosted git repository.
chufenggao 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 7336afaa65 [Fix-12916] Add permission check when query or download log
(#12917)
7336afaa65 is described below
commit 7336afaa65e3c4bb4596081cf0049b5166506a0c
Author: rickchengx <[email protected]>
AuthorDate: Fri Nov 25 17:59:28 2022 +0800
[Fix-12916] Add permission check when query or download log (#12917)
---
.../api/controller/LoggerController.java | 4 +-
.../api/service/LoggerService.java | 6 +-
.../api/service/impl/LoggerServiceImpl.java | 10 ++-
.../service/impl/ProcessInstanceServiceImpl.java | 6 +-
.../api/service/LoggerServiceTest.java | 80 ++++++++++++++++++----
.../api/service/ProcessInstanceServiceTest.java | 2 +-
.../dolphinscheduler/dao/mapper/ProjectMapper.java | 7 ++
.../dolphinscheduler/dao/mapper/ProjectMapper.xml | 12 ++++
8 files changed, 103 insertions(+), 24 deletions(-)
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
index 0909d4d85c..bd2a79285d 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
@@ -81,7 +81,7 @@ public class LoggerController extends BaseController {
@RequestParam(value =
"taskInstanceId") int taskInstanceId,
@RequestParam(value =
"skipLineNum") int skipNum,
@RequestParam(value = "limit") int
limit) {
- return loggerService.queryLog(taskInstanceId, skipNum, limit);
+ return loggerService.queryLog(loginUser, taskInstanceId, skipNum,
limit);
}
/**
@@ -101,7 +101,7 @@ public class LoggerController extends BaseController {
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public ResponseEntity downloadTaskLog(@Parameter(hidden = true)
@RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value =
"taskInstanceId") int taskInstanceId) {
- byte[] logBytes = loggerService.getLogBytes(taskInstanceId);
+ byte[] logBytes = loggerService.getLogBytes(loginUser, taskInstanceId);
return ResponseEntity
.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
index 33477c509e..db1cb7c465 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
@@ -31,20 +31,22 @@ public interface LoggerService {
/**
* view log
*
+ * @param loginUser login user
* @param taskInstId task instance id
* @param skipLineNum skip line number
* @param limit limit
* @return log string data
*/
- Result<ResponseTaskLog> queryLog(int taskInstId, int skipLineNum, int
limit);
+ Result<ResponseTaskLog> queryLog(User loginUser, int taskInstId, int
skipLineNum, int limit);
/**
* get log size
*
+ * @param loginUser login user
* @param taskInstId task instance id
* @return log byte array
*/
- byte[] getLogBytes(int taskInstId);
+ byte[] getLogBytes(User loginUser, int taskInstId);
/**
* query log
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
index 239c9669f1..227f74c12d 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
@@ -77,6 +77,7 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
/**
* view log
*
+ * @param loginUser login user
* @param taskInstId task instance id
* @param skipLineNum skip line number
* @param limit limit
@@ -84,7 +85,7 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
*/
@Override
@SuppressWarnings("unchecked")
- public Result<ResponseTaskLog> queryLog(int taskInstId, int skipLineNum,
int limit) {
+ public Result<ResponseTaskLog> queryLog(User loginUser, int taskInstId,
int skipLineNum, int limit) {
TaskInstance taskInstance =
taskInstanceDao.findTaskInstanceById(taskInstId);
@@ -96,6 +97,8 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
logger.error("Host of task instance is null, taskInstanceId:{}.",
taskInstId);
return Result.error(Status.TASK_INSTANCE_HOST_IS_NULL);
}
+ Project project =
projectMapper.queryProjectByTaskInstanceId(taskInstId);
+ projectService.checkProjectAndAuthThrowException(loginUser, project,
VIEW_LOG);
Result<ResponseTaskLog> result = new
Result<>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg());
String log = queryLog(taskInstance, skipLineNum, limit);
int lineNum = log.split("\\r\\n").length;
@@ -106,15 +109,18 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
/**
* get log size
*
+ * @param loginUser login user
* @param taskInstId task instance id
* @return log byte array
*/
@Override
- public byte[] getLogBytes(int taskInstId) {
+ public byte[] getLogBytes(User loginUser, int taskInstId) {
TaskInstance taskInstance =
taskInstanceDao.findTaskInstanceById(taskInstId);
if (taskInstance == null ||
StringUtils.isBlank(taskInstance.getHost())) {
throw new ServiceException("task instance is null or host is
null");
}
+ Project project =
projectMapper.queryProjectByTaskInstanceId(taskInstId);
+ projectService.checkProjectAndAuthThrowException(loginUser, project,
DOWNLOAD_LOG);
return getLogBytes(taskInstance);
}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
index 05415f899a..4c3fceefe3 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
@@ -375,7 +375,7 @@ public class ProcessInstanceServiceImpl extends
BaseServiceImpl implements Proce
}
List<TaskInstance> taskInstanceList =
taskInstanceDao.findValidTaskListByProcessId(processId,
processInstance.getTestFlag());
- addDependResultForTaskList(taskInstanceList);
+ addDependResultForTaskList(loginUser, taskInstanceList);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(PROCESS_INSTANCE_STATE,
processInstance.getState().toString());
resultMap.put(TASK_LIST, taskInstanceList);
@@ -388,12 +388,12 @@ public class ProcessInstanceServiceImpl extends
BaseServiceImpl implements Proce
/**
* add dependent result for dependent task
*/
- private void addDependResultForTaskList(List<TaskInstance>
taskInstanceList) throws IOException {
+ private void addDependResultForTaskList(User loginUser, List<TaskInstance>
taskInstanceList) throws IOException {
for (TaskInstance taskInstance : taskInstanceList) {
if
(TASK_TYPE_DEPENDENT.equalsIgnoreCase(taskInstance.getTaskType())) {
logger.info("DEPENDENT type task instance need to set
dependent result, taskCode:{}, taskInstanceId:{}",
taskInstance.getTaskCode(), taskInstance.getId());
- Result<ResponseTaskLog> logResult = loggerService.queryLog(
+ Result<ResponseTaskLog> logResult =
loggerService.queryLog(loginUser,
taskInstance.getId(),
Constants.LOG_QUERY_SKIP_LINE_NUMBER, Constants.LOG_QUERY_LIMIT);
if (logResult.getCode() == Status.SUCCESS.ordinal()) {
String log = logResult.getData().getMessage();
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
index ca34d74730..000a5955a4 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
@@ -21,6 +21,7 @@ import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationCon
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.VIEW_LOG;
import org.apache.dolphinscheduler.api.enums.Status;
+import org.apache.dolphinscheduler.api.exceptions.ServiceException;
import org.apache.dolphinscheduler.api.service.impl.LoggerServiceImpl;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
@@ -78,60 +79,111 @@ public class LoggerServiceTest {
private LogClient logClient;
@Test
- public void testQueryDataSourceList() {
+ public void testQueryLog() {
+ User loginUser = new User();
+ loginUser.setId(1);
TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setExecutorId(loginUser.getId() + 1);
Mockito.when(taskInstanceDao.findTaskInstanceById(1)).thenReturn(taskInstance);
- Result result = loggerService.queryLog(2, 1, 1);
+ Result result = loggerService.queryLog(loginUser, 2, 1, 1);
// TASK_INSTANCE_NOT_FOUND
Assertions.assertEquals(Status.TASK_INSTANCE_NOT_FOUND.getCode(),
result.getCode().intValue());
try {
// HOST NOT FOUND OR ILLEGAL
- result = loggerService.queryLog(1, 1, 1);
+ result = loggerService.queryLog(loginUser, 1, 1, 1);
} catch (RuntimeException e) {
Assertions.assertTrue(true);
logger.error("testQueryDataSourceList error {}", e.getMessage());
}
Assertions.assertEquals(Status.TASK_INSTANCE_HOST_IS_NULL.getCode(),
result.getCode().intValue());
- // SUCCESS
+ // PROJECT_NOT_EXIST
taskInstance.setHost("127.0.0.1:8080");
taskInstance.setLogPath("/temp/log");
+ try {
+ Mockito.doThrow(new
ServiceException(Status.PROJECT_NOT_EXIST)).when(projectService)
+ .checkProjectAndAuthThrowException(loginUser, null,
VIEW_LOG);
+ loggerService.queryLog(loginUser, 1, 1, 1);
+ } catch (ServiceException serviceException) {
+ Assertions.assertEquals(Status.PROJECT_NOT_EXIST.getCode(),
serviceException.getCode());
+ }
+
+ // USER_NO_OPERATION_PERM
+ Project project = getProject(1);
+
Mockito.when(projectMapper.queryProjectByTaskInstanceId(1)).thenReturn(project);
+ try {
+ Mockito.doThrow(new
ServiceException(Status.USER_NO_OPERATION_PERM)).when(projectService)
+ .checkProjectAndAuthThrowException(loginUser, project,
VIEW_LOG);
+ loggerService.queryLog(loginUser, 1, 1, 1);
+ } catch (ServiceException serviceException) {
+ Assertions.assertEquals(Status.USER_NO_OPERATION_PERM.getCode(),
serviceException.getCode());
+ }
+
+ // SUCCESS
+
Mockito.doNothing().when(projectService).checkProjectAndAuthThrowException(loginUser,
project, VIEW_LOG);
Mockito.when(taskInstanceDao.findTaskInstanceById(1)).thenReturn(taskInstance);
- result = loggerService.queryLog(1, 1, 1);
+ result = loggerService.queryLog(loginUser, 1, 1, 1);
Assertions.assertEquals(Status.SUCCESS.getCode(),
result.getCode().intValue());
}
@Test
public void testGetLogBytes() {
+ User loginUser = new User();
+ loginUser.setId(1);
TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setExecutorId(loginUser.getId() + 1);
Mockito.when(taskInstanceDao.findTaskInstanceById(1)).thenReturn(taskInstance);
// task instance is null
try {
- loggerService.getLogBytes(2);
- } catch (RuntimeException e) {
- Assertions.assertTrue(true);
+ loggerService.getLogBytes(loginUser, 2);
+ } catch (ServiceException e) {
+ Assertions.assertEquals(new ServiceException("task instance is
null or host is null").getMessage(),
+ e.getMessage());
logger.error("testGetLogBytes error: {}", "task instance is null");
}
// task instance host is null
try {
- loggerService.getLogBytes(1);
- } catch (RuntimeException e) {
- Assertions.assertTrue(true);
+ loggerService.getLogBytes(loginUser, 1);
+ } catch (ServiceException e) {
+ Assertions.assertEquals(new ServiceException("task instance is
null or host is null").getMessage(),
+ e.getMessage());
logger.error("testGetLogBytes error: {}", "task instance host is
null");
}
- // success
+ // PROJECT_NOT_EXIST
taskInstance.setHost("127.0.0.1:8080");
taskInstance.setLogPath("/temp/log");
+ try {
+ Mockito.doThrow(new
ServiceException(Status.PROJECT_NOT_EXIST)).when(projectService)
+ .checkProjectAndAuthThrowException(loginUser, null,
DOWNLOAD_LOG);
+ loggerService.queryLog(loginUser, 1, 1, 1);
+ } catch (ServiceException serviceException) {
+ Assertions.assertEquals(Status.PROJECT_NOT_EXIST.getCode(),
serviceException.getCode());
+ }
+
+ // USER_NO_OPERATION_PERM
+ Project project = getProject(1);
+
Mockito.when(projectMapper.queryProjectByTaskInstanceId(1)).thenReturn(project);
+ try {
+ Mockito.doThrow(new
ServiceException(Status.USER_NO_OPERATION_PERM)).when(projectService)
+ .checkProjectAndAuthThrowException(loginUser, project,
DOWNLOAD_LOG);
+ loggerService.queryLog(loginUser, 1, 1, 1);
+ } catch (ServiceException serviceException) {
+ Assertions.assertEquals(Status.USER_NO_OPERATION_PERM.getCode(),
serviceException.getCode());
+ }
+
+ // SUCCESS
+
Mockito.doNothing().when(projectService).checkProjectAndAuthThrowException(loginUser,
project, DOWNLOAD_LOG);
Mockito.when(logClient.getLogBytes(Mockito.anyString(),
Mockito.anyInt(), Mockito.anyString()))
.thenReturn(new byte[0]);
- loggerService.getLogBytes(1);
-
+
Mockito.when(projectMapper.queryProjectByTaskInstanceId(1)).thenReturn(project);
+ byte[] result = loggerService.getLogBytes(loginUser, 1);
+ Assertions.assertEquals(90, result.length);
}
@Test
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java
index f6bbefd8e4..abf29bbc5b 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java
@@ -414,7 +414,7 @@ public class ProcessInstanceServiceTest {
.thenReturn(Optional.of(processInstance));
when(taskInstanceDao.findValidTaskListByProcessId(processInstance.getId(),
processInstance.getTestFlag()))
.thenReturn(taskInstanceList);
- when(loggerService.queryLog(taskInstance.getId(), 0,
4098)).thenReturn(res);
+ when(loggerService.queryLog(loginUser, taskInstance.getId(), 0,
4098)).thenReturn(res);
Map<String, Object> successRes =
processInstanceService.queryTaskListByProcessId(loginUser, projectCode, 1);
Assertions.assertEquals(Status.SUCCESS,
successRes.get(Constants.STATUS));
}
diff --git
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java
index 59c635f711..c43a2415f0 100644
---
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java
+++
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java
@@ -143,4 +143,11 @@ public interface ProjectMapper extends BaseMapper<Project>
{
* @return projectList
*/
List<Project> queryAllProjectForDependent();
+
+ /**
+ * query the project by task instance id
+ * @param taskInstanceId
+ * @return project
+ */
+ Project queryProjectByTaskInstanceId(@Param("taskInstanceId") int
taskInstanceId);
}
diff --git
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml
index d01d970ee1..6996d6f754 100644
---
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml
+++
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml
@@ -185,4 +185,16 @@
select code, name
from t_ds_project
</select>
+
+ <select id="queryProjectByTaskInstanceId"
resultType="org.apache.dolphinscheduler.dao.entity.Project">
+ select
+ <include refid="baseSqlV2">
+ <property name="alias" value="p"/>
+ </include>
+ from t_ds_task_instance ti
+ join t_ds_process_instance pi on ti.process_instance_id = pi.id
+ join t_ds_process_definition pd on pi.process_definition_code = pd.code
+ join t_ds_project p on p.code = pd.project_code
+ where ti.id = #{taskInstanceId}
+ </select>
</mapper>