From 12f8138167f8481f66d52775b510457f532b56e4 Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Sun, 26 Nov 2023 18:53:44 +0800 Subject: [PATCH] Expire session when update user password (#15219) --- .../api/controller/LoginController.java | 17 +-- .../api/controller/UsersController.java | 46 ++++--- .../api/security/Authenticator.java | 7 +- .../security/impl/AbstractAuthenticator.java | 29 +++-- .../security/impl/ldap/LdapAuthenticator.java | 4 +- .../impl/pwd/PasswordAuthenticator.java | 2 +- .../impl/sso/CasdoorAuthenticator.java | 4 +- .../api/service/SessionService.java | 33 +---- .../api/service/UsersService.java | 28 ++--- .../api/service/impl/SessionServiceImpl.java | 116 ++++-------------- .../api/service/impl/UsersServiceImpl.java | 111 ++++++----------- .../controller/AbstractControllerTest.java | 13 +- .../impl/ldap/LdapAuthenticatorTest.java | 9 +- .../impl/pwd/PasswordAuthenticatorTest.java | 9 +- .../impl/sso/CasdoorAuthenticatorTest.java | 6 +- .../api/service/SessionServiceTest.java | 45 ++----- .../api/service/UsersServiceTest.java | 51 +++++--- .../dolphinscheduler/dao/entity/Session.java | 99 ++------------- .../dao/mapper/SessionMapper.java | 22 ---- .../dao/repository/BaseDao.java | 17 +++ .../dolphinscheduler/dao/repository/IDao.java | 10 ++ .../dao/repository/SessionDao.java | 30 +++++ .../dao/repository/impl/SessionDaoImpl.java | 49 ++++++++ .../dao/mapper/SessionMapper.xml | 37 ------ .../dao/mapper/SessionMapperTest.java | 5 +- 25 files changed, 326 insertions(+), 473 deletions(-) create mode 100644 dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java create mode 100644 dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/SessionDaoImpl.java delete mode 100644 dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/SessionMapper.xml diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java index 33e0e519b2..7e4b82db30 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoginController.java @@ -34,6 +34,7 @@ import org.apache.dolphinscheduler.common.constants.Constants; import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.utils.JSONUtils; import org.apache.dolphinscheduler.common.utils.OkHttpUtils; +import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; import org.apache.commons.lang3.StringUtils; @@ -160,20 +161,13 @@ public class LoginController extends BaseController { return Result.success(); } - /** - * sign out - * - * @param loginUser login user - * @param request request - * @return sign out result - */ @Operation(summary = "signOut", description = "SIGNOUT_NOTES") @PostMapping(value = "/signOut") @ApiException(SIGN_OUT_ERROR) public Result signOut(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, HttpServletRequest request) { String ip = getClientIpAddress(request); - sessionService.signOut(ip, loginUser); + sessionService.expireSession(loginUser.getId()); // clear session request.removeAttribute(Constants.SESSION_USER); return success(); @@ -244,13 +238,10 @@ public class LoginController extends BaseController { if (user == null) { user = usersService.createUser(UserType.GENERAL_USER, username, null); } - String sessionId = sessionService.createSession(user, null); - if (sessionId == null) { - log.error("Failed to create session, userName:{}.", user.getUserName()); - } + Session session = sessionService.createSessionIfAbsent(user); response.setStatus(HttpStatus.SC_MOVED_TEMPORARILY); response.sendRedirect(String.format("%s?sessionId=%s&authType=%s", oAuth2ClientProperties.getCallbackUrl(), - sessionId, "oauth2")); + session.getId(), "oauth2")); } catch (Exception ex) { log.error(ex.getMessage(), ex); response.setStatus(HttpStatus.SC_MOVED_TEMPORARILY); 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 c376c5a7fc..a5a4486e6c 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 @@ -76,18 +76,6 @@ public class UsersController extends BaseController { @Autowired private UsersService usersService; - /** - * create user - * - * @param loginUser login user - * @param userName user name - * @param userPassword user password - * @param email email - * @param tenantId tenant id - * @param phone phone - * @param queue queue - * @return create result code - */ @Operation(summary = "createUser", description = "CREATE_USER_NOTES") @Parameters({ @Parameter(name = "userName", description = "USER_NAME", required = true, schema = @Schema(implementation = String.class)), @@ -172,19 +160,27 @@ public class UsersController extends BaseController { @PostMapping(value = "/update") @ResponseStatus(HttpStatus.OK) @ApiException(UPDATE_USER_ERROR) - public Result updateUser(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, - @RequestParam(value = "id") int id, - @RequestParam(value = "userName") String userName, - @RequestParam(value = "userPassword") String userPassword, - @RequestParam(value = "queue", required = false, defaultValue = "") String queue, - @RequestParam(value = "email") String email, - @RequestParam(value = "tenantId") int tenantId, - @RequestParam(value = "phone", required = false) String phone, - @RequestParam(value = "state", required = false) int state, - @RequestParam(value = "timeZone", required = false) String timeZone) throws Exception { - Map result = usersService.updateUser(loginUser, id, userName, userPassword, email, tenantId, - phone, queue, state, timeZone); - return returnDataList(result); + public Result updateUser(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "id") int id, + @RequestParam(value = "userName") String userName, + @RequestParam(value = "userPassword") String userPassword, + @RequestParam(value = "queue", required = false, defaultValue = "") String queue, + @RequestParam(value = "email") String email, + @RequestParam(value = "tenantId") int tenantId, + @RequestParam(value = "phone", required = false) String phone, + @RequestParam(value = "state", required = false) int state, + @RequestParam(value = "timeZone", required = false) String timeZone) throws Exception { + User user = usersService.updateUser(loginUser, + id, + userName, + userPassword, + email, + tenantId, + phone, + queue, + state, + timeZone); + return Result.success(user); } /** diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/Authenticator.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/Authenticator.java index 5c2a556bb7..bdfbf320e5 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/Authenticator.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/Authenticator.java @@ -24,16 +24,19 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; +import lombok.NonNull; + public interface Authenticator { /** * Verifying legality via username and password + * * @param username user name * @param password user password - * @param extra extra info + * @param ip client ip * @return result object */ - Result> authenticate(String username, String password, String extra); + Result> authenticate(@NonNull String username, String password, @NonNull String ip); /** * Get authenticated user diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java index e589911857..43b7e57402 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/AbstractAuthenticator.java @@ -29,15 +29,20 @@ import org.apache.dolphinscheduler.common.enums.Flag; import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.commons.lang3.StringUtils; + import java.util.HashMap; import java.util.Map; import java.util.Objects; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.util.WebUtils; @Slf4j public abstract class AbstractAuthenticator implements Authenticator { @@ -56,15 +61,14 @@ public abstract class AbstractAuthenticator implements Authenticator { * * @param userId user identity field * @param password user login password - * @param extra extra user login field * @return user object in databse */ - public abstract User login(String userId, String password, String extra); + public abstract User login(@NonNull String userId, String password); @Override - public Result> authenticate(String userId, String password, String extra) { + public Result> authenticate(@NonNull String userId, String password, @NonNull String ip) { Result> result = new Result<>(); - User user = login(userId, password, extra); + User user = login(userId, password); if (user == null) { if (Objects.equals(securityConfig.getType(), AuthenticationType.CASDOOR_SSO.name())) { log.error("State or code entered incorrectly."); @@ -87,9 +91,8 @@ public abstract class AbstractAuthenticator implements Authenticator { } // create session - String sessionId = sessionService.createSession(user, extra); - if (sessionId == null) { - log.error("Failed to create session, userName:{}.", user.getUserName()); + Session session = sessionService.createSessionIfAbsent(user); + if (session == null) { result.setCode(Status.LOGIN_SESSION_FAILED.getCode()); result.setMsg(Status.LOGIN_SESSION_FAILED.getMsg()); return result; @@ -98,7 +101,7 @@ public abstract class AbstractAuthenticator implements Authenticator { log.info("Session is created, userName:{}.", user.getUserName()); Map data = new HashMap<>(); - data.put(Constants.SESSION_ID, sessionId); + data.put(Constants.SESSION_ID, session.getId()); data.put(Constants.SECURITY_CONFIG_TYPE, securityConfig.getType()); result.setData(data); @@ -109,9 +112,15 @@ public abstract class AbstractAuthenticator implements Authenticator { @Override public User getAuthUser(HttpServletRequest request) { - Session session = sessionService.getSession(request); + String sessionId = request.getHeader(Constants.SESSION_ID); + if (StringUtils.isBlank(sessionId)) { + Cookie cookie = WebUtils.getCookie(request, Constants.SESSION_ID); + if (cookie != null) { + sessionId = cookie.getValue(); + } + } + Session session = sessionService.getSession(sessionId); if (session == null) { - log.info("session info is null "); return null; } // get user object from session diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java index e849f884a5..64f15eeeb2 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticator.java @@ -20,6 +20,8 @@ package org.apache.dolphinscheduler.api.security.impl.ldap; import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator; import org.apache.dolphinscheduler.dao.entity.User; +import lombok.NonNull; + import org.springframework.beans.factory.annotation.Autowired; public class LdapAuthenticator extends AbstractAuthenticator { @@ -28,7 +30,7 @@ public class LdapAuthenticator extends AbstractAuthenticator { LdapService ldapService; @Override - public User login(String userId, String password, String extra) { + public User login(@NonNull String userId, String password) { User user = null; String ldapEmail = ldapService.ldapLogin(userId, password); if (ldapEmail != null) { diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java index 2dc4ff0463..a7ae0dd9f1 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java @@ -23,7 +23,7 @@ import org.apache.dolphinscheduler.dao.entity.User; public class PasswordAuthenticator extends AbstractAuthenticator { @Override - public User login(String userId, String password, String extra) { + public User login(String userId, String password) { return userService.queryUser(userId, password); } } diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java index 2acbabbd56..4d8cf93ada 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticator.java @@ -27,6 +27,8 @@ import java.security.MessageDigest; import javax.servlet.http.HttpServletRequest; +import lombok.NonNull; + import org.casbin.casdoor.entity.CasdoorUser; import org.casbin.casdoor.service.CasdoorAuthService; import org.springframework.beans.factory.annotation.Autowired; @@ -46,7 +48,7 @@ public class CasdoorAuthenticator extends AbstractSsoAuthenticator { private String adminUserName; @Override - public User login(String state, String code, String extra) { + public User login(@NonNull String state, String code) { ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (servletRequestAttributes == null) { diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java index 37c34f7462..95a4291286 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/SessionService.java @@ -20,36 +20,13 @@ package org.apache.dolphinscheduler.api.service; import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; -import javax.servlet.http.HttpServletRequest; - -/** - * session service - */ public interface SessionService { - /** - * get user session from request - * - * @param request request - * @return session - */ - Session getSession(HttpServletRequest request); + Session getSession(String sessionId); - /** - * create session - * - * @param user user - * @param ip ip - * @return session string - */ - String createSession(User user, String ip); + Session createSessionIfAbsent(User user); - /** - * sign out - * remove ip restrictions - * - * @param ip no use - * @param loginUser login user - */ - void signOut(String ip, User loginUser); + void expireSession(Integer userId); + + boolean isSessionExpire(Session session); } 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 9abe60c72c..e0f984eb13 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 @@ -114,24 +114,16 @@ public interface UsersService { */ Result queryUserList(User loginUser, String searchVal, Integer pageNo, Integer pageSize); - /** - * updateProcessInstance user - * - * - * @param loginUser - * @param userId user id - * @param userName user name - * @param userPassword user password - * @param email email - * @param tenantId tennat id - * @param phone phone - * @param queue queue - * @return update result code - * @throws Exception exception - */ - Map updateUser(User loginUser, int userId, String userName, String userPassword, String email, - int tenantId, String phone, String queue, int state, - String timeZone) throws IOException; + User updateUser(User loginUser, + Integer userId, + String userName, + String userPassword, + String email, + Integer tenantId, + String phone, + String queue, + int state, + String timeZone) throws IOException; /** * delete user diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SessionServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SessionServiceImpl.java index baf5088108..79816c58d9 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SessionServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/SessionServiceImpl.java @@ -17,12 +17,11 @@ package org.apache.dolphinscheduler.api.service.impl; -import org.apache.dolphinscheduler.api.controller.BaseController; import org.apache.dolphinscheduler.api.service.SessionService; import org.apache.dolphinscheduler.common.constants.Constants; import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; -import org.apache.dolphinscheduler.dao.mapper.SessionMapper; +import org.apache.dolphinscheduler.dao.repository.SessionDao; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -31,15 +30,11 @@ import java.util.Date; import java.util.List; import java.util.UUID; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; - import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.util.WebUtils; /** * session service implement @@ -49,114 +44,57 @@ import org.springframework.web.util.WebUtils; public class SessionServiceImpl extends BaseServiceImpl implements SessionService { @Autowired - private SessionMapper sessionMapper; + private SessionDao sessionDao; - /** - * get user session from request - * - * @param request request - * @return session - */ @Override - public Session getSession(HttpServletRequest request) { - String sessionId = request.getHeader(Constants.SESSION_ID); - - if (StringUtils.isBlank(sessionId)) { - Cookie cookie = WebUtils.getCookie(request, Constants.SESSION_ID); - - if (cookie != null) { - sessionId = cookie.getValue(); - } - } - + public Session getSession(String sessionId) { if (StringUtils.isBlank(sessionId)) { return null; } - - String ip = BaseController.getClientIpAddress(request); - log.debug("Get session: {}, ip: {}.", sessionId, ip); - - return sessionMapper.selectById(sessionId); + return sessionDao.queryById(sessionId); } - /** - * create session - * - * @param user user - * @param ip ip - * @return session string - */ @Override @Transactional - public String createSession(User user, String ip) { - Session session = null; - - // logined - List sessionList = sessionMapper.queryByUserId(user.getId()); - - Date now = new Date(); - - /** - * if you have logged in and are still valid, return directly - */ + public Session createSessionIfAbsent(User user) { + Session session; + List sessionList = sessionDao.queryByUserId(user.getId()); + // todo: this can be remove after the old session data is cleared if (CollectionUtils.isNotEmpty(sessionList)) { // is session list greater 1 , delete other ,get one if (sessionList.size() > 1) { for (int i = 1; i < sessionList.size(); i++) { - sessionMapper.deleteById(sessionList.get(i).getId()); + sessionDao.deleteById(sessionList.get(i).getId()); } } session = sessionList.get(0); - if (now.getTime() - session.getLastLoginTime().getTime() <= Constants.SESSION_TIME_OUT * 1000) { - /** - * updateProcessInstance the latest login time - */ - session.setLastLoginTime(now); - sessionMapper.updateById(session); - - return session.getId(); - + if (isSessionExpire(session)) { + session.setLastLoginTime(new Date()); + sessionDao.updateById(session); + return session; } else { - /** - * session expired, then delete this session first - */ - sessionMapper.deleteById(session.getId()); + sessionDao.deleteById(session.getId()); } } // assign new session - session = new Session(); - - session.setId(UUID.randomUUID().toString()); - session.setIp(ip); - session.setUserId(user.getId()); - session.setLastLoginTime(now); - - sessionMapper.insert(session); - - return session.getId(); + Session newSession = Session.builder() + .id(UUID.randomUUID().toString()) + .userId(user.getId()) + .lastLoginTime(new Date()) + .build(); + sessionDao.insert(newSession); + return newSession; } - /** - * sign out - * remove ip restrictions - * - * @param ip no use - * @param loginUser login user - */ @Override - public void signOut(String ip, User loginUser) { - try { - /** - * query session by user id and ip - */ - Session session = sessionMapper.queryByUserIdAndIp(loginUser.getId(), ip); + public void expireSession(Integer userId) { + sessionDao.deleteByUserId(userId); + } - // delete session - sessionMapper.deleteById(session.getId()); - } catch (Exception e) { - log.warn("userId : {} , ip : {} , find more one session", loginUser.getId(), ip, e); - } + @Override + public boolean isSessionExpire(Session session) { + return System.currentTimeMillis() - session.getLastLoginTime().getTime() <= Constants.SESSION_TIME_OUT * 1000; } } 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 f75a8ab8db..f268d791b7 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 @@ -23,6 +23,7 @@ import org.apache.dolphinscheduler.api.dto.resources.ResourceComponent; import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.exceptions.ServiceException; import org.apache.dolphinscheduler.api.service.MetricsCleanUpService; +import org.apache.dolphinscheduler.api.service.SessionService; import org.apache.dolphinscheduler.api.service.UsersService; import org.apache.dolphinscheduler.api.utils.CheckUtils; import org.apache.dolphinscheduler.api.utils.PageInfo; @@ -132,6 +133,9 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService { @Autowired private MetricsCleanUpService metricsCleanUpService; + @Autowired + private SessionService sessionService; + /** * create user, only system admin have permission * @@ -359,102 +363,68 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService { return result; } - /** - * updateProcessInstance user - * - * @param userId user id - * @param userName user name - * @param userPassword user password - * @param email email - * @param tenantId tenant id - * @param phone phone - * @param queue queue - * @param state state - * @param timeZone timeZone - * @return update result code - * @throws Exception exception - */ @Override - public Map updateUser(User loginUser, int userId, - String userName, - String userPassword, - String email, - int tenantId, - String phone, - String queue, - int state, - String timeZone) throws IOException { - Map result = new HashMap<>(); - result.put(Constants.STATUS, false); - + @Transactional + public User updateUser(User loginUser, + Integer userId, + String userName, + String userPassword, + String email, + Integer tenantId, + String phone, + String queue, + int state, + String timeZone) { if (resourcePermissionCheckService.functionDisabled()) { - putMsg(result, Status.FUNCTION_DISABLED); - return result; + throw new ServiceException(Status.FUNCTION_DISABLED); } - if (check(result, !canOperator(loginUser, userId), Status.USER_NO_OPERATION_PERM)) { - log.warn("User does not have permission for this feature, userId:{}, userName:{}.", loginUser.getId(), - loginUser.getUserName()); - return result; + if (!canOperator(loginUser, userId)) { + throw new ServiceException(Status.USER_NO_OPERATION_PERM); } User user = userMapper.selectById(userId); if (user == null) { - log.error("User does not exist, userId:{}.", userId); - putMsg(result, Status.USER_NOT_EXIST, userId); - return result; + throw new ServiceException(Status.USER_NOT_EXIST, userId); } if (StringUtils.isNotEmpty(userName)) { if (!CheckUtils.checkUserName(userName)) { - log.warn("Parameter userName check failed."); - putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName); - return result; + throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName); } + // todo: use the db unique index User tempUser = userMapper.queryByUserNameAccurately(userName); - if (tempUser != null && tempUser.getId() != userId) { - log.warn("User name already exists, userName:{}.", tempUser.getUserName()); - putMsg(result, Status.USER_NAME_EXIST); - return result; + if (tempUser != null && !userId.equals(tempUser.getId())) { + throw new ServiceException(Status.USER_NAME_EXIST); } user.setUserName(userName); } if (StringUtils.isNotEmpty(userPassword)) { if (!CheckUtils.checkPasswordLength(userPassword)) { - log.warn("Parameter userPassword check failed."); - putMsg(result, Status.USER_PASSWORD_LENGTH_ERROR); - return result; + throw new ServiceException(Status.USER_PASSWORD_LENGTH_ERROR); } user.setUserPassword(EncryptionUtils.getMd5(userPassword)); + sessionService.expireSession(user.getId()); } if (StringUtils.isNotEmpty(email)) { if (!CheckUtils.checkEmail(email)) { - log.warn("Parameter email check failed."); - putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, email); - return result; + throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, email); } user.setEmail(email); } if (StringUtils.isNotEmpty(phone) && !CheckUtils.checkPhone(phone)) { - log.warn("Parameter phone check failed."); - putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, phone); - return result; + throw new ServiceException(Status.REQUEST_PARAMS_NOT_VALID_ERROR, phone); } if (state == 0 && user.getState() != state && Objects.equals(loginUser.getId(), user.getId())) { - log.warn("Not allow to disable your own account, userId:{}, userName:{}.", user.getId(), - user.getUserName()); - putMsg(result, Status.NOT_ALLOW_TO_DISABLE_OWN_ACCOUNT); - return result; + throw new ServiceException(Status.NOT_ALLOW_TO_DISABLE_OWN_ACCOUNT); } if (StringUtils.isNotEmpty(timeZone)) { if (!CheckUtils.checkTimeZone(timeZone)) { - log.warn("Parameter time zone is illegal."); - putMsg(result, Status.TIME_ZONE_ILLEGAL, timeZone); - return result; + throw new ServiceException(Status.TIME_ZONE_ILLEGAL, timeZone); } user.setTimeZone(timeZone); } @@ -462,20 +432,13 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService { user.setPhone(phone); user.setQueue(queue); user.setState(state); - Date now = new Date(); - user.setUpdateTime(now); + user.setUpdateTime(new Date()); user.setTenantId(tenantId); // updateProcessInstance user - int update = userMapper.updateById(user); - if (update > 0) { - log.info("User is updated and id is :{}.", userId); - putMsg(result, Status.SUCCESS); - } else { - log.error("User update error, userId:{}.", userId); - putMsg(result, Status.UPDATE_USER_ERROR); + if (userMapper.updateById(user) <= 0) { + throw new ServiceException(Status.UPDATE_USER_ERROR); } - - return result; + return user; } /** @@ -521,6 +484,7 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService { userMapper.queryTenantCodeByUserId(id); accessTokenMapper.deleteAccessTokenByUserId(id); + sessionService.expireSession(id); if (userMapper.deleteById(id) > 0) { metricsCleanUpService.cleanUpApiResponseTimeMetricsByUserId(id); @@ -1459,10 +1423,13 @@ public class UsersServiceImpl extends BaseServiceImpl implements UsersService { */ @Override @Transactional - public User createUserIfNotExists(String userName, String userPassword, String email, String phone, + public User createUserIfNotExists(String userName, + String userPassword, + String email, + String phone, String tenantCode, String queue, - int state) throws IOException { + int state) { User user = userMapper.queryByUserNameAccurately(userName); if (Objects.isNull(user)) { Tenant tenant = tenantMapper.queryByTenantCode(tenantCode); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java index cb06f1d7a7..6fbb890be7 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/AbstractControllerTest.java @@ -25,9 +25,9 @@ import org.apache.dolphinscheduler.api.service.UsersService; import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.common.constants.Constants; import org.apache.dolphinscheduler.dao.DaoConfiguration; +import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; -import org.apache.commons.lang3.StringUtils; import org.apache.curator.test.TestingServer; import java.text.MessageFormat; @@ -77,17 +77,20 @@ public abstract class AbstractControllerTest { @AfterEach public void after() throws Exception { - sessionService.signOut("127.0.0.1", user); + if (user != null) { + sessionService.expireSession(user.getId()); + } } private void createSession(User loginUser) { user = loginUser; - String session = sessionService.createSession(loginUser, "127.0.0.1"); - sessionId = session; + Session session = sessionService.createSessionIfAbsent(loginUser); + Assertions.assertNotNull(session); - Assertions.assertFalse(StringUtils.isEmpty(session)); + sessionId = session.getId(); + Assertions.assertNotNull(sessionId); } public Map success() { diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java index 5d38880394..26f086a907 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/ldap/LdapAuthenticatorTest.java @@ -17,6 +17,7 @@ package org.apache.dolphinscheduler.api.security.impl.ldap; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import org.apache.dolphinscheduler.api.controller.AbstractControllerTest; @@ -109,7 +110,7 @@ public class LdapAuthenticatorTest extends AbstractControllerTest { @Test public void testAuthenticate() { when(ldapService.ldapLogin(ldapUid, ldapUserPwd)).thenReturn(ldapEmail); - when(sessionService.createSession(Mockito.any(User.class), Mockito.eq(ip))).thenReturn(mockSession.getId()); + when(sessionService.createSessionIfAbsent(Mockito.any(User.class))).thenReturn(mockSession); // test username pwd correct and user not exist, config user not exist action deny, so login denied when(ldapService.getLdapUserNotExistAction()).thenReturn(LdapUserNotExistActionType.DENY); @@ -125,7 +126,7 @@ public class LdapAuthenticatorTest extends AbstractControllerTest { logger.info(result.toString()); // test username pwd correct and user not exist, config action create but can't create session, so login failed - when(sessionService.createSession(Mockito.any(User.class), Mockito.eq(ip))).thenReturn(null); + when(sessionService.createSessionIfAbsent(Mockito.any(User.class))).thenReturn(null); result = ldapAuthenticator.authenticate(ldapUid, ldapUserPwd, ip); Assertions.assertEquals(Status.LOGIN_SESSION_FAILED.getCode(), (int) result.getCode()); @@ -139,12 +140,12 @@ public class LdapAuthenticatorTest extends AbstractControllerTest { public void testGetAuthUser() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); when(usersService.queryUser(mockUser.getId())).thenReturn(mockUser); - when(sessionService.getSession(request)).thenReturn(mockSession); + when(sessionService.getSession(any())).thenReturn(mockSession); User user = ldapAuthenticator.getAuthUser(request); Assertions.assertNotNull(user); - when(sessionService.getSession(request)).thenReturn(null); + when(sessionService.getSession(any())).thenReturn(null); user = ldapAuthenticator.getAuthUser(request); Assertions.assertNull(user); } diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticatorTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticatorTest.java index eb65560b91..d008229848 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticatorTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticatorTest.java @@ -17,6 +17,7 @@ package org.apache.dolphinscheduler.api.security.impl.pwd; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import org.apache.dolphinscheduler.api.controller.AbstractControllerTest; @@ -81,21 +82,21 @@ public class PasswordAuthenticatorTest extends AbstractControllerTest { @Test public void testLogin() { when(usersService.queryUser("test", "test")).thenReturn(mockUser); - User login = authenticator.login("test", "test", "127.0.0.1"); + User login = authenticator.login("test", "test"); Assertions.assertNotNull(login); } @Test public void testAuthenticate() { when(usersService.queryUser("test", "test")).thenReturn(mockUser); - when(sessionService.createSession(mockUser, "127.0.0.1")).thenReturn(mockSession.getId()); + when(sessionService.createSessionIfAbsent(mockUser)).thenReturn(mockSession); Result result = authenticator.authenticate("test", "test", "127.0.0.1"); Assertions.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode()); 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()); + when(sessionService.createSessionIfAbsent(mockUser)).thenReturn(mockSession); Result result1 = authenticator.authenticate("test", "test", "127.0.0.1"); Assertions.assertEquals(Status.USER_DISABLED.getCode(), (int) result1.getCode()); logger.info(result1.toString()); @@ -105,7 +106,7 @@ public class PasswordAuthenticatorTest extends AbstractControllerTest { public void testGetAuthUser() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); when(usersService.queryUser(mockUser.getId())).thenReturn(mockUser); - when(sessionService.getSession(request)).thenReturn(mockSession); + when(sessionService.getSession(any())).thenReturn(mockSession); User user = authenticator.getAuthUser(request); Assertions.assertNotNull(user); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticatorTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticatorTest.java index c1ef0b46cd..25a1e7a306 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticatorTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/security/impl/sso/CasdoorAuthenticatorTest.java @@ -112,7 +112,7 @@ public class CasdoorAuthenticatorTest extends AbstractControllerTest { @Test public void testAuthenticate() { when(usersService.getUserByUserName(casdoorUsername)).thenReturn(mockUser); - when(sessionService.createSession(mockUser, ip)).thenReturn(mockSession.getId()); + when(sessionService.createSessionIfAbsent(mockUser)).thenReturn(mockSession); when(casdoorAuthService.getOAuthToken(code, state)).thenReturn(token); when(casdoorAuthService.parseJwtToken(token)).thenReturn(mockCasdoorUser); @@ -131,13 +131,13 @@ public class CasdoorAuthenticatorTest extends AbstractControllerTest { Objects.requireNonNull(request.getSession()).setAttribute(Constants.SSO_LOGIN_USER_STATE, state); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); - when(sessionService.createSession(mockUser, ip)).thenReturn(null); + when(sessionService.createSessionIfAbsent(mockUser)).thenReturn(null); result = casdoorAuthenticator.authenticate(state, code, ip); Assertions.assertEquals(Status.LOGIN_SESSION_FAILED.getCode(), (int) result.getCode()); Objects.requireNonNull(request.getSession()).setAttribute(Constants.SSO_LOGIN_USER_STATE, state); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); - when(sessionService.createSession(mockUser, ip)).thenReturn(mockSession.getId()); + when(sessionService.createSessionIfAbsent(mockUser)).thenReturn(mockSession); when(usersService.getUserByUserName(casdoorUsername)).thenReturn(null); when(usersService.createUser(userType, casdoorUsername, casdoorEmail)).thenReturn(null); result = casdoorAuthenticator.authenticate(state, code, ip); diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SessionServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SessionServiceTest.java index c7db202714..cb82554f2b 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SessionServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/SessionServiceTest.java @@ -18,14 +18,11 @@ package org.apache.dolphinscheduler.api.service; import org.apache.dolphinscheduler.api.service.impl.SessionServiceImpl; -import org.apache.dolphinscheduler.common.constants.Constants; import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.utils.DateUtils; import org.apache.dolphinscheduler.dao.entity.Session; import org.apache.dolphinscheduler.dao.entity.User; -import org.apache.dolphinscheduler.dao.mapper.SessionMapper; - -import org.apache.commons.lang3.StringUtils; +import org.apache.dolphinscheduler.dao.repository.SessionDao; import java.util.ArrayList; import java.util.Calendar; @@ -43,8 +40,6 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.mock.web.MockCookie; -import org.springframework.mock.web.MockHttpServletRequest; /** * session service test @@ -58,7 +53,7 @@ public class SessionServiceTest { private SessionServiceImpl sessionService; @Mock - private SessionMapper sessionMapper; + private SessionDao sessionDao; private String sessionId = "aaaaaaaaaaaaaaaaaa"; @@ -70,32 +65,14 @@ public class SessionServiceTest { public void after() { } - /** - * create session - */ @Test public void testGetSession() { - Mockito.when(sessionMapper.selectById(sessionId)).thenReturn(getSession()); - // get sessionId from header - MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest(); - mockHttpServletRequest.addHeader(Constants.SESSION_ID, sessionId); - mockHttpServletRequest.addHeader("HTTP_X_FORWARDED_FOR", "127.0.0.1"); + Mockito.when(sessionDao.queryById(sessionId)).thenReturn(getSession()); // query - Session session = sessionService.getSession(mockHttpServletRequest); + Session session = sessionService.getSession(sessionId); Assertions.assertNotNull(session); - logger.info("session ip {}", session.getIp()); - // get sessionId from cookie - mockHttpServletRequest = new MockHttpServletRequest(); - mockHttpServletRequest.addHeader("HTTP_X_FORWARDED_FOR", "127.0.0.1"); - MockCookie mockCookie = new MockCookie(Constants.SESSION_ID, sessionId); - mockHttpServletRequest.setCookies(mockCookie); - // query - session = sessionService.getSession(mockHttpServletRequest); - Assertions.assertNotNull(session); - logger.info("session ip {}", session.getIp()); - Assertions.assertEquals(session.getIp(), "127.0.0.1"); } /** @@ -107,10 +84,10 @@ public class SessionServiceTest { User user = new User(); user.setUserType(UserType.GENERAL_USER); user.setId(1); - Mockito.when(sessionMapper.queryByUserId(1)).thenReturn(getSessions()); - String sessionId = sessionService.createSession(user, ip); - logger.info("createSessionId is " + sessionId); - Assertions.assertTrue(!StringUtils.isEmpty(sessionId)); + Mockito.when(sessionDao.queryByUserId(1)).thenReturn(getSessions()); + Session session = sessionService.createSessionIfAbsent(user); + Assertions.assertNotNull(session); + Assertions.assertNotNull(session.getId()); } /** @@ -118,15 +95,15 @@ public class SessionServiceTest { * remove ip restrictions */ @Test - public void testSignOut() { + public void testExpireSession() { int userId = 88888888; String ip = "127.0.0.1"; User user = new User(); user.setId(userId); - Mockito.when(sessionMapper.queryByUserIdAndIp(userId, ip)).thenReturn(getSession()); + Mockito.doNothing().when(sessionDao).deleteByUserId(userId); - sessionService.signOut(ip, user); + sessionService.expireSession(userId); } 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 6e15b76e88..557adcbab6 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 @@ -17,6 +17,8 @@ package org.apache.dolphinscheduler.api.service; +import static org.apache.dolphinscheduler.api.AssertionsHelper.assertDoesNotThrow; +import static org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowsServiceException; import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.USER_MANAGER; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -54,7 +56,6 @@ import org.apache.dolphinscheduler.spi.enums.ResourceType; import org.apache.commons.collections4.CollectionUtils; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -131,6 +132,9 @@ public class UsersServiceTest { @Mock private ResourcePermissionCheckService resourcePermissionCheckService; + @Mock + private SessionService sessionService; + private String queueName = "UsersServiceTestQueue"; private static final Logger serviceLogger = LoggerFactory.getLogger(BaseServiceImpl.class); @@ -301,20 +305,36 @@ public class UsersServiceTest { } @Test - public void testUpdateUser() throws IOException { + public void testUpdateUser() { String userName = "userTest0001"; String userPassword = "userTest0001"; // user not exist - Map result = usersService.updateUser(getLoginUser(), 0, userName, userPassword, - "3443@qq.com", 1, "13457864543", "queue", 1, "Asia/Shanghai"); - Assertions.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS)); + assertThrowsServiceException( + Status.USER_NOT_EXIST, + () -> usersService.updateUser(getLoginUser(), + 0, + userName, + userPassword, + "3443@qq.com", + 1, + "13457864543", + "queue", + 1, + "Asia/Shanghai")); // success - when(userMapper.selectById(1)).thenReturn(getUser()); + when(userMapper.selectById(any())).thenReturn(getUser()); when(userMapper.updateById(any())).thenReturn(1); - result = usersService.updateUser(getLoginUser(), 1, userName, userPassword, "32222s@qq.com", 1, - "13457864543", "queue", 1, "Asia/Shanghai"); - Assertions.assertEquals(Status.SUCCESS, result.get(Constants.STATUS)); + assertDoesNotThrow(() -> usersService.updateUser(getLoginUser(), + 1, + userName, + userPassword, + "32222s@qq.com", + 1, + "13457864543", + "queue", + 1, + "Asia/Shanghai")); } @Test @@ -784,7 +804,7 @@ public class UsersServiceTest { } @Test - public void testCreateUserIfNotExists() throws IOException { + public void testCreateUserIfNotExists() { User user; String userName = "userTest0001"; String userPassword = "userTest"; @@ -794,11 +814,12 @@ public class UsersServiceTest { int stat = 1; // User exists - Mockito.when(userMapper.existUser(userName)).thenReturn(true); - Mockito.when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); - Mockito.when(userMapper.queryDetailsById(getUser().getId())).thenReturn(getUser()); - Mockito.when(userMapper.queryByUserNameAccurately(userName)).thenReturn(getUser()); - Mockito.when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getTenant()); + when(userMapper.existUser(userName)).thenReturn(true); + when(userMapper.selectById(getUser().getId())).thenReturn(getUser()); + when(userMapper.queryDetailsById(getUser().getId())).thenReturn(getUser()); + when(userMapper.queryByUserNameAccurately(userName)).thenReturn(getUser()); + when(userMapper.updateById(any())).thenReturn(1); + when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getTenant()); user = usersService.createUserIfNotExists(userName, userPassword, email, phone, tenantCode, queueName, stat); Assertions.assertEquals(getUser(), user); diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Session.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Session.java index 7929b3de6a..848d32da68 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Session.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/Session.java @@ -18,108 +18,31 @@ package org.apache.dolphinscheduler.dao.entity; import java.util.Date; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -/** - * session - */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor @TableName("t_ds_session") public class Session { - /** - * id - */ @TableId(value = "id", type = IdType.INPUT) private String id; - /** - * user id - */ private int userId; - /** - * last login time - */ private Date lastLoginTime; - /** - * user login ip - */ + // We will not bind session with ip + @Deprecated private String ip; - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public int getUserId() { - return userId; - } - - public void setUserId(int userId) { - this.userId = userId; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public Date getLastLoginTime() { - return lastLoginTime; - } - - public void setLastLoginTime(Date lastLoginTime) { - this.lastLoginTime = lastLoginTime; - } - - @Override - public String toString() { - return "Session{" + - "id=" + id + - ", userId=" + userId + - ", ip='" + ip + '\'' + - ", lastLoginTime=" + lastLoginTime + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Session session = (Session) o; - - if (userId != session.userId) { - return false; - } - if (!id.equals(session.id)) { - return false; - } - if (!lastLoginTime.equals(session.lastLoginTime)) { - return false; - } - return ip.equals(session.ip); - } - - @Override - public int hashCode() { - int result = id.hashCode(); - result = 31 * result + userId; - result = 31 * result + lastLoginTime.hashCode(); - result = 31 * result + ip.hashCode(); - return result; - } } diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/SessionMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/SessionMapper.java index 8f6a7597ee..5463c96bb3 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/SessionMapper.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/SessionMapper.java @@ -18,30 +18,8 @@ package org.apache.dolphinscheduler.dao.mapper; import org.apache.dolphinscheduler.dao.entity.Session; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - import com.baomidou.mybatisplus.core.mapper.BaseMapper; -/** - * session mapper interface - */ public interface SessionMapper extends BaseMapper { - /** - * query session list by userId - * @param userId userId - * @return session list - */ - List queryByUserId(@Param("userId") int userId); - - /** - * query session by userId and Ip - * @param userId userId - * @param ip ip - * @return session - */ - Session queryByUserIdAndIp(@Param("userId") int userId, @Param("ip") String ip); - } diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/BaseDao.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/BaseDao.java index 05bf7f59fd..2937957dbd 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/BaseDao.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/BaseDao.java @@ -27,6 +27,7 @@ import java.util.Optional; import lombok.NonNull; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public abstract class BaseDao> implements IDao { @@ -55,6 +56,14 @@ public abstract class BaseDao> return mybatisMapper.selectBatchIds(ids); } + @Override + public List queryByCondition(ENTITY queryCondition) { + if (queryCondition == null) { + throw new IllegalArgumentException("queryCondition can not be null"); + } + return mybatisMapper.selectList(new QueryWrapper<>(queryCondition)); + } + @Override public int insert(@NonNull ENTITY model) { return mybatisMapper.insert(model); @@ -88,4 +97,12 @@ public abstract class BaseDao> return mybatisMapper.deleteBatchIds(ids) > 0; } + @Override + public boolean deleteByCondition(ENTITY queryCondition) { + if (queryCondition == null) { + throw new IllegalArgumentException("queryCondition can not be null"); + } + return mybatisMapper.delete(new QueryWrapper<>(queryCondition)) > 0; + } + } diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/IDao.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/IDao.java index 9b2e0b7e60..c566d9b904 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/IDao.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/IDao.java @@ -41,6 +41,11 @@ public interface IDao { */ List queryByIds(Collection ids); + /** + * Query the entity by condition. + */ + List queryByCondition(Entity queryCondition); + /** * Insert the entity. */ @@ -66,4 +71,9 @@ public interface IDao { */ boolean deleteByIds(Collection ids); + /** + * Delete the entities by condition. + */ + boolean deleteByCondition(Entity queryCondition); + } diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java new file mode 100644 index 0000000000..fb62b653de --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.dao.repository; + +import org.apache.dolphinscheduler.dao.entity.Session; + +import java.util.List; + +public interface SessionDao extends IDao { + + void deleteByUserId(Integer userId); + + List queryByUserId(Integer userId); + +} diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/SessionDaoImpl.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/SessionDaoImpl.java new file mode 100644 index 0000000000..634931a327 --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/impl/SessionDaoImpl.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.dao.repository.impl; + +import org.apache.dolphinscheduler.dao.entity.Session; +import org.apache.dolphinscheduler.dao.mapper.SessionMapper; +import org.apache.dolphinscheduler.dao.repository.BaseDao; +import org.apache.dolphinscheduler.dao.repository.SessionDao; + +import java.util.List; + +import lombok.NonNull; + +import org.springframework.stereotype.Repository; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +@Repository +public class SessionDaoImpl extends BaseDao implements SessionDao { + + public SessionDaoImpl(@NonNull SessionMapper sessionMapper) { + super(sessionMapper); + } + + public void deleteByUserId(Integer userId) { + mybatisMapper.delete(new QueryWrapper<>(Session.builder().userId(userId).build())); + } + + @Override + public List queryByUserId(Integer userId) { + return mybatisMapper.selectList(new QueryWrapper<>(Session.builder().userId(userId).build())); + } + +} diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/SessionMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/SessionMapper.xml deleted file mode 100644 index 0aa91b7a12..0000000000 --- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/SessionMapper.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - id, user_id, ip, last_login_time - - - - - diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/SessionMapperTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/SessionMapperTest.java index 00d6c9acff..6aa253fb89 100644 --- a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/SessionMapperTest.java +++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/SessionMapperTest.java @@ -27,6 +27,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + public class SessionMapperTest extends BaseDaoTest { @Autowired @@ -87,7 +89,8 @@ public class SessionMapperTest extends BaseDaoTest { @Test public void testQueryByUserId() { Session session = insertOne(); - List sessions = sessionMapper.queryByUserId(session.getUserId()); + List sessions = + sessionMapper.selectList(new QueryWrapper<>(Session.builder().userId(session.getUserId()).build())); Assertions.assertNotEquals(0, sessions.size()); }