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/13 09:56:11 UTC
[dolphinscheduler] branch 2.0.2-prepare updated: [Cherry-pick-2.0.2][Feature][Dolphinscheduler-api] cherry-pick from dev to 2.0.2 (#7373)
This is an automated email from the ASF dual-hosted git repository.
leonbao pushed a commit to branch 2.0.2-prepare
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/2.0.2-prepare by this push:
new 65a6b58 [Cherry-pick-2.0.2][Feature][Dolphinscheduler-api] cherry-pick from dev to 2.0.2 (#7373)
65a6b58 is described below
commit 65a6b580ab27d13a7755a25a8b895dce77a451fb
Author: ouyangyewei <ou...@foxmail.com>
AuthorDate: Mon Dec 13 17:56:06 2021 +0800
[Cherry-pick-2.0.2][Feature][Dolphinscheduler-api] cherry-pick from dev to 2.0.2 (#7373)
* [Feature-7110][dolphinscheduler-api] support grant project by code
* [Feature-7180][dolphinscheduler-api] Revoke project permission for specified user
* [Feature-7191][dolphinscheduler-api] support query authorized user list by project code
* [Feature-7301][dolphinscheduler-api] Support query access token for specified user
Co-authored-by: ouyangyewei <ye...@alibaba-inc.com>
---
.../api/controller/AccessTokenController.java | 22 ++++++
.../api/controller/ProjectController.java | 22 ++++++
.../api/controller/UsersController.java | 49 +++++++++++++
.../apache/dolphinscheduler/api/enums/Status.java | 4 +-
.../api/service/AccessTokenService.java | 9 +++
.../api/service/ProjectService.java | 9 +++
.../dolphinscheduler/api/service/UsersService.java | 19 +++++
.../api/service/impl/AccessTokenServiceImpl.java | 25 +++++++
.../api/service/impl/ProjectServiceImpl.java | 25 +++++++
.../api/service/impl/UsersServiceImpl.java | 84 ++++++++++++++++++++++
.../src/main/resources/i18n/messages.properties | 5 ++
.../main/resources/i18n/messages_en_US.properties | 5 ++
.../main/resources/i18n/messages_zh_CN.properties | 5 ++
.../api/controller/AccessTokenControllerTest.java | 13 ++++
.../api/controller/ProjectControllerTest.java | 10 +++
.../api/controller/UsersControllerTest.java | 37 ++++++++++
.../api/service/AccessTokenServiceTest.java | 21 ++++++
.../api/service/ProjectServiceTest.java | 54 ++++++++++++++
.../api/service/UsersServiceTest.java | 84 ++++++++++++++++++++++
.../dao/mapper/AccessTokenMapper.java | 10 +++
.../dolphinscheduler/dao/mapper/UserMapper.java | 7 ++
.../dao/mapper/AccessTokenMapper.xml | 7 ++
.../dolphinscheduler/dao/mapper/UserMapper.xml | 8 +++
23 files changed, 533 insertions(+), 1 deletion(-)
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
index 01bb22d..a841bd6 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/AccessTokenController.java
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.controller;
+import static org.apache.dolphinscheduler.api.enums.Status.QUERY_ACCESSTOKEN_BY_USER_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_ACCESS_TOKEN_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_ACCESS_TOKEN_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.GENERATE_TOKEN_ERROR;
@@ -141,6 +142,27 @@ public class AccessTokenController extends BaseController {
}
/**
+ * query access token for specified user
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return token list for specified user
+ */
+ @ApiOperation(value = "queryAccessTokenByUser", notes = "QUERY_ACCESS_TOKEN_BY_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", dataType = "Int")
+ })
+ @GetMapping(value = "/user/{userId}")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_ACCESSTOKEN_BY_USER_ERROR)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result queryAccessTokenByUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @PathVariable("userId") Integer userId) {
+ Map<String, Object> result = this.accessTokenService.queryAccessTokenByUser(loginUser, userId);
+ return this.returnDataList(result);
+ }
+
+ /**
* delete access token by id
*
* @param loginUser login user
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
index 1dfb7e5..22e5822 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.controller;
+import static org.apache.dolphinscheduler.api.enums.Status.QUERY_AUTHORIZED_USER;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR;
@@ -238,6 +239,27 @@ public class ProjectController extends BaseController {
}
/**
+ * query authorized user
+ *
+ * @param loginUser login user
+ * @param projectCode project code
+ * @return users who have permission for the specified project
+ */
+ @ApiOperation(value = "queryAuthorizedUser", notes = "QUERY_AUTHORIZED_USER_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "projectCode", value = "PROJECT_CODE", dataType = "Long", example = "100")
+ })
+ @GetMapping(value = "/authed-user")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(QUERY_AUTHORIZED_USER)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result queryAuthorizedUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam("projectCode") Long projectCode) {
+ Map<String, Object> result = this.projectService.queryAuthorizedUser(loginUser, projectCode);
+ return this.returnDataList(result);
+ }
+
+ /**
* query authorized and user created project
*
* @param loginUser login user
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 11de038..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
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.controller;
+import static org.apache.dolphinscheduler.api.enums.Status.REVOKE_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.AUTHORIZED_USER_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_USER_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_USER_BY_ID_ERROR;
@@ -235,6 +236,54 @@ public class UsersController extends BaseController {
}
/**
+ * grant project by code
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @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 = "projectCode", value = "PROJECT_CODE", required = true, type = "Long")
+ })
+ @PostMapping(value = "/grant-project-by-code")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(GRANT_PROJECT_ERROR)
+ @AccessLogAnnotation
+ public Result grantProjectByCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "projectCode") long projectCode) {
+ Map<String, Object> result = this.usersService.grantProjectByCode(loginUser, userId, projectCode);
+ return this.returnDataList(result);
+ }
+
+ /**
+ * revoke project
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param projectCode project code
+ * @return revoke result code
+ */
+ @ApiOperation(value = "revokeProject", notes = "REVOKE_PROJECT_NOTES")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataType = "Int", example = "100"),
+ @ApiImplicitParam(name = "projectCode", value = "PROJECT_CODE", required = true, type = "Long", example = "100")
+ })
+ @PostMapping(value = "/revoke-project")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(REVOKE_PROJECT_ERROR)
+ @AccessLogAnnotation
+ public Result revokeProject(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "userId") int userId,
+ @RequestParam(value = "projectCode") long projectCode) {
+ Map<String, Object> result = this.usersService.revokeProject(loginUser, userId, projectCode);
+ return returnDataList(result);
+ }
+
+ /**
* grant resource
*
* @param loginUser login user
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
index 7276404..c4243f0 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
@@ -212,7 +212,8 @@ public enum Status {
TRANSFORM_PROJECT_OWNERSHIP(10179, "Please transform project ownership [{0}]", "请先转移项目所有权[{0}]"),
QUERY_ALERT_GROUP_ERROR(10180, "query alert group error", "查询告警组错误"),
CURRENT_LOGIN_USER_TENANT_NOT_EXIST(10181, "the tenant of the currently login user is not specified", "未指定当前登录用户的租户"),
-
+ REVOKE_PROJECT_ERROR(10182, "revoke project error", "撤销项目授权错误"),
+ QUERY_AUTHORIZED_USER(10183, "query authorized user error", "查询拥有项目权限的用户错误"),
UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"),
UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"),
@@ -304,6 +305,7 @@ public enum Status {
UPDATE_ACCESS_TOKEN_ERROR(70013, "update access token error", "更新访问token错误"),
DELETE_ACCESS_TOKEN_ERROR(70014, "delete access token error", "删除访问token错误"),
ACCESS_TOKEN_NOT_EXIST(70015, "access token not exist", "访问token不存在"),
+ QUERY_ACCESSTOKEN_BY_USER_ERROR(70016, "query access token by user error", "查询访问指定用户的token错误"),
COMMAND_STATE_COUNT_ERROR(80001, "task instance state count error", "查询各状态任务实例数错误"),
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java
index fc4ed78..b3e14ee 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AccessTokenService.java
@@ -39,6 +39,15 @@ public interface AccessTokenService {
Result queryAccessTokenList(User loginUser, String searchVal, Integer pageNo, Integer pageSize);
/**
+ * query access token for specified user
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return token list for specified user
+ */
+ Map<String, Object> queryAccessTokenByUser(User loginUser, Integer userId);
+
+ /**
* create token
*
* @param userId token for user
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java
index dffa866..1300834 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProjectService.java
@@ -111,6 +111,15 @@ public interface ProjectService {
Map<String, Object> queryAuthorizedProject(User loginUser, Integer userId);
/**
+ * query authorized user
+ *
+ * @param loginUser login user
+ * @param projectCode project code
+ * @return users who have permission for the specified project
+ */
+ Map<String, Object> queryAuthorizedUser(User loginUser, Long projectCode);
+
+ /**
* query authorized project
*
* @param loginUser login user
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 a5c004b..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
@@ -154,6 +154,25 @@ public interface UsersService {
/**
+ * grant project by code
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param projectCode project code
+ * @return grant result code
+ */
+ Map<String, Object> grantProjectByCode(User loginUser, int userId, long projectCode);
+
+ /**
+ * revoke the project permission for specified user.
+ * @param loginUser Login user
+ * @param userId User id
+ * @param projectCode Project Code
+ * @return
+ */
+ Map<String, Object> revokeProject(User loginUser, int userId, long projectCode);
+
+ /**
* grant resource
*
* @param loginUser login user
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AccessTokenServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AccessTokenServiceImpl.java
index 3904846..f5e434a 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AccessTokenServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AccessTokenServiceImpl.java
@@ -31,6 +31,7 @@ import org.apache.dolphinscheduler.dao.mapper.AccessTokenMapper;
import java.util.Date;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
@@ -79,6 +80,30 @@ public class AccessTokenServiceImpl extends BaseServiceImpl implements AccessTok
}
/**
+ * query access token for specified user
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @return token list for specified user
+ */
+ @Override
+ public Map<String, Object> queryAccessTokenByUser(User loginUser, Integer userId) {
+ Map<String, Object> result = new HashMap<>();
+ result.put(Constants.STATUS, false);
+
+ // only admin can operate
+ if (isNotAdmin(loginUser, result)) {
+ return result;
+ }
+
+ // query access token for specified user
+ List<AccessToken> accessTokenList = this.accessTokenMapper.queryAccessTokenByUser(userId);
+ result.put(Constants.DATA_LIST, accessTokenList);
+ this.putMsg(result, Status.SUCCESS);
+ return result;
+ }
+
+ /**
* create token
*
* @param userId token for user
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java
index a02458a..3bb222b 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java
@@ -390,6 +390,31 @@ public class ProjectServiceImpl extends BaseServiceImpl implements ProjectServic
}
/**
+ * query authorized user
+ *
+ * @param loginUser login user
+ * @param projectCode project code
+ * @return users who have permission for the specified project
+ */
+ @Override
+ public Map<String, Object> queryAuthorizedUser(User loginUser, Long projectCode) {
+ Map<String, Object> result = new HashMap<>();
+
+ // 1. check read permission
+ Project project = this.projectMapper.queryByCode(projectCode);
+ boolean hasProjectAndPerm = this.hasProjectAndPerm(loginUser, project, result);
+ if (!hasProjectAndPerm) {
+ return result;
+ }
+
+ // 2. query authorized user list
+ List<User> users = this.userMapper.queryAuthedUserListByProjectId(project.getId());
+ result.put(Constants.DATA_LIST, users);
+ this.putMsg(result, Status.SUCCESS);
+ return result;
+ }
+
+ /**
* query authorized project
*
* @param loginUser login 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 e07516a..ab7a244 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
@@ -580,6 +580,90 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService {
}
/**
+ * grant project by code
+ *
+ * @param loginUser login user
+ * @param userId user id
+ * @param projectCode project code
+ * @return grant result code
+ */
+ @Override
+ 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. check if user is existed
+ User tempUser = this.userMapper.selectById(userId);
+ if (tempUser == null) {
+ this.putMsg(result, Status.USER_NOT_EXIST, userId);
+ return result;
+ }
+
+ // 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;
+ }
+
+ // 3. only project owner can operate
+ if (!this.hasPerm(loginUser, project.getUserId())) {
+ this.putMsg(result, Status.USER_NO_OPERATION_PERM);
+ return result;
+ }
+
+ // 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;
+ }
+
+ /**
+ * revoke the project permission for specified user.
+ * @param loginUser Login user
+ * @param userId User id
+ * @param projectCode Project Code
+ * @return
+ */
+ @Override
+ public Map<String, Object> revokeProject(User loginUser, int userId, 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
+ User user = this.userMapper.selectById(userId);
+ if (user == null) {
+ this.putMsg(result, Status.USER_NOT_EXIST, userId);
+ return result;
+ }
+
+ // 3. 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. delete the relationship between project and user
+ this.projectUserMapper.deleteProjectRelation(project.getId(), user.getId());
+ this.putMsg(result, Status.SUCCESS);
+ return result;
+ }
+
+ /**
* grant resource
*
* @param loginUser login user
diff --git a/dolphinscheduler-api/src/main/resources/i18n/messages.properties b/dolphinscheduler-api/src/main/resources/i18n/messages.properties
index 62d3615..b5b127b 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages.properties
+++ b/dolphinscheduler-api/src/main/resources/i18n/messages.properties
@@ -140,10 +140,12 @@ DELETE_PROJECT_BY_ID_NOTES=delete project by id
QUERY_UNAUTHORIZED_PROJECT_NOTES=query unauthorized project
QUERY_ALL_PROJECT_LIST_NOTES=query all project list
QUERY_AUTHORIZED_PROJECT_NOTES=query authorized project
+QUERY_AUTHORIZED_USER_NOTES=query authorized user
TASK_RECORD_TAG=task record related operation
QUERY_TASK_RECORD_LIST_PAGING_NOTES=query task record list paging
CREATE_TOKEN_NOTES=create token ,note: please login first
QUERY_ACCESS_TOKEN_LIST_NOTES=query access token list paging
+QUERY_ACCESS_TOKEN_BY_USER_NOTES=query access token for specified user
SCHEDULE=schedule
WARNING_TYPE=warning type(sending strategy)
WARNING_GROUP_ID=warning group id
@@ -221,6 +223,9 @@ UPDATE_USER_NOTES=update user
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
+REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER
+PROJECT_CODE=project codes
GRANT_RESOURCE_NOTES=grant resource file
RESOURCE_IDS=resource ids(string format, multiple resources separated by ",")
GET_USER_INFO_NOTES=get user info
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 db705be..3fa384e 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
+++ b/dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
@@ -156,10 +156,12 @@ QUERY_ALL_PROJECT_LIST_NOTES=query all project list
DELETE_PROJECT_BY_ID_NOTES=delete project by id
QUERY_UNAUTHORIZED_PROJECT_NOTES=query unauthorized project
QUERY_AUTHORIZED_PROJECT_NOTES=query authorized project
+QUERY_AUTHORIZED_USER_NOTES=query authorized user
TASK_RECORD_TAG=task record related operation
QUERY_TASK_RECORD_LIST_PAGING_NOTES=query task record list paging
CREATE_TOKEN_NOTES=create token ,note: please login first
QUERY_ACCESS_TOKEN_LIST_NOTES=query access token list paging
+QUERY_ACCESS_TOKEN_BY_USER_NOTES=query access token for specified user
SCHEDULE=schedule
WARNING_TYPE=warning type(sending strategy)
WARNING_GROUP_ID=warning group id
@@ -268,6 +270,9 @@ UPDATE_QUEUE_NOTES=update queue
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
+REVOKE_PROJECT_NOTES=REVOKE PROJECT FOR USER
+PROJECT_CODE=project codes
GRANT_RESOURCE_NOTES=grant resource file
RESOURCE_IDS=resource ids(string format, multiple resources separated by ",")
GET_USER_INFO_NOTES=get user info
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 ec88f74..e18cdf3 100644
--- a/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
+++ b/dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
@@ -145,10 +145,12 @@ QUERY_ALL_PROJECT_LIST_NOTES=查询所有项目
DELETE_PROJECT_BY_ID_NOTES=通过ID删除项目
QUERY_UNAUTHORIZED_PROJECT_NOTES=查询未授权的项目
QUERY_AUTHORIZED_PROJECT_NOTES=查询授权项目
+QUERY_AUTHORIZED_USER_NOTES=查询拥有项目授权的用户
TASK_RECORD_TAG=任务记录相关操作
QUERY_TASK_RECORD_LIST_PAGING_NOTES=分页查询任务记录列表
CREATE_TOKEN_NOTES=创建token,注意需要先登录
QUERY_ACCESS_TOKEN_LIST_NOTES=分页查询access token列表
+QUERY_ACCESS_TOKEN_BY_USER_NOTES=查询指定用户的access token
SCHEDULE=定时
WARNING_TYPE=发送策略
WARNING_GROUP_ID=发送组ID
@@ -256,6 +258,9 @@ UPDATE_QUEUE_NOTES=更新队列
DELETE_USER_BY_ID_NOTES=删除用户通过ID
GRANT_PROJECT_NOTES=授权项目
PROJECT_IDS=项目IDS(字符串格式,多个项目以","分割)
+GRANT_PROJECT_BY_CODE_NOTES=授权项目
+REVOKE_PROJECT_NOTES=撤销用户的项目权限
+PROJECT_CODE=项目Code
GRANT_RESOURCE_NOTES=授权资源文件
RESOURCE_IDS=资源ID列表(字符串格式,多个资源ID以","分割)
GET_USER_INFO_NOTES=获取用户信息
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java
index a13d773..0a9d7a3 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AccessTokenControllerTest.java
@@ -110,6 +110,19 @@ public class AccessTokenControllerTest extends AbstractControllerTest {
}
@Test
+ public void testQueryAccessTokenByUser() throws Exception {
+ MvcResult mvcResult = this.mockMvc
+ .perform(get("/access-tokens/user/1")
+ .header("sessionId", this.sessionId))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andReturn();
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+ Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
+ logger.info(mvcResult.getResponse().getContentAsString());
+ }
+
+ @Test
public void testDelAccessTokenById() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("id","13");
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java
index 0bce72d..118484c 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java
@@ -126,6 +126,16 @@ public class ProjectControllerTest {
}
@Test
+ public void testQueryAuthorizedUser() {
+ Map<String, Object> result = new HashMap<>();
+ this.putMsg(result, Status.SUCCESS);
+
+ Mockito.when(this.projectService.queryAuthorizedUser(this.user, 3682329499136L)).thenReturn(result);
+ Result response = this.projectController.queryAuthorizedUser(this.user, 3682329499136L);
+ Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
+ }
+
+ @Test
public void testQueryAllProjectList() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
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 fb4b0ce..248cfea 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
@@ -109,6 +109,43 @@ public class UsersControllerTest extends AbstractControllerTest {
}
@Test
+ public void testGrantProjectByCode() throws Exception {
+ MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
+ paramsMap.add("userId", "32");
+ paramsMap.add("projectCode", "3682329499136");
+
+ 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();
+
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+ Assert.assertEquals(Status.USER_NOT_EXIST.getCode(), result.getCode().intValue());
+ logger.info(mvcResult.getResponse().getContentAsString());
+ }
+
+ @Test
+ public void testRevokeProject() throws Exception {
+ MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
+ paramsMap.add("userId", "32");
+ paramsMap.add("projectCode", "3682329499136");
+
+ MvcResult mvcResult = this.mockMvc.perform(post("/users/revoke-project")
+ .header(SESSION_ID, this.sessionId)
+ .params(paramsMap))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andReturn();
+
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+ Assert.assertEquals(Status.USER_NOT_EXIST.getCode(), result.getCode().intValue());
+ logger.info(mvcResult.getResponse().getContentAsString());
+ }
+
+ @Test
public void testGrantResource() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","32");
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AccessTokenServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AccessTokenServiceTest.java
index 3b8ef6b..8f8554f 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AccessTokenServiceTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/AccessTokenServiceTest.java
@@ -38,11 +38,13 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
+import org.assertj.core.util.Lists;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -80,6 +82,25 @@ public class AccessTokenServiceTest {
}
@Test
+ public void testQueryAccessTokenByUser() {
+ List<AccessToken> accessTokenList = Lists.newArrayList(this.getEntity());
+ Mockito.when(this.accessTokenMapper.queryAccessTokenByUser(1)).thenReturn(accessTokenList);
+
+ // USER_NO_OPERATION_PERM
+ User user = this.getLoginUser();
+ user.setUserType(UserType.GENERAL_USER);
+ Map<String, Object> result = this.accessTokenService.queryAccessTokenByUser(user, 1);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
+
+ // SUCCESS
+ user.setUserType(UserType.ADMIN_USER);
+ result = this.accessTokenService.queryAccessTokenByUser(user, 1);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
+ }
+
+ @Test
public void testCreateToken() {
when(accessTokenMapper.insert(any(AccessToken.class))).thenReturn(2);
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
index 6f516b7..de782df 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProjectServiceTest.java
@@ -277,6 +277,38 @@ public class ProjectServiceTest {
}
@Test
+ public void testQueryAuthorizedUser() {
+ final User loginUser = this.getLoginUser();
+
+ // Failure 1: PROJECT_NOT_FOUND
+ Map<String, Object> result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
+ logger.info("FAILURE 1: {}", result.toString());
+ Assert.assertEquals(Status.PROJECT_NOT_FOUNT, result.get(Constants.STATUS));
+
+ // Failure 2: USER_NO_OPERATION_PROJECT_PERM
+ loginUser.setId(100);
+ Mockito.when(this.projectMapper.queryByCode(Mockito.anyLong())).thenReturn(this.getProject());
+ result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
+ logger.info("FAILURE 2: {}", result.toString());
+ Assert.assertEquals(Status.USER_NO_OPERATION_PROJECT_PERM, result.get(Constants.STATUS));
+
+ // SUCCESS
+ loginUser.setUserType(UserType.ADMIN_USER);
+ Mockito.when(this.userMapper.queryAuthedUserListByProjectId(1)).thenReturn(this.getUserList());
+ result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
+ logger.info("SUCCESS 1: {}", result.toString());
+ List<User> users = (List<User>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(users));
+
+ loginUser.setId(1);
+ loginUser.setUserType(UserType.GENERAL_USER);
+ result = this.projectService.queryAuthorizedUser(loginUser, 3682329499136L);
+ logger.info("SUCCESS 2: {}", result.toString());
+ users = (List<User>) result.get(Constants.DATA_LIST);
+ Assert.assertTrue(CollectionUtils.isNotEmpty(users));
+ }
+
+ @Test
public void testQueryCreatedProject() {
User loginUser = getLoginUser();
@@ -366,6 +398,28 @@ public class ProjectServiceTest {
}
/**
+ * Get general user
+ * @return
+ */
+ private User getGeneralUser() {
+ User user = new User();
+ user.setUserType(UserType.GENERAL_USER);
+ user.setUserName("userTest0001");
+ user.setUserPassword("userTest0001");
+ return user;
+ }
+
+ /**
+ * Get user list
+ * @return
+ */
+ private List<User> getUserList() {
+ List<User> userList = new ArrayList<>();
+ userList.add(this.getGeneralUser());
+ return userList;
+ }
+
+ /**
* get project user
*/
private ProjectUser getProjectUser() {
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 e586db8..85daa7e 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
@@ -339,6 +339,74 @@ public class UsersServiceTest {
}
@Test
+ public void testGrantProjectByCode() {
+ // 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();
+ 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));
+
+ // 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.SUCCESS, result.get(Constants.STATUS));
+
+ // 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));
+ }
+
+ @Test
+ public void testRevokeProject() {
+ Mockito.when(this.userMapper.selectById(1)).thenReturn(this.getUser());
+
+ final long projectCode = 3682329499136L;
+
+ // user no permission
+ User loginUser = new User();
+ Map<String, Object> result = this.usersService.revokeProject(loginUser, 1, 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.revokeProject(loginUser, 2, projectCode);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
+
+ // success
+ Mockito.when(this.projectMapper.queryByCode(Mockito.anyLong())).thenReturn(new Project());
+ result = this.usersService.revokeProject(loginUser, 1, projectCode);
+ logger.info(result.toString());
+ Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
+ }
+
+ @Test
public void testGrantResources() {
String resourceIds = "100000,120000";
when(userMapper.selectById(1)).thenReturn(getUser());
@@ -619,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() {
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.java
index 472ba35..3c73a56 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.java
@@ -25,6 +25,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import java.util.List;
+
/**
* accesstoken mapper interface
*/
@@ -45,6 +47,14 @@ public interface AccessTokenMapper extends BaseMapper<AccessToken> {
);
/**
+ * Query access token for specified user
+ *
+ * @param userId userId
+ * @return access token for specified user
+ */
+ List<AccessToken> queryAccessTokenByUser(@Param("userId") int userId);
+
+ /**
* delete by userId
*
* @param userId userId
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UserMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UserMapper.java
index 4418363..9fcb488 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UserMapper.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UserMapper.java
@@ -124,4 +124,11 @@ public interface UserMapper extends BaseMapper<User> {
* @return user list
*/
List<User> selectByIds(@Param("ids") List<Integer> ids);
+
+ /**
+ * query authed user list by projectId
+ * @param projectId projectId
+ * @return user list
+ */
+ List<User> queryAuthedUserListByProjectId(@Param("projectId") int projectId);
}
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.xml
index 35312fb..f8c8ad4 100644
--- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.xml
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/AccessTokenMapper.xml
@@ -31,6 +31,13 @@
</if>
order by t.update_time desc
</select>
+
+ <select id="queryAccessTokenByUser" resultType="org.apache.dolphinscheduler.dao.entity.AccessToken">
+ select id, user_id, token, expire_time, create_time, update_time
+ from t_ds_access_token
+ where user_id = #{userId}
+ </select>
+
<delete id="deleteAccessTokenByUserId">
delete from t_ds_access_token
where user_id = #{userId}
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml
index dec6a51..570e395 100644
--- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml
@@ -123,4 +123,12 @@
#{id}
</foreach>
</select>
+ <select id="queryAuthedUserListByProjectId" resultType="org.apache.dolphinscheduler.dao.entity.User">
+ select
+ <include refid="baseSqlV2">
+ <property name="alias" value="u"/>
+ </include>
+ from t_ds_user u, t_ds_relation_project_user rel
+ where u.id = rel.user_id and rel.project_id = #{projectId}
+ </select>
</mapper>