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

caishunfeng pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 12f8138167 Expire session when update user password (#15219)
12f8138167 is described below

commit 12f8138167f8481f66d52775b510457f532b56e4
Author: Wenjun Ruan <[email protected]>
AuthorDate: Sun Nov 26 18:53:44 2023 +0800

    Expire session when update user password (#15219)
---
 .../api/controller/LoginController.java            |  17 +--
 .../api/controller/UsersController.java            |  46 ++++----
 .../api/security/Authenticator.java                |   7 +-
 .../api/security/impl/AbstractAuthenticator.java   |  29 ++++--
 .../api/security/impl/ldap/LdapAuthenticator.java  |   4 +-
 .../security/impl/pwd/PasswordAuthenticator.java   |   2 +-
 .../security/impl/sso/CasdoorAuthenticator.java    |   4 +-
 .../api/service/SessionService.java                |  33 +-----
 .../dolphinscheduler/api/service/UsersService.java |  28 ++---
 .../api/service/impl/SessionServiceImpl.java       | 116 +++++----------------
 .../api/service/impl/UsersServiceImpl.java         | 111 +++++++-------------
 .../api/controller/AbstractControllerTest.java     |  13 ++-
 .../security/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 ++----------------
 .../dolphinscheduler/dao/mapper/SessionMapper.java |  22 ----
 .../dolphinscheduler/dao/repository/BaseDao.java   |  17 +++
 .../dolphinscheduler/dao/repository/IDao.java      |  10 ++
 .../dao/repository/SessionDao.java                 |  17 +--
 .../dao/repository/impl/SessionDaoImpl.java        |  49 +++++++++
 .../dolphinscheduler/dao/mapper/SessionMapper.xml  |  37 -------
 .../dao/mapper/SessionMapperTest.java              |   5 +-
 25 files changed, 305 insertions(+), 481 deletions(-)

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<String, Object> result = usersService.updateUser(loginUser, id, 
userName, userPassword, email, tenantId,
-                phone, queue, state, timeZone);
-        return returnDataList(result);
+    public Result<User> 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<Map<String, String>> authenticate(String username, String password, 
String extra);
+    Result<Map<String, String>> 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<Map<String, String>> authenticate(String userId, String 
password, String extra) {
+    public Result<Map<String, String>> authenticate(@NonNull String userId, 
String password, @NonNull String ip) {
         Result<Map<String, String>> 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<String, String> 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);
+
+    Session createSessionIfAbsent(User user);
 
-    /**
-     * create session
-     *
-     * @param user user
-     * @param ip ip
-     * @return session string
-     */
-    String createSession(User user, String ip);
+    void expireSession(Integer userId);
 
-    /**
-     * sign out
-     * remove ip restrictions
-     *
-     * @param ip   no use
-     * @param loginUser login user
-     */
-    void signOut(String ip, User loginUser);
+    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<String, Object> 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<Session> 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<Session> 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<String, Object> updateUser(User loginUser, int userId,
-                                          String userName,
-                                          String userPassword,
-                                          String email,
-                                          int tenantId,
-                                          String phone,
-                                          String queue,
-                                          int state,
-                                          String timeZone) throws IOException {
-        Map<String, Object> 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<String, Object> 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<String, Object> result = usersService.updateUser(getLoginUser(), 
0, userName, userPassword,
-                "[email protected]", 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,
+                        "[email protected]",
+                        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, "[email protected]", 1,
-                "13457864543", "queue", 1, "Asia/Shanghai");
-        Assertions.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
+        assertDoesNotThrow(() -> usersService.updateUser(getLoginUser(),
+                1,
+                userName,
+                userPassword,
+                "[email protected]",
+                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<Session> {
 
-    /**
-     * query session list by userId
-     * @param userId userId
-     * @return session list
-     */
-    List<Session> 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<ENTITY, MYBATIS_MAPPER extends 
BaseMapper<ENTITY>> implements IDao<ENTITY> {
@@ -55,6 +56,14 @@ public abstract class BaseDao<ENTITY, MYBATIS_MAPPER extends 
BaseMapper<ENTITY>>
         return mybatisMapper.selectBatchIds(ids);
     }
 
+    @Override
+    public List<ENTITY> 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<ENTITY, MYBATIS_MAPPER extends 
BaseMapper<ENTITY>>
         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<Entity> {
      */
     List<Entity> queryByIds(Collection<? extends Serializable> ids);
 
+    /**
+     * Query the entity by condition.
+     */
+    List<Entity> queryByCondition(Entity queryCondition);
+
     /**
      * Insert the entity.
      */
@@ -66,4 +71,9 @@ public interface IDao<Entity> {
      */
     boolean deleteByIds(Collection<? extends Serializable> ids);
 
+    /**
+     * Delete the entities by condition.
+     */
+    boolean deleteByCondition(Entity queryCondition);
+
 }
diff --git 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
 
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java
similarity index 66%
copy from 
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
copy to 
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java
index 2dc4ff0463..fb62b653de 100644
--- 
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/security/impl/pwd/PasswordAuthenticator.java
+++ 
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/repository/SessionDao.java
@@ -15,15 +15,16 @@
  * limitations under the License.
  */
 
-package org.apache.dolphinscheduler.api.security.impl.pwd;
+package org.apache.dolphinscheduler.dao.repository;
 
-import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
-import org.apache.dolphinscheduler.dao.entity.User;
+import org.apache.dolphinscheduler.dao.entity.Session;
 
-public class PasswordAuthenticator extends AbstractAuthenticator {
+import java.util.List;
+
+public interface SessionDao extends IDao<Session> {
+
+    void deleteByUserId(Integer userId);
+
+    List<Session> queryByUserId(Integer userId);
 
-    @Override
-    public User login(String userId, String password, String extra) {
-        return userService.queryUser(userId, password);
-    }
 }
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<Session, SessionMapper> 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<Session> 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 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-  ~ 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.
-  -->
-
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"; >
-<mapper namespace="org.apache.dolphinscheduler.dao.mapper.SessionMapper">
-    <sql id="baseSql">
-        id, user_id, ip, last_login_time
-    </sql>
-    <select id="queryByUserId" 
resultType="org.apache.dolphinscheduler.dao.entity.Session">
-        select
-        <include refid="baseSql"/>
-        from t_ds_session
-        where user_id = #{userId}
-    </select>
-
-    <select id="queryByUserIdAndIp" 
resultType="org.apache.dolphinscheduler.dao.entity.Session">
-        select
-        <include refid="baseSql"/>
-        from t_ds_session
-        where user_id = #{userId} AND ip = #{ip}
-    </select>
-</mapper>
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<Session> sessions = 
sessionMapper.queryByUserId(session.getUserId());
+        List<Session> sessions =
+                sessionMapper.selectList(new 
QueryWrapper<>(Session.builder().userId(session.getUserId()).build()));
         Assertions.assertNotEquals(0, sessions.size());
 
     }

Reply via email to