Browse Source

[Feature][Permission] Project management module authority control refactoring, authority abstract interface setting. (#10261)

* Create process definition with task group and task group priority cannot be save into db

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* [Feature][API] Permission control of project

* The result of the assertion cannot be changed. The only difference is the judgment condition.

* test recovery.

* controller test fix.

* ProjectE2ETest fix.

* WebElement import.

* Prioritize problem solving.

* Judging the length of the set fix

Co-authored-by: houshitao <shitaohou@163.com>
Co-authored-by: hstdream <33045461+hstdream@users.noreply.github.com>
3.1.0-release
WangJPLeo 3 years ago committed by GitHub
parent
commit
7ac8ea493c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseService.java
  2. 24
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/BaseServiceImpl.java
  3. 54
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java
  4. 26
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataAnalysisControllerTest.java
  5. 104
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
  6. 29
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java
  7. 14
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java
  8. 19
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml
  9. 17
      dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapperTest.java
  10. 1
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java
  11. 54
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckService.java
  12. 149
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckServiceImpl.java
  13. 125
      dolphinscheduler-service/src/test/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckServiceTest.java

11
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/BaseService.java

@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Map; import java.util.Map;
@ -83,6 +85,15 @@ public interface BaseService {
*/ */
boolean canOperator(User operateUser, int createUserId); boolean canOperator(User operateUser, int createUserId);
/**
* Verify that the operator has permissions
* @param user operate user
* @param ids Object[]
* @Param type authorizationType
* @return check result
*/
boolean canOperatorPermissions(User user, Object[] ids, AuthorizationType type);
/** /**
* check and parse date parameters * check and parse date parameters
* *

24
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/BaseServiceImpl.java

@ -22,9 +22,15 @@ import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.service.BaseService; import org.apache.dolphinscheduler.api.service.BaseService;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.utils.DateUtils; import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.service.permission.ResourcePermissionCheckService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException; import java.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -37,6 +43,10 @@ import java.util.Objects;
* base service impl * base service impl
*/ */
public class BaseServiceImpl implements BaseService { public class BaseServiceImpl implements BaseService {
private static final Logger logger = LoggerFactory.getLogger(ProjectServiceImpl.class);
@Autowired
private ResourcePermissionCheckService resourcePermissionCheckService;
/** /**
* check admin * check admin
@ -145,6 +155,20 @@ public class BaseServiceImpl implements BaseService {
return operateUser.getId() == createUserId || isAdmin(operateUser); return operateUser.getId() == createUserId || isAdmin(operateUser);
} }
/**
* Verify that the operator has permissions
* @param user operate user
* @param ids Object[]
* @param type AuthorizationType
* @return boolean
*/
@Override
public boolean canOperatorPermissions(User user, Object[] ids,AuthorizationType type) {
boolean operationPermissionCheck = resourcePermissionCheckService.operationPermissionCheck(type, user.getId(), null, logger);
boolean resourcePermissionCheck = resourcePermissionCheckService.resourcePermissionCheck(type, ids, user.getUserType().equals(UserType.ADMIN_USER) ? 0 : user.getId(), logger);
return operationPermissionCheck || resourcePermissionCheck;
}
/** /**
* check and parse date parameters * check and parse date parameters
* *

54
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java

@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.PageInfo; import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils; import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils;
import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils.CodeGenerateException; import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils.CodeGenerateException;
@ -35,10 +36,14 @@ import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper; import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper; import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper; import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.apache.dolphinscheduler.service.permission.ResourcePermissionCheckService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -54,6 +59,8 @@ import static org.apache.dolphinscheduler.api.utils.CheckUtils.checkDesc;
@Service @Service
public class ProjectServiceImpl extends BaseServiceImpl implements ProjectService { public class ProjectServiceImpl extends BaseServiceImpl implements ProjectService {
private static final Logger logger = LoggerFactory.getLogger(ProjectServiceImpl.class);
@Autowired @Autowired
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@ -66,6 +73,9 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
@Autowired @Autowired
private UserMapper userMapper; private UserMapper userMapper;
@Autowired
private ResourcePermissionCheckService resourcePermissionCheckService;
/** /**
* create project * create project
* *
@ -165,7 +175,7 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
if (project == null) { if (project == null) {
putMsg(result, Status.PROJECT_NOT_EXIST); putMsg(result, Status.PROJECT_NOT_EXIST);
} else if (!checkReadPermission(loginUser, project)) { } else if (!checkReadPermissions(loginUser, project.getId())) {
// check read permission // check read permission
putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), projectCode); putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), projectCode);
} else { } else {
@ -179,7 +189,7 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
boolean checkResult = false; boolean checkResult = false;
if (project == null) { if (project == null) {
putMsg(result, Status.PROJECT_NOT_FOUND, ""); putMsg(result, Status.PROJECT_NOT_FOUND, "");
} else if (!checkReadPermission(loginUser, project)) { } else if (!checkReadPermissions(loginUser, project.getId())) {
putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getCode()); putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getCode());
} else { } else {
checkResult = true; checkResult = true;
@ -192,7 +202,7 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
boolean checkResult = false; boolean checkResult = false;
if (project == null) { if (project == null) {
putMsg(result, Status.PROJECT_NOT_FOUND, ""); putMsg(result, Status.PROJECT_NOT_FOUND, "");
} else if (!checkReadPermission(loginUser, project)) { } else if (!checkReadPermissions(loginUser, project.getId())) {
putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getName()); putMsg(result, Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(), project.getName());
} else { } else {
checkResult = true; checkResult = true;
@ -216,11 +226,11 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
Page<Project> page = new Page<>(pageNo, pageSize); Page<Project> page = new Page<>(pageNo, pageSize);
int userId = loginUser.getUserType() == UserType.ADMIN_USER ? 0 : loginUser.getId(); Set<Integer> projectIds = resourcePermissionCheckService.userOwnedResourceIdsAcquisition(AuthorizationType.PROJECTS, loginUser.getId(), logger);
IPage<Project> projectIPage = projectMapper.queryProjectListPaging(page, userId, searchVal); IPage<Project> projectIPage = projectMapper.queryProjectListPaging(page, new ArrayList<>(projectIds), searchVal);
List<Project> projectList = projectIPage.getRecords(); List<Project> projectList = projectIPage.getRecords();
if (userId != 0) { if (loginUser.getUserType() != UserType.ADMIN_USER) {
for (Project project : projectList) { for (Project project : projectList) {
project.setPerm(Constants.DEFAULT_ADMIN_PERMISSION); project.setPerm(Constants.DEFAULT_ADMIN_PERMISSION);
} }
@ -248,7 +258,7 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
return checkResult; return checkResult;
} }
if (!canOperator(loginUser, project.getUserId())) { if (!canOperatorPermissions(loginUser, new Object[]{project.getId()}, AuthorizationType.PROJECTS)) {
putMsg(result, Status.USER_NO_OPERATION_PERM); putMsg(result, Status.USER_NO_OPERATION_PERM);
return result; return result;
} }
@ -343,13 +353,9 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
public Map<String, Object> queryUnauthorizedProject(User loginUser, Integer userId) { public Map<String, Object> queryUnauthorizedProject(User loginUser, Integer userId) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
List<Project> projectList; Set<Integer> projectIds = resourcePermissionCheckService.userOwnedResourceIdsAcquisition(AuthorizationType.PROJECTS, loginUser.getId(), logger);
if (isAdmin(loginUser)) { List<Project> projectList = projectMapper.listAuthorizedProjects(loginUser.getUserType().equals(UserType.ADMIN_USER) ? 0 : loginUser.getId(), new ArrayList<>(projectIds));
// admin gets all projects except userId
projectList = projectMapper.queryProjectExceptUserId(userId);
} else {
projectList = projectMapper.queryProjectCreatedByUser(loginUser.getId());
}
List<Project> resultList = new ArrayList<>(); List<Project> resultList = new ArrayList<>();
Set<Project> projectSet; Set<Project> projectSet;
if (projectList != null && !projectList.isEmpty()) { if (projectList != null && !projectList.isEmpty()) {
@ -453,12 +459,8 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
public Map<String, Object> queryProjectCreatedAndAuthorizedByUser(User loginUser) { public Map<String, Object> queryProjectCreatedAndAuthorizedByUser(User loginUser) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
List<Project> projects = null; Set<Integer> projectIds = resourcePermissionCheckService.userOwnedResourceIdsAcquisition(AuthorizationType.PROJECTS, loginUser.getId(), logger);
if (loginUser.getUserType() == UserType.ADMIN_USER) { List<Project> projects = projectMapper.listAuthorizedProjects(loginUser.getUserType().equals(UserType.ADMIN_USER) ? 0 : loginUser.getId(), new ArrayList<>(projectIds));
projects = projectMapper.selectList(null);
} else {
projects = projectMapper.queryProjectCreatedAndAuthorizedByUserId(loginUser.getId());
}
result.put(Constants.DATA_LIST, projects); result.put(Constants.DATA_LIST, projects);
putMsg(result, Status.SUCCESS); putMsg(result, Status.SUCCESS);
@ -478,6 +480,18 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
return (permissionId & Constants.READ_PERMISSION) != 0; return (permissionId & Constants.READ_PERMISSION) != 0;
} }
/**
* check whether have read permission new
* @param user
* @param id
* @return true if the user have permission to see the project, otherwise return false
*/
private boolean checkReadPermissions(User user, Integer id){
boolean operationPermissionCheck = resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, user.getId(), null, logger);
boolean resourcePermissionCheck = resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{id}, user.getUserType().equals(UserType.ADMIN_USER) ? 0 : user.getId(), logger);
return operationPermissionCheck && resourcePermissionCheck;
}
/** /**
* query permission id * query permission id
* *

26
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/DataAnalysisControllerTest.java

@ -33,30 +33,41 @@ import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.PowerMockito;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import java.util.Date;
/** /**
* data analysis controller test * data analysis controller test
*/ */
public class DataAnalysisControllerTest extends AbstractControllerTest { public class DataAnalysisControllerTest extends AbstractControllerTest {
private static final Logger logger = LoggerFactory.getLogger(DataAnalysisControllerTest.class); private static final Logger logger = LoggerFactory.getLogger(DataAnalysisControllerTest.class);
@MockBean(name = "projectMapper") @Autowired
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
private int createProject() {
Project project = new Project();
project.setCode(16L);
project.setName("ut project");
project.setUserId(1);
project.setCreateTime(new Date());
projectMapper.insert(project);
return project.getId();
}
@Test @Test
public void testCountTaskState() throws Exception { public void testCountTaskState() throws Exception {
PowerMockito.when(projectMapper.queryByCode(Mockito.anyLong())).thenReturn(getProject("test")); int projectId = createProject();
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-12-01 00:00:00"); paramsMap.add("startDate","2019-12-01 00:00:00");
paramsMap.add("endDate","2019-12-28 00:00:00"); paramsMap.add("endDate","2019-12-28 00:00:00");
paramsMap.add("projectCode","16"); paramsMap.add("projectCode","16");
MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/task-state-count") MvcResult mvcResult = mockMvc.perform(get("/projects/analysis/task-state-count")
.header("sessionId", sessionId) .header("sessionId", sessionId)
.params(paramsMap)) .params(paramsMap))
@ -66,11 +77,13 @@ public class DataAnalysisControllerTest extends AbstractControllerTest {
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class); Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
assertThat(result.getCode().intValue()).isEqualTo(Status.SUCCESS.getCode()); assertThat(result.getCode().intValue()).isEqualTo(Status.SUCCESS.getCode());
logger.info(mvcResult.getResponse().getContentAsString()); logger.info(mvcResult.getResponse().getContentAsString());
projectMapper.deleteById(projectId);
} }
@Test @Test
public void testCountProcessInstanceState() throws Exception { public void testCountProcessInstanceState() throws Exception {
PowerMockito.when(projectMapper.queryByCode(Mockito.anyLong())).thenReturn(getProject("test")); int projectId = createProject();
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("startDate","2019-12-01 00:00:00"); paramsMap.add("startDate","2019-12-01 00:00:00");
@ -86,11 +99,12 @@ public class DataAnalysisControllerTest extends AbstractControllerTest {
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class); Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
assertThat(result.getCode().intValue()).isEqualTo(Status.SUCCESS.getCode()); assertThat(result.getCode().intValue()).isEqualTo(Status.SUCCESS.getCode());
logger.info(mvcResult.getResponse().getContentAsString()); logger.info(mvcResult.getResponse().getContentAsString());
projectMapper.deleteById(projectId);
} }
@Test @Test
public void testCountDefinitionByUser() throws Exception { public void testCountDefinitionByUser() throws Exception {
PowerMockito.when(projectMapper.queryByCode(Mockito.anyLong())).thenReturn(getProject("test"));
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectId","16"); paramsMap.add("projectId","16");

104
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java

@ -19,9 +19,8 @@ package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.service.impl.ProjectServiceImpl; 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; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.Project;
@ -34,12 +33,9 @@ import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.dolphinscheduler.service.permission.ResourcePermissionCheckService;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -50,9 +46,6 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/** /**
* project service test * project service test
**/ **/
@ -68,10 +61,11 @@ public class ProjectServiceTest {
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Mock @Mock
private ProjectUserMapper projectUserMapper; private ProcessDefinitionMapper processDefinitionMapper;
@Mock @Mock
private ProcessDefinitionMapper processDefinitionMapper; private ResourcePermissionCheckService resourcePermissionCheckService;
@Mock @Mock
private UserMapper userMapper; private UserMapper userMapper;
@ -80,6 +74,8 @@ public class ProjectServiceTest {
private String userName = "ProjectServiceTest"; private String userName = "ProjectServiceTest";
private static final Logger projectServiceLogger = LoggerFactory.getLogger(ProjectServiceImpl.class);
@Test @Test
public void testCreateProject() { public void testCreateProject() {
@ -106,8 +102,8 @@ public class ProjectServiceTest {
@Test @Test
public void testCheckProjectAndAuth() { public void testCheckProjectAndAuth() {
// no admin user
long projectCode = 1L; long projectCode = 1L;
Mockito.when(projectUserMapper.queryProjectRelation(1, 1)).thenReturn(getProjectUser());
User loginUser = getLoginUser(); User loginUser = getLoginUser();
Map<String, Object> result = projectService.checkProjectAndAuth(loginUser, null, projectCode); Map<String, Object> result = projectService.checkProjectAndAuth(loginUser, null, projectCode);
@ -118,17 +114,23 @@ public class ProjectServiceTest {
Project project = getProject(); Project project = getProject();
//USER_NO_OPERATION_PROJECT_PERM //USER_NO_OPERATION_PROJECT_PERM
project.setUserId(2); project.setUserId(2);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(false);
result = projectService.checkProjectAndAuth(loginUser, project, projectCode); result = projectService.checkProjectAndAuth(loginUser, project, projectCode);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result.get(Constants.STATUS)); Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result.get(Constants.STATUS));
//success //success
project.setUserId(1); project.setUserId(1);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
result = projectService.checkProjectAndAuth(loginUser, project, projectCode); result = projectService.checkProjectAndAuth(loginUser, project, projectCode);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
// admin user
Map<String, Object> result2 = new HashMap<>(); Map<String, Object> result2 = new HashMap<>();
loginUser = geAdminUser();
result2 = projectService.checkProjectAndAuth(loginUser, null, projectCode); result2 = projectService.checkProjectAndAuth(loginUser, null, projectCode);
Assert.assertEquals(Status.PROJECT_NOT_EXIST, result2.get(Constants.STATUS)); Assert.assertEquals(Status.PROJECT_NOT_EXIST, result2.get(Constants.STATUS));
@ -136,12 +138,18 @@ public class ProjectServiceTest {
Project project1 = getProject(); Project project1 = getProject();
// USER_NO_OPERATION_PROJECT_PERM // USER_NO_OPERATION_PROJECT_PERM
project1.setUserId(2); project1.setUserId(2);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 11, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 0, projectServiceLogger)).thenReturn(true);
result2 = projectService.checkProjectAndAuth(loginUser, project1, projectCode); result2 = projectService.checkProjectAndAuth(loginUser, project1, projectCode);
Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result2.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result2.get(Constants.STATUS));
//success //success
project1.setUserId(1); project1.setUserId(1);
projectService.checkProjectAndAuth(loginUser, project1, projectCode); Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 11, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 0, projectServiceLogger)).thenReturn(true);
result2 = projectService.checkProjectAndAuth(loginUser, project1, projectCode);
Assert.assertEquals(Status.SUCCESS, result2.get(Constants.STATUS));
} }
@ -155,6 +163,7 @@ public class ProjectServiceTest {
// not exist user // not exist user
User tempUser = new User(); User tempUser = new User();
tempUser.setId(Integer.MAX_VALUE); tempUser.setId(Integer.MAX_VALUE);
tempUser.setUserType(UserType.GENERAL_USER);
boolean checkResult = projectService.hasProjectAndPerm(tempUser, project, result); boolean checkResult = projectService.hasProjectAndPerm(tempUser, project, result);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertFalse(checkResult); Assert.assertFalse(checkResult);
@ -162,35 +171,13 @@ public class ProjectServiceTest {
//success //success
result = new HashMap<>(); result = new HashMap<>();
project.setUserId(1); project.setUserId(1);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
checkResult = projectService.hasProjectAndPerm(loginUser, project, result); checkResult = projectService.hasProjectAndPerm(loginUser, project, result);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertTrue(checkResult); Assert.assertTrue(checkResult);
} }
@Test
public void testQueryProjectListPaging() {
IPage<Project> page = new Page<>(1, 10);
page.setRecords(getList());
page.setTotal(1L);
Mockito.when(projectMapper.queryProjectListPaging(Mockito.any(Page.class), Mockito.eq(1), Mockito.eq(projectName))).thenReturn(page);
User loginUser = getLoginUser();
// project owner
Result result = projectService.queryProjectListPaging(loginUser, 10, 1, projectName);
logger.info(result.toString());
PageInfo<Project> pageInfo = (PageInfo<Project>) result.getData();
Assert.assertTrue(CollectionUtils.isNotEmpty(pageInfo.getTotalList()));
//admin
Mockito.when(projectMapper.queryProjectListPaging(Mockito.any(Page.class), Mockito.eq(0), Mockito.eq(projectName))).thenReturn(page);
loginUser.setUserType(UserType.ADMIN_USER);
result = projectService.queryProjectListPaging(loginUser, 10, 1, projectName);
logger.info(result.toString());
pageInfo = (PageInfo<Project>) result.getData();
Assert.assertTrue(CollectionUtils.isNotEmpty(pageInfo.getTotalList()));
}
@Test @Test
public void testDeleteProject() { public void testDeleteProject() {
User loginUser = getLoginUser(); User loginUser = getLoginUser();
@ -199,12 +186,17 @@ public class ProjectServiceTest {
Map<String, Object> result = projectService.deleteProject(loginUser, 11L); Map<String, Object> result = projectService.deleteProject(loginUser, 11L);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.PROJECT_NOT_EXIST, result.get(Constants.STATUS)); Assert.assertEquals(Status.PROJECT_NOT_EXIST, result.get(Constants.STATUS));
loginUser.setId(2); loginUser.setId(2);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 2, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 2, projectServiceLogger)).thenReturn(false);
//USER_NO_OPERATION_PROJECT_PERM //USER_NO_OPERATION_PROJECT_PERM
result = projectService.deleteProject(loginUser, 1L); result = projectService.deleteProject(loginUser, 1L);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result.get(Constants.STATUS)); Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result.get(Constants.STATUS));
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 2, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 0, projectServiceLogger)).thenReturn(true);
//DELETE_PROJECT_ERROR_DEFINES_NOT_NULL //DELETE_PROJECT_ERROR_DEFINES_NOT_NULL
Mockito.when(processDefinitionMapper.queryAllDefinitionList(1L)).thenReturn(getProcessDefinitions()); Mockito.when(processDefinitionMapper.queryAllDefinitionList(1L)).thenReturn(getProcessDefinitions());
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setUserType(UserType.ADMIN_USER);
@ -213,6 +205,8 @@ public class ProjectServiceTest {
Assert.assertEquals(Status.DELETE_PROJECT_ERROR_DEFINES_NOT_NULL, result.get(Constants.STATUS)); Assert.assertEquals(Status.DELETE_PROJECT_ERROR_DEFINES_NOT_NULL, result.get(Constants.STATUS));
//success //success
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 2, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 0, projectServiceLogger)).thenReturn(true);
Mockito.when(projectMapper.deleteById(1)).thenReturn(1); Mockito.when(projectMapper.deleteById(1)).thenReturn(1);
Mockito.when(processDefinitionMapper.queryAllDefinitionList(1L)).thenReturn(new ArrayList<>()); Mockito.when(processDefinitionMapper.queryAllDefinitionList(1L)).thenReturn(new ArrayList<>());
result = projectService.deleteProject(loginUser, 1L); result = projectService.deleteProject(loginUser, 1L);
@ -234,15 +228,21 @@ public class ProjectServiceTest {
Assert.assertEquals(Status.PROJECT_NOT_FOUND, result.get(Constants.STATUS)); Assert.assertEquals(Status.PROJECT_NOT_FOUND, result.get(Constants.STATUS));
//PROJECT_ALREADY_EXISTS //PROJECT_ALREADY_EXISTS
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
result = projectService.update(loginUser, 2L, projectName, "desc", userName); result = projectService.update(loginUser, 2L, projectName, "desc", userName);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.PROJECT_ALREADY_EXISTS, result.get(Constants.STATUS)); Assert.assertEquals(Status.PROJECT_ALREADY_EXISTS, result.get(Constants.STATUS));
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
Mockito.when(userMapper.queryByUserNameAccurately(Mockito.any())).thenReturn(null); Mockito.when(userMapper.queryByUserNameAccurately(Mockito.any())).thenReturn(null);
result = projectService.update(loginUser, 2L, "test", "desc", "testuser"); result = projectService.update(loginUser, 2L, "test", "desc", "testuser");
Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS)); Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
//success //success
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
Mockito.when(userMapper.queryByUserNameAccurately(Mockito.any())).thenReturn(new User()); Mockito.when(userMapper.queryByUserNameAccurately(Mockito.any())).thenReturn(new User());
project.setUserId(1); project.setUserId(1);
Mockito.when(projectMapper.updateById(Mockito.any(Project.class))).thenReturn(1); Mockito.when(projectMapper.updateById(Mockito.any(Project.class))).thenReturn(1);
@ -284,6 +284,8 @@ public class ProjectServiceTest {
// Failure 2: USER_NO_OPERATION_PROJECT_PERM // Failure 2: USER_NO_OPERATION_PROJECT_PERM
loginUser.setId(100); loginUser.setId(100);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 100, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 100, projectServiceLogger)).thenReturn(false);
Mockito.when(this.projectMapper.queryByCode(Mockito.anyLong())).thenReturn(this.getProject()); Mockito.when(this.projectMapper.queryByCode(Mockito.anyLong())).thenReturn(this.getProject());
result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L); result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
logger.info("FAILURE 2: {}", result.toString()); logger.info("FAILURE 2: {}", result.toString());
@ -291,6 +293,8 @@ public class ProjectServiceTest {
// SUCCESS // SUCCESS
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setUserType(UserType.ADMIN_USER);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 100, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 0, projectServiceLogger)).thenReturn(true);
Mockito.when(this.userMapper.queryAuthedUserListByProjectId(1)).thenReturn(this.getUserList()); Mockito.when(this.userMapper.queryAuthedUserListByProjectId(1)).thenReturn(this.getUserList());
result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L); result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
logger.info("SUCCESS 1: {}", result.toString()); logger.info("SUCCESS 1: {}", result.toString());
@ -299,6 +303,8 @@ public class ProjectServiceTest {
loginUser.setId(1); loginUser.setId(1);
loginUser.setUserType(UserType.GENERAL_USER); loginUser.setUserType(UserType.GENERAL_USER);
Mockito.when(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, 1, null, projectServiceLogger)).thenReturn(true);
Mockito.when(resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, new Object[]{1}, 1, projectServiceLogger)).thenReturn(true);
result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L); result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
logger.info("SUCCESS 2: {}", result.toString()); logger.info("SUCCESS 2: {}", result.toString());
users = (List<User>) result.get(Constants.DATA_LIST); users = (List<User>) result.get(Constants.DATA_LIST);
@ -328,14 +334,15 @@ public class ProjectServiceTest {
User loginUser = getLoginUser(); User loginUser = getLoginUser();
// not admin user // not admin user
Mockito.when(projectMapper.queryProjectCreatedAndAuthorizedByUserId(1)).thenReturn(getList()); Set<Integer> projectIds = new HashSet<>();
Mockito.when(projectMapper.listAuthorizedProjects(1, new ArrayList<>(projectIds))).thenReturn(getList());
result = projectService.queryProjectCreatedAndAuthorizedByUser(loginUser); result = projectService.queryProjectCreatedAndAuthorizedByUser(loginUser);
List<Project> notAdminUserResult = (List<Project>) result.get(Constants.DATA_LIST); List<Project> notAdminUserResult = (List<Project>) result.get(Constants.DATA_LIST);
Assert.assertTrue(CollectionUtils.isNotEmpty(notAdminUserResult)); Assert.assertTrue(CollectionUtils.isNotEmpty(notAdminUserResult));
//admin user //admin user
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setUserType(UserType.ADMIN_USER);
Mockito.when(projectMapper.selectList(null)).thenReturn(getList()); Mockito.when(projectMapper.listAuthorizedProjects(0, new ArrayList<>(projectIds))).thenReturn(getList());
result = projectService.queryProjectCreatedAndAuthorizedByUser(loginUser); result = projectService.queryProjectCreatedAndAuthorizedByUser(loginUser);
List<Project> projects = (List<Project>) result.get(Constants.DATA_LIST); List<Project> projects = (List<Project>) result.get(Constants.DATA_LIST);
@ -358,11 +365,11 @@ public class ProjectServiceTest {
@Test @Test
public void testQueryUnauthorizedProject() { public void testQueryUnauthorizedProject() {
Mockito.when(projectMapper.queryProjectExceptUserId(2)).thenReturn(getList());
Mockito.when(projectMapper.queryProjectCreatedByUser(2)).thenReturn(getList());
Mockito.when(projectMapper.queryAuthedProjectListByUserId(2)).thenReturn(getSingleList());
// test admin user // test admin user
Set<Integer> projectIds = new HashSet<>();
Mockito.when(projectMapper.listAuthorizedProjects(0, new ArrayList<>(projectIds))).thenReturn(getList());
User loginUser = new User(); User loginUser = new User();
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setUserType(UserType.ADMIN_USER);
Map<String, Object> result = projectService.queryUnauthorizedProject(loginUser, 2); Map<String, Object> result = projectService.queryUnauthorizedProject(loginUser, 2);
@ -371,6 +378,7 @@ public class ProjectServiceTest {
Assert.assertTrue(CollectionUtils.isNotEmpty(projects)); Assert.assertTrue(CollectionUtils.isNotEmpty(projects));
// test non-admin user // test non-admin user
Mockito.when(projectMapper.listAuthorizedProjects(2, new ArrayList<>(projectIds))).thenReturn(getList());
loginUser.setId(2); loginUser.setId(2);
loginUser.setUserType(UserType.GENERAL_USER); loginUser.setUserType(UserType.GENERAL_USER);
result = projectService.queryUnauthorizedProject(loginUser, 3); result = projectService.queryUnauthorizedProject(loginUser, 3);
@ -420,6 +428,14 @@ public class ProjectServiceTest {
return loginUser; return loginUser;
} }
private User geAdminUser() {
User loginUser = new User();
loginUser.setUserType(UserType.ADMIN_USER);
loginUser.setUserName(userName);
loginUser.setId(11);
return loginUser;
}
/** /**
* Get general user * Get general user
* @return * @return

29
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java

@ -25,17 +25,34 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
public enum AuthorizationType { public enum AuthorizationType {
/** /**
* 0 RESOURCE_FILE_ID; * 0 RESOURCE_FILE_ID;
* 0 RESOURCE_FILE_NAME; * 1 RESOURCE_FILE_NAME;
* 1 UDF_FILE; * 2 UDF_FILE;
* 1 DATASOURCE; * 3 DATASOURCE;
* 2 UDF; * 4 UDF;
* 5 PROJECTS;
* 6 WORKER_GROUP;
* 7 ALERT_GROUP;
* 8 ENVIRONMENT;
* 9 ACCESS_TOKEN;
* 10 QUEUE;
* 11 DATA_ANALYSIS;
* 12 K8S_NAMESPACE;
* 13 MONITOR;
*/ */
RESOURCE_FILE_ID(0, "resource file id"), RESOURCE_FILE_ID(0, "resource file id"),
RESOURCE_FILE_NAME(1, "resource file name"), RESOURCE_FILE_NAME(1, "resource file name"),
UDF_FILE(2, "udf file"), UDF_FILE(2, "udf file"),
DATASOURCE(3, "data source"), DATASOURCE(3, "data source"),
UDF(4, "udf function"); UDF(4, "udf function"),
PROJECTS(5, "projects"),
WORKER_GROUP(6, "worker group"),
ALERT_GROUP(7, "alert group"),
ENVIRONMENT(8, "environment"),
ACCESS_TOKEN(9, "access token"),
QUEUE(10,"queue"),
DATA_ANALYSIS(11,"data analysis"),
K8S_NAMESPACE(12,"k8s namespace"),
MONITOR(13,"montitor");
AuthorizationType(int code, String descp) { AuthorizationType(int code, String descp) {
this.code = code; this.code = code;
this.descp = descp; this.descp = descp;

14
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.java

@ -71,12 +71,12 @@ public interface ProjectMapper extends BaseMapper<Project> {
/** /**
* project page * project page
* @param page page * @param page page
* @param userId userId * @param projectsIds projectsIds
* @param searchName searchName * @param searchName searchName
* @return project Ipage * @return project Ipage
*/ */
IPage<Project> queryProjectListPaging(IPage<Project> page, IPage<Project> queryProjectListPaging(IPage<Project> page,
@Param("userId") int userId, @Param("projectsIds") List<Integer> projectsIds,
@Param("searchName") String searchName); @Param("searchName") String searchName);
/** /**
@ -127,4 +127,14 @@ public interface ProjectMapper extends BaseMapper<Project> {
* @return projectList * @return projectList
*/ */
List<Project> queryAllProject(@Param("userId") int userId); List<Project> queryAllProject(@Param("userId") int userId);
/**
* list authorized Projects
* @param userId
* @param projectsIds
* @param <T>
* @return
*/
List<Project> listAuthorizedProjects(@Param("userId") int userId, @Param("projectsIds")List<Integer> projectsIds);
} }

19
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ProjectMapper.xml

@ -94,11 +94,11 @@
from t_ds_project p from t_ds_project p
left join t_ds_user u on u.id=p.user_id left join t_ds_user u on u.id=p.user_id
where 1=1 where 1=1
<if test="userId != 0"> <if test="projectsIds != null and projectsIds.size() > 0">
and p.id in and p.id in
(select project_id from t_ds_relation_project_user where user_id=#{userId} <foreach item="id" index="index" collection="projectsIds" open="(" separator="," close=")">
union select id as project_id from t_ds_project where user_id=#{userId} #{id}
) </foreach>
</if> </if>
<if test="searchName!=null and searchName != ''"> <if test="searchName!=null and searchName != ''">
AND (p.name LIKE concat('%', #{searchName}, '%') AND (p.name LIKE concat('%', #{searchName}, '%')
@ -169,4 +169,15 @@
and user_id = #{userId} and user_id = #{userId}
</if> </if>
</select> </select>
<select id="listAuthorizedProjects" resultType="org.apache.dolphinscheduler.dao.entity.Project">
select
<include refid="baseSql"/>
from t_ds_project dp
where 1=1
<if test="userId != 0">
and dp.id in (select project_id from t_ds_relation_project_user where user_id=#{userId}
union select id as project_id from t_ds_project where user_id=#{userId})
</if>
</select>
</mapper> </mapper>

17
dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/ProjectMapperTest.java

@ -21,6 +21,8 @@ import org.apache.dolphinscheduler.dao.BaseDaoTest;
import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -142,12 +144,12 @@ public class ProjectMapperTest extends BaseDaoTest {
Page<Project> page = new Page(1, 3); Page<Project> page = new Page(1, 3);
IPage<Project> projectIPage = projectMapper.queryProjectListPaging( IPage<Project> projectIPage = projectMapper.queryProjectListPaging(
page, page,
project.getUserId(), null,
null null
); );
IPage<Project> projectIPage1 = projectMapper.queryProjectListPaging( IPage<Project> projectIPage1 = projectMapper.queryProjectListPaging(
page, page,
project.getUserId(), null,
project.getName() project.getName()
); );
Assert.assertEquals(projectIPage.getTotal(), 1); Assert.assertEquals(projectIPage.getTotal(), 1);
@ -192,4 +194,15 @@ public class ProjectMapperTest extends BaseDaoTest {
Assert.assertNotEquals(projects.size(), 0); Assert.assertNotEquals(projects.size(), 0);
} }
/**
* test query project permission
*/
@Test
public void testListAuthorizedProjects(){
Project project = insertOne();
List<Project> projects = projectMapper.listAuthorizedProjects(1, Collections.singletonList(project.getId()));
Assert.assertEquals(projects.size(),0);
}
} }

1
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java

@ -29,6 +29,7 @@ import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")

54
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckService.java

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.dolphinscheduler.service.permission;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.slf4j.Logger;
import java.util.Set;
public interface ResourcePermissionCheckService<T>{
/**
* resourcePermissionCheck
* @param authorizationType
* @param needChecks
* @param userId
* @param logger
* @return
*/
boolean resourcePermissionCheck(AuthorizationType authorizationType, T[] needChecks, int userId, Logger logger);
/**
* userOwnedResourceIdsAcquisition
* @param authorizationType
* @param userId
* @param logger
* @param <T>
* @return
*/
<T> Set<T> userOwnedResourceIdsAcquisition(AuthorizationType authorizationType, int userId, Logger logger);
/**
* operationpermissionCheck
* @param authorizationType
* @param userId
* @param sourceUrl
* @param logger
* @return
*/
boolean operationPermissionCheck(AuthorizationType authorizationType, int userId, String sourceUrl, Logger logger);
}

149
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckServiceImpl.java

@ -0,0 +1,149 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.dolphinscheduler.service.permission;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.*;
import org.apache.dolphinscheduler.dao.mapper.*;
import org.apache.dolphinscheduler.service.process.ProcessService;
import org.slf4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.stream.Collectors.toSet;
@Component
public class ResourcePermissionCheckServiceImpl implements ResourcePermissionCheckService<Object>, ApplicationContextAware {
@Autowired
private ProcessService processService;
public static final Map<AuthorizationType, ResourceAcquisitionAndPermissionCheck<?>> RESOURCE_LIST_MAP = new ConcurrentHashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
for (ResourceAcquisitionAndPermissionCheck<?> authorizedResourceList : applicationContext.getBeansOfType(ResourceAcquisitionAndPermissionCheck.class).values()) {
List<AuthorizationType> authorizationTypes = authorizedResourceList.authorizationTypes();
authorizationTypes.forEach(auth -> RESOURCE_LIST_MAP.put(auth, authorizedResourceList));
}
}
@Override
public boolean resourcePermissionCheck(AuthorizationType authorizationType, Object[] needChecks, int userId, Logger logger) {
if (Objects.nonNull(needChecks) && needChecks.length > 0){
Set<Object> originResSet = new HashSet<>(Arrays.asList(needChecks));
Set<Object> ownResSets = RESOURCE_LIST_MAP.get(authorizationType).listAuthorizedResource(userId, logger);
originResSet.removeAll(ownResSets);
return originResSet.isEmpty();
}
return true;
}
@Override
public boolean operationPermissionCheck(AuthorizationType authorizationType, int userId, String sourceUrl, Logger logger) {
return RESOURCE_LIST_MAP.get(authorizationType).permissionCheck(userId, sourceUrl, logger);
}
@Override
public <T> Set<T> userOwnedResourceIdsAcquisition(AuthorizationType authorizationType, int userId, Logger logger) {
User user = processService.getUserById(userId);
if (user == null){
logger.error("user id {} doesn't exist", userId);
return Collections.emptySet();
}
return RESOURCE_LIST_MAP.get(authorizationType).listAuthorizedResource(user.getUserType().equals(UserType.ADMIN_USER) ? 0 : userId, logger);
}
@Component
public static class ProjectsResourceList implements ResourceAcquisitionAndPermissionCheck<Integer> {
private final ProjectMapper projectMapper;
@Autowired
private ProcessService processService;
public ProjectsResourceList(ProjectMapper projectMapper) {
this.projectMapper = projectMapper;
}
@Override
public List<AuthorizationType> authorizationTypes() {
return Collections.singletonList(AuthorizationType.PROJECTS);
}
@Override
public boolean permissionCheck(int userId, String url, Logger logger) {
// all users can create projects
return true;
}
@Override
public Set<Integer> listAuthorizedResource(int userId, Logger logger) {
return projectMapper.listAuthorizedProjects(userId, null).stream().map(Project::getId).collect(toSet());
}
}
interface ResourceAcquisitionAndPermissionCheck<T> {
/**
* authorization types
* @return
*/
List<AuthorizationType> authorizationTypes();
/**
* get all resources under the user (no admin)
* @param userId
* @param <T>
* @return
*/
<T> Set<T> listAuthorizedResource(int userId, Logger logger);
/**
* permission check
* @param userId
* @return
*/
boolean permissionCheck(int userId, String url, Logger logger);
}
}

125
dolphinscheduler-service/src/test/java/org/apache/dolphinscheduler/service/permission/ResourcePermissionCheckServiceTest.java

@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.dolphinscheduler.service.permission;
import com.google.common.collect.Lists;
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.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.service.process.ProcessService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* permission service test
*/
@RunWith(MockitoJUnitRunner.class)
public class ResourcePermissionCheckServiceTest {
private static final Logger logger = LoggerFactory.getLogger(ResourcePermissionCheckServiceTest.class);
@Mock
private ProcessService processService;
@Mock
private ProjectMapper projectMapper;
@Mock
private ApplicationContext context;
@Mock
private ResourcePermissionCheckService<Object> resourcePermissionCheckService;
@InjectMocks
ResourcePermissionCheckServiceImpl resourcePermissionCheckServices;
protected static final Map<AuthorizationType, ResourcePermissionCheckServiceImpl.ResourceAcquisitionAndPermissionCheck<?>> RESOURCE_LIST_MAP = new ConcurrentHashMap<>();
@Test
public void testResourcePermissionCheck(){
User user = new User();
user.setId(1);
Object[] obj = new Object[]{1,2};
boolean result = this.resourcePermissionCheckService.resourcePermissionCheck(AuthorizationType.PROJECTS, obj, user.getId(), logger);
Assert.assertFalse(result);
}
@Test
public void testOperationPermissionCheck(){
User user = new User();
user.setId(1);
resourcePermissionCheckServices.setApplicationContext(context);
Assert.assertFalse(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, user.getId(), null, logger));
String sourceUrl = "/tmp/";
Assert.assertFalse(resourcePermissionCheckService.operationPermissionCheck(AuthorizationType.PROJECTS, user.getId(), sourceUrl, logger));
}
@Test
public void testUserOwnedResourceIdsAcquisition(){
User user = new User();
user.setId(1);
//ADMIN
user.setUserType(UserType.ADMIN_USER);
Object[] obj = new Object[]{1,2};
List<Project> projectList = Lists.newArrayList(this.getEntity());
Set result = resourcePermissionCheckServices.userOwnedResourceIdsAcquisition(AuthorizationType.PROJECTS,
user.getId(),
logger);
Assert.assertNotNull(result);
}
@Test
public void testSetApplication(){
resourcePermissionCheckServices.setApplicationContext(context);
}
/**
* create entity
*/
private Project getEntity() {
Project project = new Project();
project.setId(1);
project.setUserId(1);
project.setName("permissionsTest");
project.setUserName("permissionTest");
return project;
}
/**
* entity list
*/
private List<Project> getList() {
List<Project> list = new ArrayList<>();
list.add(getEntity());
return list;
}
}
Loading…
Cancel
Save