Browse Source

[Feature-7110][dolphinscheduler-api] support grant project by code (#7390)

Co-authored-by: ouyangyewei <yewei.oyyw@alibaba-inc.com>
3.0.0/version-upgrade
ouyangyewei 3 years ago committed by GitHub
parent
commit
57697602c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
  2. 4
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
  3. 51
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
  4. 1
      dolphinscheduler-api/src/main/resources/i18n/messages.properties
  5. 1
      dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
  6. 1
      dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
  7. 9
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java
  8. 61
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java

10
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java

@ -240,13 +240,13 @@ public class UsersController extends BaseController {
* *
* @param loginUser login user * @param loginUser login user
* @param userId user id * @param userId user id
* @param projectCodes project code array * @param projectCode project code
* @return grant result code * @return grant result code
*/ */
@ApiOperation(value = "grantProjectByCode", notes = "GRANT_PROJECT_BY_CODE_NOTES") @ApiOperation(value = "grantProjectByCode", notes = "GRANT_PROJECT_BY_CODE_NOTES")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType = "Int", example = "100"), @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType = "Int", example = "100"),
@ApiImplicitParam(name = "projectCodes", value = "PROJECT_CODES", required = true, type = "String") @ApiImplicitParam(name = "projectCode", value = "PROJECT_CODE", required = true, type = "Long")
}) })
@PostMapping(value = "/grant-project-by-code") @PostMapping(value = "/grant-project-by-code")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@ -254,9 +254,9 @@ public class UsersController extends BaseController {
@AccessLogAnnotation @AccessLogAnnotation
public Result grantProjectByCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, public Result grantProjectByCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "userId") int userId, @RequestParam(value = "userId") int userId,
@RequestParam(value = "projectCodes") String projectCodes) { @RequestParam(value = "projectCode") long projectCode) {
Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, userId, projectCodes); Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, userId, projectCode);
return returnDataList(result); return this.returnDataList(result);
} }
/** /**

4
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java

@ -158,10 +158,10 @@ public interface UsersService {
* *
* @param loginUser login user * @param loginUser login user
* @param userId user id * @param userId user id
* @param projectCodes project code array * @param projectCode project code
* @return grant result code * @return grant result code
*/ */
Map<String, Object> grantProjectByCode(User loginUser, int userId, String projectCodes); Map<String, Object> grantProjectByCode(User loginUser, int userId, long projectCode);
/** /**
* revoke the project permission for specified user. * revoke the project permission for specified user.

51
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java

@ -584,54 +584,45 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService {
* *
* @param loginUser login user * @param loginUser login user
* @param userId user id * @param userId user id
* @param projectCodes project code array * @param projectCode project code
* @return grant result code * @return grant result code
*/ */
@Override @Override
public Map<String, Object> grantProjectByCode(final User loginUser, final int userId, final String projectCodes) { public Map<String, Object> grantProjectByCode(final User loginUser, final int userId, final long projectCode) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put(Constants.STATUS, false); result.put(Constants.STATUS, false);
// 1. only admin can operate // 1. check if user is existed
if (this.check(result, !this.isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
return result;
}
// 2. check if user is existed
User tempUser = this.userMapper.selectById(userId); User tempUser = this.userMapper.selectById(userId);
if (tempUser == null) { if (tempUser == null) {
putMsg(result, Status.USER_NOT_EXIST, userId); this.putMsg(result, Status.USER_NOT_EXIST, userId);
return result; return result;
} }
// 3. if the selected projectCodes are empty, delete all items associated with the user // 2. check if project is existed
if (this.check(result, StringUtils.isEmpty(projectCodes), Status.SUCCESS)) { Project project = this.projectMapper.queryByCode(projectCode);
this.projectUserMapper.deleteProjectRelation(0, userId); if (project == null) {
this.putMsg(result, Status.PROJECT_NOT_FOUNT, projectCode);
return result; return result;
} }
// 4. maintain the relationship between project and user // 3. only project owner can operate
Set<Long> projectCodeSet = Arrays.stream(projectCodes.split(Constants.COMMA)).map(Long::parseLong).collect(Collectors.toSet()); if (!this.hasPerm(loginUser, project.getUserId())) {
final List<Project> projectList = this.projectMapper.queryByCodes(projectCodeSet); this.putMsg(result, Status.USER_NO_OPERATION_PERM);
if (CollectionUtils.isEmpty(projectList)) {
logger.info("project not exists");
putMsg(result, Status.PROJECT_NOT_FOUNT, projectCodes);
return result; return result;
} }
for (final Project project : projectList) {
final Date today = new Date();
ProjectUser projectUser = new ProjectUser();
projectUser.setUserId(userId);
projectUser.setProjectId(project.getId());
projectUser.setPerm(7);
projectUser.setCreateTime(today);
projectUser.setUpdateTime(today);
this.projectUserMapper.insert(projectUser);
}
putMsg(result, Status.SUCCESS); // 4. maintain the relationship between project and user
final Date today = new Date();
ProjectUser projectUser = new ProjectUser();
projectUser.setUserId(userId);
projectUser.setProjectId(project.getId());
projectUser.setPerm(7);
projectUser.setCreateTime(today);
projectUser.setUpdateTime(today);
this.projectUserMapper.insert(projectUser);
this.putMsg(result, Status.SUCCESS);
return result; return result;
} }

