5 changed files with 229 additions and 106 deletions
-
20src/main/java/a8k/app/config/WebConfig.java
-
1src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingControler.java
-
27src/main/java/a8k/app/interceptor/RefreshAccessInterceptor.java
-
282src/main/java/a8k/app/service/data/AppUserMgrService.java
-
5src/main/java/a8k/app/service/setting/AppSettingsMgrService.java
@ -0,0 +1,20 @@ |
|||||
|
package a8k.app.config; |
||||
|
|
||||
|
import a8k.app.interceptor.RefreshAccessInterceptor; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
|
||||
|
@Configuration |
||||
|
public class WebConfig implements WebMvcConfigurer { |
||||
|
private final RefreshAccessInterceptor refreshInterceptor; |
||||
|
|
||||
|
public WebConfig(RefreshAccessInterceptor refreshInterceptor) { |
||||
|
this.refreshInterceptor = refreshInterceptor; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void addInterceptors(InterceptorRegistry registry) { |
||||
|
registry.addInterceptor(refreshInterceptor).addPathPatterns("/api/**"); |
||||
|
} |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
package a8k.app.interceptor; |
||||
|
|
||||
|
import a8k.app.service.data.AppUserMgrService; |
||||
|
import jakarta.servlet.http.HttpServletRequest; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import org.jetbrains.annotations.NotNull; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.servlet.HandlerInterceptor; |
||||
|
|
||||
|
/** |
||||
|
* Interceptor that refreshes the last-access timestamp on each HTTP request. |
||||
|
*/ |
||||
|
@Component |
||||
|
public class RefreshAccessInterceptor implements HandlerInterceptor { |
||||
|
|
||||
|
private final AppUserMgrService userMgr; |
||||
|
|
||||
|
public RefreshAccessInterceptor(AppUserMgrService userMgr) { |
||||
|
this.userMgr = userMgr; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) { |
||||
|
userMgr.recordAccess(); |
||||
|
return true; |
||||
|
} |
||||
|
} |
@ -1,123 +1,193 @@ |
|||||
package a8k.app.service.data; |
package a8k.app.service.data; |
||||
|
|
||||
import a8k.app.dao.AppUsrDao; |
import a8k.app.dao.AppUsrDao; |
||||
|
import a8k.app.dao.DeviceSettingDao; |
||||
import a8k.app.dao.type.db.AppUser; |
import a8k.app.dao.type.db.AppUser; |
||||
|
import a8k.app.dao.type.db.DeviceSetting; |
||||
import a8k.app.hardware.type.A8kEcode; |
import a8k.app.hardware.type.A8kEcode; |
||||
import a8k.app.type.exception.AppException; |
import a8k.app.type.exception.AppException; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
import jakarta.annotation.Resource; |
import jakarta.annotation.Resource; |
||||
import org.slf4j.Logger; |
import org.slf4j.Logger; |
||||
|
import org.springframework.scheduling.annotation.EnableScheduling; |
||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.time.Duration; |
||||
|
import java.time.Instant; |
||||
import java.util.List; |
import java.util.List; |
||||
|
|
||||
|
|
||||
@Component |
@Component |
||||
|
@EnableScheduling //Enable scheduled tasks |
||||
public class AppUserMgrService { |
public class AppUserMgrService { |
||||
static Logger logger = org.slf4j.LoggerFactory.getLogger(AppUserMgrService.class); |
|
||||
|
|
||||
@Resource |
|
||||
AppUsrDao appUsrDao; |
|
||||
|
|
||||
AppUser loginUsr = null; |
|
||||
|
|
||||
|
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
||||
// EXT FUNC |
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
||||
|
|
||||
|
|
||||
public AppUser login(int id, String password) throws AppException { |
|
||||
var usr = appUsrDao.getUsrById(id); |
|
||||
if (usr == null) |
|
||||
throw new AppException(A8kEcode.USR_NOT_EXIT); |
|
||||
|
|
||||
if (!usr.password.equals(password)) { |
|
||||
throw new AppException(A8kEcode.USR_PASSWORD_ERROR); |
|
||||
} |
|
||||
loginUsr = usr; |
|
||||
return (usr); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public Void unlogin() { |
|
||||
loginUsr = null; |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
synchronized public AppUser getLoginUsr() { |
|
||||
return (loginUsr); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public List<AppUser> getUsrlist() { |
|
||||
return (appUsrDao.getAllUsr()); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public AppUser addUser(String account, String password, AppUser.UsrRole type) throws AppException { |
|
||||
var user = appUsrDao.getUsrByAccount(account); |
|
||||
if (user != null) { |
|
||||
throw new AppException(A8kEcode.USR_ALREADY_EXIST); |
|
||||
} |
|
||||
user = new AppUser(account, password, type); |
|
||||
appUsrDao.addUser(user); |
|
||||
return appUsrDao.getUsrByAccount(account); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public Void delUser(Integer id) { |
|
||||
appUsrDao.deleteUserById(id); |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public AppUser updateUsr(AppUser usr) { |
|
||||
appUsrDao.updateUser(usr); |
|
||||
return usr; |
|
||||
} |
|
||||
|
|
||||
public AppUser modifyUsrPwd(Integer id, String oldpasswd,String password) throws AppException { |
|
||||
var user = appUsrDao.getUsrById(id); |
|
||||
if (user == null) { |
|
||||
throw new AppException(A8kEcode.USR_NOT_EXIT); |
|
||||
} |
|
||||
|
|
||||
if(!user.password.equals(oldpasswd)){ |
|
||||
throw new AppException(A8kEcode.USR_OLD_PASSWORD_ERROR); |
|
||||
} |
|
||||
|
|
||||
if (password.isEmpty()) { |
|
||||
throw new AppException(A8kEcode.USR_PASSWORD_IS_EMPTY); |
|
||||
} |
|
||||
|
|
||||
user.password = password; |
|
||||
appUsrDao.updateUser(user); |
|
||||
return user; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
public AppUser modifyUsrRole(Integer id, AppUser.UsrRole usrRole) throws AppException { |
|
||||
var user = appUsrDao.getUsrById(id); |
|
||||
if (user == null) { |
|
||||
throw new AppException(A8kEcode.USR_NOT_EXIT); |
|
||||
} |
|
||||
user.usrRole = usrRole; |
|
||||
appUsrDao.updateUser(user); |
|
||||
return user; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
public AppUser modifyUsrAccount(Integer id, String newaccount) throws AppException { |
|
||||
var user = appUsrDao.getUsrById(id); |
|
||||
if (user == null) { |
|
||||
throw new AppException(A8kEcode.USR_NOT_EXIT); |
|
||||
} |
|
||||
user.account = newaccount; |
|
||||
appUsrDao.updateUser(user); |
|
||||
return user; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
static Logger logger = org.slf4j.LoggerFactory.getLogger(AppUserMgrService.class); |
||||
|
|
||||
|
/** |
||||
|
* current user |
||||
|
*/ |
||||
|
@Resource |
||||
|
AppUsrDao appUsrDao; |
||||
|
@Resource |
||||
|
DeviceSettingDao deviceSettingDao; |
||||
|
|
||||
|
AppUser loginUsr = null; |
||||
|
|
||||
|
/** |
||||
|
* timestamp of last access |
||||
|
*/ |
||||
|
private volatile Instant lastAccess; |
||||
|
|
||||
|
/** |
||||
|
* auto logout time out duration |
||||
|
*/ |
||||
|
private volatile Duration autoLogoutTimeout; |
||||
|
|
||||
|
/** |
||||
|
* flag to enable auto logout |
||||
|
*/ |
||||
|
private volatile boolean autoLogout; |
||||
|
|
||||
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||||
|
// EXT FUNC |
||||
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||||
|
|
||||
|
/** |
||||
|
* load timeout and switch |
||||
|
*/ |
||||
|
@PostConstruct |
||||
|
public void init() { |
||||
|
DeviceSetting deviceSetting = deviceSettingDao.get(); |
||||
|
int minutes = deviceSetting.getAutoLogoutTimeout(); |
||||
|
this.autoLogoutTimeout = Duration.ofMinutes(minutes); |
||||
|
boolean autoLogout = deviceSetting.getAutoLogout(); |
||||
|
this.autoLogout = autoLogout; |
||||
|
logger.debug("initialized autoLogout={}, timeout={} minutes", autoLogout, minutes); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public AppUser login(int id, String password) throws AppException { |
||||
|
var usr = appUsrDao.getUsrById(id); |
||||
|
if (usr == null) |
||||
|
throw new AppException(A8kEcode.USR_NOT_EXIT); |
||||
|
|
||||
|
if (!usr.password.equals(password)) { |
||||
|
throw new AppException(A8kEcode.USR_PASSWORD_ERROR); |
||||
|
} |
||||
|
loginUsr = usr; |
||||
|
return (usr); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Void unlogin() { |
||||
|
loginUsr = null; |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* refresh lastAccess on each intercepted request |
||||
|
*/ |
||||
|
public synchronized void recordAccess() { |
||||
|
if (loginUsr != null) { |
||||
|
this.lastAccess = Instant.now(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public synchronized void updateAutoLogout(boolean autoLogout) { |
||||
|
this.autoLogout = autoLogout; |
||||
|
logger.debug("updated cache autoLogout:{}", autoLogout); |
||||
|
} |
||||
|
|
||||
|
public synchronized void updateAutoLogoutTimeout(int autoLogoutTimeout) { |
||||
|
this.autoLogoutTimeout = Duration.ofMinutes(autoLogoutTimeout); |
||||
|
logger.debug("updated cache autoLogoutTimeout {} minutes", autoLogoutTimeout); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
synchronized public AppUser getLoginUsr() { |
||||
|
return (loginUsr); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public List<AppUser> getUsrlist() { |
||||
|
return (appUsrDao.getAllUsr()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public AppUser addUser(String account, String password, AppUser.UsrRole type) throws AppException { |
||||
|
var user = appUsrDao.getUsrByAccount(account); |
||||
|
if (user != null) { |
||||
|
throw new AppException(A8kEcode.USR_ALREADY_EXIST); |
||||
|
} |
||||
|
user = new AppUser(account, password, type); |
||||
|
appUsrDao.addUser(user); |
||||
|
return appUsrDao.getUsrByAccount(account); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public Void delUser(Integer id) { |
||||
|
appUsrDao.deleteUserById(id); |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public AppUser updateUsr(AppUser usr) { |
||||
|
appUsrDao.updateUser(usr); |
||||
|
return usr; |
||||
|
} |
||||
|
|
||||
|
public AppUser modifyUsrPwd(Integer id, String oldpasswd, String password) throws AppException { |
||||
|
var user = appUsrDao.getUsrById(id); |
||||
|
if (user == null) { |
||||
|
throw new AppException(A8kEcode.USR_NOT_EXIT); |
||||
|
} |
||||
|
|
||||
|
if (!user.password.equals(oldpasswd)) { |
||||
|
throw new AppException(A8kEcode.USR_OLD_PASSWORD_ERROR); |
||||
|
} |
||||
|
|
||||
|
if (password.isEmpty()) { |
||||
|
throw new AppException(A8kEcode.USR_PASSWORD_IS_EMPTY); |
||||
|
} |
||||
|
|
||||
|
user.password = password; |
||||
|
appUsrDao.updateUser(user); |
||||
|
return user; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public AppUser modifyUsrRole(Integer id, AppUser.UsrRole usrRole) throws AppException { |
||||
|
var user = appUsrDao.getUsrById(id); |
||||
|
if (user == null) { |
||||
|
throw new AppException(A8kEcode.USR_NOT_EXIT); |
||||
|
} |
||||
|
user.usrRole = usrRole; |
||||
|
appUsrDao.updateUser(user); |
||||
|
return user; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public AppUser modifyUsrAccount(Integer id, String newaccount) throws AppException { |
||||
|
var user = appUsrDao.getUsrById(id); |
||||
|
if (user == null) { |
||||
|
throw new AppException(A8kEcode.USR_NOT_EXIT); |
||||
|
} |
||||
|
user.account = newaccount; |
||||
|
appUsrDao.updateUser(user); |
||||
|
return user; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Scheduled(fixedDelay = 60_000) |
||||
|
public void autoLogoutTask() { |
||||
|
if (!autoLogout || loginUsr == null) { |
||||
|
return; |
||||
|
} |
||||
|
if (Duration.between(lastAccess, Instant.now()).compareTo(autoLogoutTimeout) >= 0) { |
||||
|
logger.info("auto logout user {} after {} minutes inactivity", loginUsr.account, autoLogoutTimeout.toMinutes()); |
||||
|
unlogin(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
} |
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue