Browse Source

feature: Add user state #1923 (#2424)

* feature: #1923

* fix:docker sql script add column

* fix: update sql script

* fix: UT bug

* fix: UT bug

* fix: UT bug

* fix: e2e UT bug

* fix: e2e button location

Co-authored-by: dailidong <dailidong66@gmail.com>
pull/2/head
Rubik-W 4 years ago committed by GitHub
parent
commit
68e3487e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      docker/postgres/docker-entrypoint-initdb/init.sql
  2. 25
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/UsersController.java
  3. 1
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  4. 10
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptor.java
  5. 8
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/PasswordAuthenticator.java
  6. 14
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
  7. 1
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoginControllerTest.java
  8. 6
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptorTest.java
  9. 8
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/PasswordAuthenticatorTest.java
  10. 18
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
  11. 14
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/User.java
  12. 2
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml
  13. 15
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue
  14. 8
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue
  15. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  16. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
  17. 2
      e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java
  18. 21
      sql/upgrade/1.2.2_schema/mysql/dolphinscheduler_ddl.sql
  19. 20
      sql/upgrade/1.2.2_schema/postgresql/dolphinscheduler_ddl.sql

3
docker/postgres/docker-entrypoint-initdb/init.sql

@ -623,6 +623,7 @@ CREATE TABLE t_ds_user (
create_time timestamp DEFAULT NULL , create_time timestamp DEFAULT NULL ,
update_time timestamp DEFAULT NULL , update_time timestamp DEFAULT NULL ,
queue varchar(64) DEFAULT NULL , queue varchar(64) DEFAULT NULL ,
state int DEFAULT 1 ,
PRIMARY KEY (id) PRIMARY KEY (id)
); );
@ -749,7 +750,7 @@ ALTER TABLE t_ds_worker_server ALTER COLUMN id SET DEFAULT NEXTVAL('t_ds_worker_
-- Records of t_ds_user?user : admin , password : dolphinscheduler123 -- Records of t_ds_user?user : admin , password : dolphinscheduler123
INSERT INTO t_ds_user(user_name,user_password,user_type,email,phone,tenant_id,create_time,update_time) VALUES ('admin', '7ad2410b2f4c074479a8937a28a22b8f', '0', 'xxx@qq.com', 'xx', '0', '2018-03-27 15:48:50', '2018-10-24 17:40:22'); INSERT INTO t_ds_user(user_name,user_password,user_type,email,phone,state,tenant_id,create_time,update_time) VALUES ('admin', '7ad2410b2f4c074479a8937a28a22b8f', '0', 'xxx@qq.com', 'xx', 1, '0', '2018-03-27 15:48:50', '2018-10-24 17:40:22');
-- Records of t_ds_alertgroup,dolphinscheduler warning group -- Records of t_ds_alertgroup,dolphinscheduler warning group
INSERT INTO t_ds_alertgroup(group_name,group_type,description,create_time,update_time) VALUES ('dolphinscheduler warning group', '0', 'dolphinscheduler warning group','2018-11-29 10:20:39', '2018-11-29 10:20:39'); INSERT INTO t_ds_alertgroup(group_name,group_type,description,create_time,update_time) VALUES ('dolphinscheduler warning group', '0', 'dolphinscheduler warning group','2018-11-29 10:20:39', '2018-11-29 10:20:39');

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

@ -72,7 +72,8 @@ public class UsersController extends BaseController {
@ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"), @ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"), @ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"), @ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100") @ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "state", value = "STATE", dataType = "Int", example = "1")
}) })
@PostMapping(value = "/create") @PostMapping(value = "/create")
@ResponseStatus(HttpStatus.CREATED) @ResponseStatus(HttpStatus.CREATED)
@ -83,11 +84,11 @@ public class UsersController extends BaseController {
@RequestParam(value = "tenantId") int tenantId, @RequestParam(value = "tenantId") int tenantId,
@RequestParam(value = "queue", required = false, defaultValue = "") String queue, @RequestParam(value = "queue", required = false, defaultValue = "") String queue,
@RequestParam(value = "email") String email, @RequestParam(value = "email") String email,
@RequestParam(value = "phone", required = false) String phone) throws Exception { @RequestParam(value = "phone", required = false) String phone,
logger.info("login user {}, create user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}", @RequestParam(value = "state", required = false) int state) throws Exception {
loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone, queue); logger.info("login user {}, create user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}, state: {}",
loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone, queue, state);
Map<String, Object> result = usersService.createUser(loginUser, userName, userPassword, email, tenantId, phone, queue); Map<String, Object> result = usersService.createUser(loginUser, userName, userPassword, email, tenantId, phone, queue, state);
return returnDataList(result); return returnDataList(result);
} }
@ -146,7 +147,8 @@ public class UsersController extends BaseController {
@ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"), @ApiImplicitParam(name = "tenantId", value = "TENANT_ID", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"), @ApiImplicitParam(name = "queue", value = "QUEUE", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"), @ApiImplicitParam(name = "email", value = "EMAIL", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100") @ApiImplicitParam(name = "phone", value = "PHONE", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "state", value = "STATE", dataType = "Int", example = "1")
}) })
@PostMapping(value = "/update") @PostMapping(value = "/update")
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@ -158,10 +160,11 @@ public class UsersController extends BaseController {
@RequestParam(value = "queue", required = false, defaultValue = "") String queue, @RequestParam(value = "queue", required = false, defaultValue = "") String queue,
@RequestParam(value = "email") String email, @RequestParam(value = "email") String email,
@RequestParam(value = "tenantId") int tenantId, @RequestParam(value = "tenantId") int tenantId,
@RequestParam(value = "phone", required = false) String phone) throws Exception { @RequestParam(value = "phone", required = false) String phone,
logger.info("login user {}, updateProcessInstance user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}", @RequestParam(value = "state", required = false) int state) throws Exception {
loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone, queue); logger.info("login user {}, updateProcessInstance user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}, state: {}",
Map<String, Object> result = usersService.updateUser(id, userName, userPassword, email, tenantId, phone, queue); loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone, queue, state);
Map<String, Object> result = usersService.updateUser(id, userName, userPassword, email, tenantId, phone, queue, state);
return returnDataList(result); return returnDataList(result);
} }