1
dolphinscheduler-api/src/main/resources/i18n/messages.properties

@ -224,7 +224,6 @@ DELETE_USER_BY_ID_NOTES=delete user by id
GRANT_PROJECT_NOTES=GRANT PROJECT GRANT_PROJECT_NOTES=GRANT PROJECT
PROJECT_IDS=project ids(string format, multiple projects separated by ",") PROJECT_IDS=project ids(string format, multiple projects separated by ",")
GRANT_PROJECT_BY_CODE_NOTES=GRANT PROJECT BY CODE GRANT_PROJECT_BY_CODE_NOTES=GRANT PROJECT BY CODE
PROJECT_CODES=project codes(string format, multiple project codes separated by ",")
REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER
PROJECT_CODE=project codes PROJECT_CODE=project codes
GRANT_RESOURCE_NOTES=grant resource file GRANT_RESOURCE_NOTES=grant resource file

1
dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties

@ -271,7 +271,6 @@ DELETE_USER_BY_ID_NOTES=delete user by id
GRANT_PROJECT_NOTES=GRANT PROJECT GRANT_PROJECT_NOTES=GRANT PROJECT
PROJECT_IDS=project ids(string format, multiple projects separated by ",") PROJECT_IDS=project ids(string format, multiple projects separated by ",")
GRANT_PROJECT_BY_CODE_NOTES=GRANT PROJECT BY CODE GRANT_PROJECT_BY_CODE_NOTES=GRANT PROJECT BY CODE
PROJECT_CODES=project codes(string format, multiple project codes separated by ",")
REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER
PROJECT_CODE=project codes PROJECT_CODE=project codes
GRANT_RESOURCE_NOTES=grant resource file GRANT_RESOURCE_NOTES=grant resource file

1
dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties

@ -259,7 +259,6 @@ DELETE_USER_BY_ID_NOTES=删除用户通过ID
GRANT_PROJECT_NOTES=授权项目 GRANT_PROJECT_NOTES=授权项目
PROJECT_IDS=项目IDS(字符串格式,多个项目以","分割) PROJECT_IDS=项目IDS(字符串格式,多个项目以","分割)
GRANT_PROJECT_BY_CODE_NOTES=授权项目 GRANT_PROJECT_BY_CODE_NOTES=授权项目
PROJECT_CODES=项目Codes(字符串格式,多个项目Code以","分割)
REVOKE_PROJECT_NOTES=撤销用户的项目权限 REVOKE_PROJECT_NOTES=撤销用户的项目权限
PROJECT_CODE=项目Code PROJECT_CODE=项目Code
GRANT_RESOURCE_NOTES=授权资源文件 GRANT_RESOURCE_NOTES=授权资源文件

