You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by le...@apache.org on 2021/12/14 04:39:39 UTC

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

This is an automated email from the ASF dual-hosted git repository.

leonbao 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 5769760  [Feature-7110][dolphinscheduler-api] support grant project by code (#7390)
5769760 is described below

commit 57697602c53d4db54f70abad1d37d41926f87bb7
Author: ouyangyewei <ou...@foxmail.com>
AuthorDate: Tue Dec 14 12:39:08 2021 +0800

    [Feature-7110][dolphinscheduler-api] support grant project by code (#7390)
    
    Co-authored-by: ouyangyewei <ye...@alibaba-inc.com>
---
 .../api/controller/UsersController.java            | 10 ++--
 .../dolphinscheduler/api/service/UsersService.java |  4 +-
 .../api/service/impl/UsersServiceImpl.java         | 51 ++++++++----------
 .../src/main/resources/i18n/messages.properties    |  1 -
 .../main/resources/i18n/messages_en_US.properties  |  1 -
 .../main/resources/i18n/messages_zh_CN.properties  |  1 -
 .../api/controller/UsersControllerTest.java        |  9 ++--
 .../api/service/UsersServiceTest.java              | 61 +++++++++++++++++-----
 8 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
index 502023a..a79e5f7 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
+++ b/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 userId user id
-     * @param projectCodes project code array
+     * @param projectCode project code
      * @return grant result code
      */
     @ApiOperation(value = "grantProjectByCode", notes = "GRANT_PROJECT_BY_CODE_NOTES")
     @ApiImplicitParams({
         @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")
     @ResponseStatus(HttpStatus.OK)
@@ -254,9 +254,9 @@ public class UsersController extends BaseController {
     @AccessLogAnnotation
     public Result grantProjectByCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
             @RequestParam(value = "userId") int userId,
-            @RequestParam(value = "projectCodes") String projectCodes) {
-        Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, userId, projectCodes);
-        return returnDataList(result);
+            @RequestParam(value = "projectCode") long projectCode) {
+        Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, userId, projectCode);
+        return this.returnDataList(result);
     }
 
     /**
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
index 6e701a0..485702a 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
@@ -158,10 +158,10 @@ public interface UsersService {
      *
      * @param loginUser login user
      * @param userId user id
-     * @param projectCodes project code array
+     * @param projectCode project 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.
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
index 4caf22c..2c65c40 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/UsersServiceImpl.java
+++ b/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 userId user id
-     * @param projectCodes project code array
+     * @param projectCode project code
      * @return grant result code
      */
     @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<>();
         result.put(Constants.STATUS, false);
 
-        // 1. only admin can operate
-        if (this.check(result, !this.isAdmin(loginUser), Status.USER_NO_OPERATION_PERM)) {
-            return result;
-        }
-
-        // 2. check if user is existed
+        // 1. check if user is existed
         User tempUser = this.userMapper.selectById(userId);
         if (tempUser == null) {
-            putMsg(result, Status.USER_NOT_EXIST, userId);
+            this.putMsg(result, Status.USER_NOT_EXIST, userId);
             return result;
         }
 
-        // 3. if the selected projectCodes are empty, delete all items associated with the user
-        if (this.check(result, StringUtils.isEmpty(projectCodes), Status.SUCCESS)) {
-            this.projectUserMapper.deleteProjectRelation(0, userId);
+        // 2. check if project is existed
+        Project project = this.projectMapper.queryByCode(projectCode);
+        if (project == null) {
+            this.putMsg(result, Status.PROJECT_NOT_FOUNT, projectCode);
             return result;
         }
 
-        // 4. maintain the relationship between project and user
-        Set<Long> projectCodeSet = Arrays.stream(projectCodes.split(Constants.COMMA)).map(Long::parseLong).collect(Collectors.toSet());
-        final List<Project> projectList = this.projectMapper.queryByCodes(projectCodeSet);
-        if (CollectionUtils.isEmpty(projectList)) {
-            logger.info("project not exists");
-            putMsg(result, Status.PROJECT_NOT_FOUNT, projectCodes);
+        // 3. only project owner can operate
+        if (!this.hasPerm(loginUser, project.getUserId())) {
+            this.putMsg(result, Status.USER_NO_OPERATION_PERM);
             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;
     }
 
diff --git a/dolphinscheduler-api/src/main/resources/i18n/messages.properties b/dolphinscheduler-api/src/main/resources/i18n/messages.properties
index 282dcf4..b5b127b 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages.properties
+++ b/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 
 PROJECT_IDS=project ids(string format, multiple projects separated by ",")
 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
 PROJECT_CODE=project codes
 GRANT_RESOURCE_NOTES=grant resource file
diff --git a/dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties b/dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
index 4b48d4a..3fa384e 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
+++ b/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 
 PROJECT_IDS=project ids(string format, multiple projects separated by ",")
 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
 PROJECT_CODE=project codes
 GRANT_RESOURCE_NOTES=grant resource file
diff --git a/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties b/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
index e6ede24..e18cdf3 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
+++ b/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
@@ -259,7 +259,6 @@ DELETE_USER_BY_ID_NOTES=删除用户通过ID
 GRANT_PROJECT_NOTES=授权项目
 PROJECT_IDS=项目IDS(字符串格式,多个项目以","分割)
 GRANT_PROJECT_BY_CODE_NOTES=授权项目
-PROJECT_CODES=项目Codes(字符串格式,多个项目Code以","分割)
 REVOKE_PROJECT_NOTES=撤销用户的项目权限
 PROJECT_CODE=项目Code
 GRANT_RESOURCE_NOTES=授权资源文件
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java
index 5b69614..2794bae 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/UsersControllerTest.java
+++ b/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 {
         MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
         paramsMap.add("userId", "32");
-        paramsMap.add("projectCodes", "3682329499136,3643998558592");
+        paramsMap.add("projectCode", "3682329499136");
 
-        MvcResult mvcResult = mockMvc.perform(post("/users/grant-project-by-code")
-                                                      .header(SESSION_ID, sessionId)
-                                                      .params(paramsMap))
+        MvcResult mvcResult = this.mockMvc
+                .perform(post("/users/grant-project-by-code")
+                .header(SESSION_ID, this.sessionId)
+                .params(paramsMap))
                 .andExpect(status().isOk())
                 .andExpect(content().contentType(MediaType.APPLICATION_JSON))
                 .andReturn();
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
index acfe220..5e0eb6b 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
+++ b/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
  */
-@RunWith(MockitoJUnitRunner.class)
+@RunWith(MockitoJUnitRunner.Silent.class)
 public class UsersServiceTest {
 
     private static final Logger logger = LoggerFactory.getLogger(UsersServiceTest.class);
@@ -340,24 +340,43 @@ public class UsersServiceTest {
 
     @Test
     public void testGrantProjectByCode() {
-        when(userMapper.selectById(1)).thenReturn(getUser());
-
-        // user no permission
+        // Mock Project, User
+        final long projectCode = 1L;
+        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();
-        String projectCodes = "3682329499136,3643998558592";
-        Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, 1, projectCodes);
+        Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, 999, projectCode);
+        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());
         Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
 
-        // user not exist
-        loginUser.setUserType(UserType.ADMIN_USER);
-        result = this.usersService.grantProjectByCode(loginUser, 2, projectCodes);
+        // SUCCESS: USER IS PROJECT OWNER
+        loginUser.setId(projectCreator);
+        loginUser.setUserType(UserType.GENERAL_USER);
+        result = this.usersService.grantProjectByCode(loginUser, authorizer, projectCode);
         logger.info(result.toString());
-        Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
+        Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
 
-        // success
-        Mockito.when(this.projectMapper.queryByCodes(Mockito.anyCollection())).thenReturn(Lists.newArrayList(new Project()));
-        result = this.usersService.grantProjectByCode(loginUser, 1, projectCodes);
+        // SUCCESS: USER IS ADMINISTRATOR
+        loginUser.setId(999);
+        loginUser.setUserType(UserType.ADMIN_USER);
+        result = this.usersService.grantProjectByCode(loginUser, authorizer, projectCode);
         logger.info(result.toString());
         Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
     }
@@ -668,6 +687,22 @@ public class UsersServiceTest {
     }
 
     /**
+     * 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
      */
     private User getGeneralUser() {