1
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -175,6 +175,7 @@ public enum Status {
QUERY_WORKER_GROUP_FAIL(10146,"query worker group fail ", "查询worker分组失败"), QUERY_WORKER_GROUP_FAIL(10146,"query worker group fail ", "查询worker分组失败"),
DELETE_WORKER_GROUP_FAIL(10147,"delete worker group fail ", "删除worker分组失败"), DELETE_WORKER_GROUP_FAIL(10147,"delete worker group fail ", "删除worker分组失败"),
COPY_PROCESS_DEFINITION_ERROR(10148,"copy process definition error", "复制工作流错误"), COPY_PROCESS_DEFINITION_ERROR(10148,"copy process definition error", "复制工作流错误"),
USER_DISABLED(10149,"The current user is disabled", "当前用户已停用"),
UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"), UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"),
UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"), UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"),

10
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptor.java

@ -16,9 +16,11 @@
*/ */
package org.apache.dolphinscheduler.api.interceptor; package org.apache.dolphinscheduler.api.interceptor;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.security.Authenticator; import org.apache.dolphinscheduler.api.security.Authenticator;
import org.apache.dolphinscheduler.api.service.SessionService; import org.apache.dolphinscheduler.api.service.SessionService;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.Flag;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.UserMapper; import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.HttpStatus;
@ -85,6 +87,14 @@ public class LoginHandlerInterceptor implements HandlerInterceptor {
return false; return false;
} }
} }
// check user state
if (user.getState() == Flag.NO.ordinal()) {
response.setStatus(HttpStatus.SC_UNAUTHORIZED);
logger.info(Status.USER_DISABLED.getMsg());
return false;
}
request.setAttribute(Constants.SESSION_USER, user); request.setAttribute(Constants.SESSION_USER, user);
return true; return true;
} }

8
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/PasswordAuthenticator.java