9
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java

@ -111,11 +111,12 @@ public class UsersControllerTest extends AbstractControllerTest {
public void testGrantProjectByCode() throws Exception { public void testGrantProjectByCode() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId", "32"); paramsMap.add("userId", "32");
paramsMap.add("projectCodes", "3682329499136,3643998558592"); paramsMap.add("projectCode", "3682329499136");
MvcResult mvcResult = mockMvc.perform(post("/users/grant-project-by-code") MvcResult mvcResult = this.mockMvc
.header(SESSION_ID, sessionId) .perform(post("/users/grant-project-by-code")
.params(paramsMap)) .header(SESSION_ID, this.sessionId)
.params(paramsMap))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn(); .andReturn();

61
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java

@ -70,7 +70,7 @@ import com.google.common.collect.Lists;
/** /**
* users service test * users service test
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.Silent.class)
public class UsersServiceTest { public class UsersServiceTest {
private static final Logger logger = LoggerFactory.getLogger(UsersServiceTest.class); private static final Logger logger = LoggerFactory.getLogger(UsersServiceTest.class);
@ -340,24 +340,43 @@ public class UsersServiceTest {
@Test @Test
public void testGrantProjectByCode() { public void testGrantProjectByCode() {
when(userMapper.selectById(1)).thenReturn(getUser()); // Mock Project, User
final long projectCode = 1L;
// user no permission final int projectCreator = 1;
final int authorizer = 100;
Mockito.when(this.userMapper.selectById(authorizer)).thenReturn(this.getUser());
Mockito.when(this.userMapper.selectById(projectCreator)).thenReturn(this.getUser());
Mockito.when(this.projectMapper.queryByCode(projectCode)).thenReturn(this.getProject());
// ERROR: USER_NOT_EXIST
User loginUser = new User(); User loginUser = new User();
String projectCodes = "3682329499136,3643998558592"; Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, 999, projectCode);
Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, 1, projectCodes); logger.info(result.toString());
Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
// ERROR: PROJECT_NOT_FOUNT
result = this.usersService.grantProjectByCode(loginUser, authorizer, 999);
logger.info(result.toString());
Assert.assertEquals(Status.PROJECT_NOT_FOUNT, result.get(Constants.STATUS));
// ERROR: USER_NO_OPERATION_PERM
loginUser.setId(999);
loginUser.setUserType(UserType.GENERAL_USER);
result = this.usersService.grantProjectByCode(loginUser, authorizer, projectCode);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS)); Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
// user not exist // SUCCESS: USER IS PROJECT OWNER
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setId(projectCreator);
result = this.usersService.grantProjectByCode(loginUser, 2, projectCodes); loginUser.setUserType(UserType.GENERAL_USER);
result = this.usersService.grantProjectByCode(loginUser, authorizer, projectCode);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
// success // SUCCESS: USER IS ADMINISTRATOR
Mockito.when(this.projectMapper.queryByCodes(Mockito.anyCollection())).thenReturn(Lists.newArrayList(new Project())); loginUser.setId(999);
result = this.usersService.grantProjectByCode(loginUser, 1, projectCodes); loginUser.setUserType(UserType.ADMIN_USER);
result = this.usersService.grantProjectByCode(loginUser, authorizer, 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));
} }
@ -667,6 +686,22 @@ public class UsersServiceTest {
return user; return user;
} }
/**
* Get project
* @return
*/
private Project getProject() {
Project project = new Project();
project.setId(1);
project.setCode(1L);
project.setUserId(1);
project.setName("PJ-001");
project.setPerm(7);
project.setDefCount(0);
project.setInstRunningCount(0);
return project;
}
/** /**
* get user * get user
*/ */

Loading…
Cancel
Save