@ -21,6 +21,7 @@ import org.apache.dolphinscheduler.api.service.SessionService;
import org.apache.dolphinscheduler.api.service.UsersService; import org.apache.dolphinscheduler.api.service.UsersService;
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.Flag;
import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.Session;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,6 +50,13 @@ public class PasswordAuthenticator implements Authenticator {
return result; return result;
} }
// check user state
if (user.getState() == Flag.NO.ordinal()) {
result.setCode(Status.USER_DISABLED.getCode());
result.setMsg(Status.USER_DISABLED.getMsg());
return result;
}
// create session // create session
String sessionId = sessionService.createSession(user, extra); String sessionId = sessionService.createSession(user, extra);
if (sessionId == null) { if (sessionId == null) {

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

@ -94,7 +94,8 @@ public class UsersService extends BaseService {
String email, String email,
int tenantId, int tenantId,
String phone, String phone,
String queue) throws Exception { String queue,
int state) throws Exception {
Map<String, Object> result = new HashMap<>(5); Map<String, Object> result = new HashMap<>(5);
@ -115,7 +116,7 @@ public class UsersService extends BaseService {
return result; return result;
} }
User user = createUser(userName, userPassword, email, tenantId, phone, queue); User user = createUser(userName, userPassword, email, tenantId, phone, queue, state);
Tenant tenant = tenantMapper.queryById(tenantId); Tenant tenant = tenantMapper.queryById(tenantId);
// resource upload startup // resource upload startup
@ -139,7 +140,8 @@ public class UsersService extends BaseService {
String email, String email,
int tenantId, int tenantId,
String phone, String phone,
String queue) throws Exception { String queue,
int state) throws Exception {
User user = new User(); User user = new User();
Date now = new Date(); Date now = new Date();
@ -148,6 +150,7 @@ public class UsersService extends BaseService {
user.setEmail(email); user.setEmail(email);
user.setTenantId(tenantId); user.setTenantId(tenantId);
user.setPhone(phone); user.setPhone(phone);
user.setState(state);
// create general users, administrator users are currently built-in // create general users, administrator users are currently built-in
user.setUserType(UserType.GENERAL_USER); user.setUserType(UserType.GENERAL_USER);
user.setCreateTime(now); user.setCreateTime(now);
@ -260,7 +263,8 @@ public class UsersService extends BaseService {
String email, String email,
int tenantId, int tenantId,
String phone, String phone,
String queue) throws Exception { String queue,
int state) throws Exception {
Map<String, Object> result = new HashMap<>(5); Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false); result.put(Constants.STATUS, false);
@ -309,7 +313,9 @@ public class UsersService extends BaseService {
} }
user.setPhone(phone); user.setPhone(phone);
} }
user.setQueue(queue); user.setQueue(queue);
user.setState(state);
Date now = new Date(); Date now = new Date();
user.setUpdateTime(now); user.setUpdateTime(now);

1
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/LoginControllerTest.java

@ -56,7 +56,6 @@ public class LoginControllerTest extends AbstractControllerTest{
logger.info(mvcResult.getResponse().getContentAsString()); logger.info(mvcResult.getResponse().getContentAsString());
} }
@Test @Test
public void testSignOut() throws Exception { public void testSignOut() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>(); MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();

6
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LoginHandlerInterceptorTest.java

@ -57,6 +57,7 @@ public class LoginHandlerInterceptorTest {
User mockUser = new User(); User mockUser = new User();
mockUser.setId(1); mockUser.setId(1);
mockUser.setUserType(UserType.GENERAL_USER); mockUser.setUserType(UserType.GENERAL_USER);
mockUser.setState(1);
// test no token // test no token
when(authenticator.getAuthUser(request)).thenReturn(mockUser); when(authenticator.getAuthUser(request)).thenReturn(mockUser);
@ -67,5 +68,10 @@ public class LoginHandlerInterceptorTest {
when(request.getHeader("token")).thenReturn(token); when(request.getHeader("token")).thenReturn(token);
when(userMapper.queryUserByToken(token)).thenReturn(mockUser); when(userMapper.queryUserByToken(token)).thenReturn(mockUser);
Assert.assertTrue(interceptor.preHandle(request, response, null)); Assert.assertTrue(interceptor.preHandle(request, response, null));
// test disable user
mockUser.setState(0);
when(authenticator.getAuthUser(request)).thenReturn(mockUser);
Assert.assertFalse(interceptor.preHandle(request, response, null));
} }
} }

8
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/PasswordAuthenticatorTest.java

@ -67,6 +67,7 @@ public class PasswordAuthenticatorTest {
mockUser.setEmail("test@test.com"); mockUser.setEmail("test@test.com");
mockUser.setUserPassword("test"); mockUser.setUserPassword("test");
mockUser.setId(1); mockUser.setId(1);
mockUser.setState(1);
mockSession = new Session(); mockSession = new Session();
mockSession.setId(UUID.randomUUID().toString()); mockSession.setId(UUID.randomUUID().toString());
@ -82,6 +83,13 @@ public class PasswordAuthenticatorTest {
Result result = authenticator.authenticate("test", "test", "127.0.0.1"); Result result = authenticator.authenticate("test", "test", "127.0.0.1");
Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode());
logger.info(result.toString()); logger.info(result.toString());
mockUser.setState(0);
when(usersService.queryUser("test", "test")).thenReturn(mockUser);
when(sessionService.createSession(mockUser, "127.0.0.1")).thenReturn(mockSession.getId());
Result result1 = authenticator.authenticate("test", "test", "127.0.0.1");
Assert.assertEquals(Status.USER_DISABLED.getCode(), (int) result1.getCode());
logger.info(result1.toString());
} }
@Test @Test

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

@ -98,41 +98,42 @@ public class UsersServiceTest {
String email = "123@qq.com"; String email = "123@qq.com";
int tenantId = Integer.MAX_VALUE; int tenantId = Integer.MAX_VALUE;
String phone= "13456432345"; String phone= "13456432345";
int state = 1;
try { try {
//userName error //userName error
Map<String, Object> result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName); Map<String, Object> result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
userName = "userTest0001"; userName = "userTest0001";
userPassword = "userTest000111111111111111"; userPassword = "userTest000111111111111111";
//password error //password error
result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName); result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
userPassword = "userTest0001"; userPassword = "userTest0001";
email = "1q.com"; email = "1q.com";
//email error //email error
result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName); result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
email = "122222@qq.com"; email = "122222@qq.com";
phone ="2233"; phone ="2233";
//phone error //phone error
result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName); result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
phone = "13456432345"; phone = "13456432345";
//tenantId not exists //tenantId not exists
result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName); result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.TENANT_NOT_EXIST, result.get(Constants.STATUS)); Assert.assertEquals(Status.TENANT_NOT_EXIST, result.get(Constants.STATUS));
//success //success
Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant()); Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant());
result = usersService.createUser(user, userName, userPassword, email, 1, phone, queueName); result = usersService.createUser(user, userName, userPassword, email, 1, phone, queueName, state);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
@ -225,13 +226,13 @@ public class UsersServiceTest {
String userPassword = "userTest0001"; String userPassword = "userTest0001";
try { try {
//user not exist //user not exist
Map<String, Object> result = usersService.updateUser(0,userName,userPassword,"3443@qq.com",1,"13457864543","queue"); Map<String, Object> result = usersService.updateUser(0,userName,userPassword,"3443@qq.com",1,"13457864543","queue", 1);
Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS)); Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
logger.info(result.toString()); logger.info(result.toString());
//success //success
when(userMapper.selectById(1)).thenReturn(getUser()); when(userMapper.selectById(1)).thenReturn(getUser());
result = usersService.updateUser(1,userName,userPassword,"32222s@qq.com",1,"13457864543","queue"); result = usersService.updateUser(1,userName,userPassword,"32222s@qq.com",1,"13457864543","queue", 1);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
} catch (Exception e) { } catch (Exception e) {
@ -482,6 +483,7 @@ public class UsersServiceTest {
user.setUserType(UserType.ADMIN_USER); user.setUserType(UserType.ADMIN_USER);
user.setUserName("userTest0001"); user.setUserName("userTest0001");
user.setUserPassword("userTest0001"); user.setUserPassword("userTest0001");
user.setState(1);
return user; return user;
} }

14
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/User.java

@ -67,6 +67,11 @@ public class User {
*/ */
private int tenantId; private int tenantId;
/**
* user state
*/
private int state;
/** /**
* tenant code * tenant code
*/ */
@ -219,6 +224,14 @@ public class User {
this.queue = queue; this.queue = queue;
} }
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {
@ -254,6 +267,7 @@ public class User {
", phone='" + phone + '\'' + ", phone='" + phone + '\'' +
", userType=" + userType + ", userType=" + userType +
", tenantId=" + tenantId + ", tenantId=" + tenantId +
", state=" + state +
", tenantCode='" + tenantCode + '\'' + ", tenantCode='" + tenantCode + '\'' +
", tenantName='" + tenantName + '\'' + ", tenantName='" + tenantName + '\'' +
", queueName='" + queueName + '\'' + ", queueName='" + queueName + '\'' +

2
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UserMapper.xml

@ -32,7 +32,7 @@
</select> </select>
<select id="queryUserPaging" resultType="org.apache.dolphinscheduler.dao.entity.User"> <select id="queryUserPaging" resultType="org.apache.dolphinscheduler.dao.entity.User">
select u.id,u.user_name,u.user_password,u.user_type,u.email,u.phone,u.tenant_id,u.create_time, select u.id,u.user_name,u.user_password,u.user_type,u.email,u.phone,u.tenant_id,u.create_time,
u.update_time,t.tenant_name, u.update_time,t.tenant_name,u.state,
case when u.queue <![CDATA[ <> ]]> '' then u.queue else q.queue_name end as queue, q.queue_name case when u.queue <![CDATA[ <> ]]> '' then u.queue else q.queue_name end as queue, q.queue_name
from t_ds_user u from t_ds_user u
left join t_ds_tenant t on u.tenant_id=t.id left join t_ds_tenant t on u.tenant_id=t.id

15
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue

@ -93,6 +93,15 @@
</x-input> </x-input>
</template> </template>
</m-list-box-f> </m-list-box-f>
<m-list-box-f>
<template slot="name">{{$t('State')}}</template>
<template slot="content">
<x-radio-group v-model="userState" >
<x-radio :label="'1'">{{$t('Enable')}}</x-radio>
<x-radio :label="'0'">{{$t('Disable')}}</x-radio>
</x-radio-group>
</template>
</m-list-box-f>
</div> </div>
</template> </template>
</m-popup> </m-popup>
@ -118,6 +127,7 @@
queueName: '', queueName: '',
email: '', email: '',
phone: '', phone: '',
userState: '1',
tenantList: [], tenantList: [],
// Source admin user information // Source admin user information
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER' && router.history.current.name !== 'account' isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER' && router.history.current.name !== 'account'
@ -241,7 +251,8 @@
tenantId: this.tenantId, tenantId: this.tenantId,
email: this.email, email: this.email,
queue: queueCode, queue: queueCode,
phone: this.phone phone: this.phone,
state: this.userState
} }
if (this.item) { if (this.item) {
@ -270,6 +281,7 @@
this.userPassword = '' this.userPassword = ''
this.email = this.item.email this.email = this.item.email
this.phone = this.item.phone this.phone = this.item.phone
this.userState = this.item.state + '' || '1'
this.tenantId = this.item.tenantId this.tenantId = this.item.tenantId
this.$nextTick(() => { this.$nextTick(() => {
this.queueName = _.find(this.queueList, ['code', this.item.queue]).id||'' this.queueName = _.find(this.queueList, ['code', this.item.queue]).id||''
@ -282,6 +294,7 @@
this.userPassword = '' this.userPassword = ''
this.email = this.item.email this.email = this.item.email
this.phone = this.item.phone this.phone = this.item.phone
this.userState = this.state + '' || '1'
this.tenantId = this.item.tenantId this.tenantId = this.item.tenantId
if(this.queueList.length>0) { if(this.queueList.length>0) {
this.queueName = _.find(this.queueList, ['code', this.item.queue]).id this.queueName = _.find(this.queueList, ['code', this.item.queue]).id

8
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/users/_source/list.vue

@ -40,7 +40,9 @@
<th> <th>
<span>{{$t('Phone')}}</span> <span>{{$t('Phone')}}</span>
</th> </th>
<th id="state">
<span>{{$t('State')}}</span>
</th>
<th> <th>
<span>{{$t('Create Time')}}</span> <span>{{$t('Create Time')}}</span>
</th> </th>
@ -71,6 +73,10 @@
<td> <td>
<span>{{item.phone || '-'}}</span> <span>{{item.phone || '-'}}</span>
</td> </td>
<td>
<span v-if="item.state == 1">{{$t('Enable')}}</span>
<span v-else>{{$t('Disable')}}</span>
</td>
<td> <td>
<span v-if="item.createTime">{{item.createTime | formatDate}}</span> <span v-if="item.createTime">{{item.createTime | formatDate}}</span>
<span v-else>-</span> <span v-else>-</span>

4
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -590,5 +590,7 @@ export default {
'Cannot select the same node for successful branch flow and failed branch flow': 'Cannot select the same node for successful branch flow and failed branch flow', 'Cannot select the same node for successful branch flow and failed branch flow': 'Cannot select the same node for successful branch flow and failed branch flow',
'Successful branch flow and failed branch flow are required': 'Successful branch flow and failed branch flow are required', 'Successful branch flow and failed branch flow are required': 'Successful branch flow and failed branch flow are required',
'Unauthorized or deleted resources': 'Unauthorized or deleted resources', 'Unauthorized or deleted resources': 'Unauthorized or deleted resources',
'Please delete all non-existent resources': 'Please delete all non-existent resources' 'Please delete all non-existent resources': 'Please delete all non-existent resources',
'Enable': 'Enable',
'Disable': 'Disable'
} }

4
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -590,5 +590,7 @@ export default {
'Cannot select the same node for successful branch flow and failed branch flow': '成功分支流转和失败分支流转不能选择同一个节点', 'Cannot select the same node for successful branch flow and failed branch flow': '成功分支流转和失败分支流转不能选择同一个节点',
'Successful branch flow and failed branch flow are required': '成功分支流转和失败分支流转必填', 'Successful branch flow and failed branch flow are required': '成功分支流转和失败分支流转必填',
'Unauthorized or deleted resources': '未授权或已删除资源', 'Unauthorized or deleted resources': '未授权或已删除资源',
'Please delete all non-existent resources': '请删除所有未授权或已删除资源' 'Please delete all non-existent resources': '请删除所有未授权或已删除资源',
'Enable': '启用',
'Disable': '停用'
} }

2
e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java

@ -42,7 +42,7 @@ public class UserManageLocator {
public static final By SUBMIT = By.xpath("//div[3]/button[2]/span"); public static final By SUBMIT = By.xpath("//div[3]/button[2]/span");
public static final By DELETE_USER_BUTTON = By.xpath("//span[2]/button/i"); public static final By DELETE_USER_BUTTON = By.xpath("//span[2]/button");
public static final By CONFIRM_DELETE_USER_BUTTON = By.xpath("//div[2]/div/button[2]/span"); public static final By CONFIRM_DELETE_USER_BUTTON = By.xpath("//div[2]/div/button[2]/span");
} }

21
sql/upgrade/1.2.2_schema/mysql/dolphinscheduler_ddl.sql

@ -357,3 +357,24 @@ delimiter ;
CALL dc_dolphin_T_t_ds_error_command_D_worker_group_id; CALL dc_dolphin_T_t_ds_error_command_D_worker_group_id;
DROP PROCEDURE dc_dolphin_T_t_ds_error_command_D_worker_group_id; DROP PROCEDURE dc_dolphin_T_t_ds_error_command_D_worker_group_id;
-- ac_dolphin_T_t_ds_user_A_state
drop PROCEDURE if EXISTS ac_dolphin_T_t_ds_user_A_state;
delimiter d//
CREATE PROCEDURE ac_dolphin_T_t_ds_user_A_state()
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS
WHERE TABLE_NAME='t_ds_user'
AND TABLE_SCHEMA=(SELECT DATABASE())
AND COLUMN_NAME ='state')
THEN
ALTER TABLE t_ds_user ADD `state` int(1) DEFAULT 1 COMMENT 'state 0:disable 1:enable';
END IF;
END;
d//
delimiter ;
CALL ac_dolphin_T_t_ds_user_A_state;
DROP PROCEDURE ac_dolphin_T_t_ds_user_A_state;

20
sql/upgrade/1.2.2_schema/postgresql/dolphinscheduler_ddl.sql

@ -364,3 +364,23 @@ select dc_dolphin_T_t_ds_error_command_D_worker_group_id();
DROP FUNCTION dc_dolphin_T_t_ds_error_command_D_worker_group_id(); DROP FUNCTION dc_dolphin_T_t_ds_error_command_D_worker_group_id();
-- ac_dolphin_T_t_ds_user_A_state
delimiter ;
DROP FUNCTION IF EXISTS ac_dolphin_T_t_ds_user_A_state();
delimiter d//
CREATE FUNCTION ac_dolphin_T_t_ds_user_A_state() RETURNS void AS $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS
WHERE TABLE_CATALOG=current_database()
AND TABLE_SCHEMA=current_schema()
AND TABLE_NAME='t_ds_user'
AND COLUMN_NAME ='state')
THEN
ALTER TABLE t_ds_user ADD COLUMN state int DEFAULT 1;
END IF;
END;
$$ LANGUAGE plpgsql;
d//
delimiter ;
select ac_dolphin_T_t_ds_user_A_state();
DROP FUNCTION ac_dolphin_T_t_ds_user_A_state();
Loading…
Cancel
Save