diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserPasswordService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserPasswordService.java index 5d4fbb6..ae0da21 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserPasswordService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserPasswordService.java @@ -39,6 +39,9 @@ public interface ISysUserPasswordService extends ICrudService { @ApiOperation(value = "根据密码反查") public List findPasswordByPassword(String password,Long userId); + @ApiOperation(value = "根据密码反查重置时间后的") + public List findPasswordByPasswordAndResetPwdTime(String password,Long userId); + /** * 修改密码,根据密码id,和新密码 * @param pwdId diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserService.java index 53ab510..4817cfd 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysUserService.java @@ -49,6 +49,9 @@ public interface ISysUserService { @ApiOperation(value = "锁定用户", notes = "锁定用户") void doLockSysUserById(Long id); + @ApiOperation(value = "锁定用户指定状态", notes = "锁定用户指定状态") + void doLockAndStatusSysUserById(Long id, Integer status); + /** * 批量修改账号状态 * @@ -110,6 +113,22 @@ public interface ISysUserService { @ApiOperation(value = "首次登录重置账号登录次数", notes = "首次登录重置账号登录次数") void updateUserLoginNum(Long userId,Integer userLoginNum); + /** + * 手动重置密码后是否强制修改密码 + * + * @param userId + */ + @ApiOperation(value = "手动重置密码后是否强制修改密码", notes = "手动重置密码后是否强制修改密码") + void updateUserLoginNumByHeadResetPwd(Long userId,Integer userLoginNum); + + /** + * 首次登录重置账号登录次数 + * + * @param userId + */ + @ApiOperation(value = "重置账号修改密码频次", notes = "重置账号修改密码频次") + void updateUserModifyPwdNum(Long userId,Integer modifyPwdNum); + /** * 刷新账号登录时间信息 @@ -443,4 +462,11 @@ public interface ISysUserService { */ @ApiOperation(value = "获取批量账号信息", notes = "查询用户信息-批量根据登录名称查询") ListPager findSysUserByName(String userLoginName,String userName ,Pager pager); + + /** + * 查询长时间未登录账号 + * @return + */ + @ApiOperation(value = "获取批量账号信息", notes = "查询用户信息-批量根据登录名称查询") + List findUserNotLoginLongTime(String startDate, String endDate); } diff --git a/modules/i3plus-core-apiservice/pom.xml b/modules/i3plus-core-apiservice/pom.xml index ee717bf..c03aa60 100644 --- a/modules/i3plus-core-apiservice/pom.xml +++ b/modules/i3plus-core-apiservice/pom.xml @@ -14,6 +14,11 @@ jar + + + com.xuxueli + xxl-job-core + com.alibaba druid diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java index 2ff6038..1189f4a 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java @@ -25,6 +25,7 @@ import cn.estsh.i3plus.pojo.base.common.Pager; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil; +import cn.estsh.i3plus.pojo.base.util.StringUtil; import cn.estsh.i3plus.pojo.model.common.CloudPagerModel; import cn.estsh.i3plus.pojo.model.common.ImppEmail; import cn.estsh.i3plus.pojo.model.common.ImppSmsContent; @@ -489,7 +490,12 @@ public class WhiteController extends CoreBaseController { } } // 记录登录记录 - recordSysUserLog(null, loginModel.getLoginName(), userLoginStatus.getValue()); + SessionUser sessionUser = (SessionUser)result.getResultObject(); + if(StringUtil.isEmpty(sessionUser) && StringUtil.isEmpty(sessionUser.getUserId())){ + recordSysUserLog(sessionUser.getUserId(), loginModel.getLoginName(), userLoginStatus.getValue()); + } else { + recordSysUserLog(null, loginModel.getLoginName(), userLoginStatus.getValue()); + } } LOGGER.info("会员{}登陆登录完成,登录{},语言:{} , 登录耗时:{}", loginModel.getLoginName(), result.isSuccess() ? "成功" : "失败", BaseThreadLocal.getThreadLanguageCode(), (System.currentTimeMillis() - startTime)); @@ -946,6 +952,13 @@ public class WhiteController extends CoreBaseController { } } + @GetMapping(value = "/user-update-password-hint") + @ApiOperation(value = "获取修改密码提示信息", notes = "获取修改密码提示信息") + public ResultBean getUserUpdatePasswordHint() { + List sysConfigs = configService.ListSysConfig(); + return ResultBean.success().setResultList(sysConfigs); + } + @PostMapping(value = "/license") @ApiOperation(value = "更新授权", notes = "更新授权") public ResultBean updateLicense(String content) { diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/PersonnelController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/PersonnelController.java index 9fb3d0f..7f32a2e 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/PersonnelController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/PersonnelController.java @@ -171,6 +171,7 @@ public class PersonnelController extends CoreBaseController { //松下需要创建的新用户 第一次登陆系统就要重置密码 // user.setUserPasswordLastModifyTime(TimeTool.getNowTime(true)); refreshSysUserPassword(user); + user.setUserPasswordLastModifyTime(TimeTool.getNowTime(true)); SysUser userSaved = personnelService.saveSysUser(user); // 添加保存passwordId进SysUser表 @@ -805,6 +806,7 @@ public class PersonnelController extends CoreBaseController { user.setUserPhone(model.getUserPhone()); user.setLanguageCode(model.getUserLanguageCode()); user.setUserAccountType(model.getUserAccountType()); + user.setUserPasswordOverdue(model.getUserPasswordOverdue()); if (!StringUtils.isAnyBlank(model.getUserLoginPassword())) { // 使用新密码 user.setUserLoginPassword(EncryptTool.hexMD5(model.getUserLoginPassword())); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysLogUserLoginController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysLogUserLoginController.java index f4de3d0..34b36b9 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysLogUserLoginController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysLogUserLoginController.java @@ -174,4 +174,46 @@ public class SysLogUserLoginController extends CoreBaseController { } } + @GetMapping(value = "/export/month/user-login") + @ApiOperation(value = "导出用户登录日志") + public ResultBean exportMonthlyUserLoginReport(HttpServletResponse response, String startTime, String endTime) { + File file = null; + try { + List sysLogUserLogins = userService.queryUserMonthlyLoginLog(startTime, endTime); + + ExcelTool excelTool = new ExcelTool(entityManager, redisRes); + String fileName = "user-login-log-" + System.currentTimeMillis() + ".xls"; + file = new File(fileName); + file.createNewFile(); + excelTool.exportData(file, sysLogUserLogins, SysLogUserLogin.class + , (LinkedHashMap) ExcelTool.getColName(SysLogUserLogin.class)); + + response.setContentType("application/force-download"); // 设置强制下载不打开 + response.addHeader("Content-Disposition", "attachment;fileName=" + fileName); // 设置文件名 + response.addHeader("Content-type", FileContentTypeTool.getContentType(StringTool.getStringFileSuffix(fileName, true))); + + // 设置文件名 + try (BufferedInputStream bis = new BufferedInputStream(new DataInputStream(new FileInputStream(file)))) { + OutputStream os = response.getOutputStream(); + byte[] buffer = new byte[1024]; + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + } catch (Exception e) { + LOGGER.error("用户日志导出异常", e); + } + return ResultBean.success().setResultList(sysLogUserLogins); + } catch (ImppBusiException busExcep) { + return ResultBean.fail(busExcep); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + }finally { + if(file!=null){ + FileUtils.deleteQuietly(file); + } + } + } + } diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysUserController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysUserController.java index c8ce185..c4e97b0 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysUserController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysUserController.java @@ -24,6 +24,7 @@ import cn.estsh.i3plus.pojo.base.common.Pager; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil; import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil; +import cn.estsh.i3plus.pojo.model.common.ExportDataModel; import cn.estsh.i3plus.pojo.model.platform.AccountExportModel; import cn.estsh.i3plus.pojo.model.platform.AndonQueryUserModel; import cn.estsh.i3plus.pojo.model.platform.AndonQueryUserResultModel; @@ -36,6 +37,7 @@ import cn.estsh.impp.framework.boot.util.ImppRedis; import cn.estsh.impp.framework.boot.util.RedisCacheTool; import cn.estsh.impp.framework.boot.util.ResultBean; import cn.estsh.impp.framework.boot.util.ValidatorBean; +import com.alibaba.fastjson.JSON; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.io.FileUtils; @@ -283,9 +285,10 @@ public class SysUserController extends CoreBaseController { ValidatorBean.checkNotZero(status, "功能状态不能为空"); sysUserService.updateBatchSysUserStatus(StringTool.getArrayLong(ids), status, AuthUtil.getSessionUser()); - //当解除锁定状态 重置当天登录错误次数上限 + //当解除锁定状态 重置当天登录错误次数上限和自动解锁次数 if (CommonEnumUtil.USER_STATUS.ENABLE.getValue() == status) { deleteRedisLoginErrorKeys(ids); + deleteRedisAutoUnlockNumKeys(ids); } return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); } catch (ImppBusiException busExcep) { @@ -312,6 +315,22 @@ public class SysUserController extends CoreBaseController { } /** + * 删除登录错误的次数 + * + * @param ids + */ + private void deleteRedisAutoUnlockNumKeys(String[] ids) { + String[] keys = new String[ids.length]; + StringBuilder redisKey = new StringBuilder(); + for (int i = 0; i < ids.length; i++) { + redisKey.append(CommonConstWords.USER_LOGIN_ERROR).append(":").append("authUnlockKey").append(":").append(TimeTool.getToday()).append(":").append(ids[i]); + keys[i] = redisKey.toString(); + redisKey.setLength(0); + } + redisCore.deleteKey(keys); + } + + /** * 根据登录的用户名批量修改账号状态 * * @param userLoginNames 用户名数组 @@ -428,6 +447,53 @@ public class SysUserController extends CoreBaseController { } } + @PostMapping(value = "/export/user-not-login-long-time") + @ApiOperation(value = "导出长时间未登录账号", notes = "导出长时间未登录账号") + public ResultBean exportUserNotLoginLongTime(@RequestBody ExportDataModel model, HttpServletResponse response) { + File file = null; + try { + ValidatorBean.checkNotNull("ColName", model.getExportCol()); + ValidatorBean.checkNotNull("startDate", model.getStartDate()); + ValidatorBean.checkNotNull("endDate", model.getEndDate()); + LinkedHashMap exportColMap = JSON.parseObject(model.getExportCol(), LinkedHashMap.class); + List list = sysUserService.findUserNotLoginLongTime(model.getStartDate(), model.getEndDate()); + ExcelTool excelTool = new ExcelTool(entityManager, redisRes); + String fileName = "user-not-login-long-time" + System.currentTimeMillis() + ".xls"; + file = new File(fileName); + file.createNewFile(); + excelTool.exportData(file, list, SysUser.class + , exportColMap); + + response.setContentType("application/force-download"); // 设置强制下载不打开 + response.addHeader("Content-Disposition", "attachment;fileName=" + fileName); // 设置文件名 + response.addHeader("Content-type", FileContentTypeTool.getContentType(StringTool.getStringFileSuffix(fileName, true))); + + // 设置文件名 + try (BufferedInputStream bis = new BufferedInputStream(new DataInputStream(new FileInputStream(file)))) { + OutputStream os = response.getOutputStream(); + byte[] buffer = new byte[1024]; + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + } catch (Exception e) { + LOGGER.error("用户长时间未登录日志导出异常", e); + } + return ResultBean.success("操作成功") + .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()) + .setResultList(list); + } catch (ImppBusiException busExcep) { + return ResultBean.fail(busExcep); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } finally { + if (file != null) { + FileUtils.deleteQuietly(file); + } + } + } + /** * 查询系统用户 * @@ -600,6 +666,8 @@ public class SysUserController extends CoreBaseController { userPasswordService.updatePasswordResetLastModifyTime(user.getId(), password, false); //重置成随机密码会让用户首次登录修改密码 sysUserService.updateUserLoginNum(user.getId(), 0); + //重置成随机密码之后清空修改次数,重新计算 + sysUserService.updateUserModifyPwdNum(user.getId(), 0); String content = "系统提示:\n" + "\t" + getSessionUser().getUserName() + "使用密码重置功能帮您重置了【" + user.getUserLoginName() + "】账号的密码," + "新密码是:" + password + ""; @@ -653,6 +721,10 @@ public class SysUserController extends CoreBaseController { num = numMax - num; userPasswordService.updatePasswordResetLastModifyTime(user.getId(), password, true); + //手动重置密码是否需要用户首次登录修改密码 + sysUserService.updateUserLoginNumByHeadResetPwd(user.getId(), 0); + //密码管理员手动重置密码之后清空修改次数,重新计算 + sysUserService.updateUserModifyPwdNum(user.getId(), 0); LOGGER.info("系统提示:{} 使用密码重置功能帮{}重置了{}账号的密码,新密码是:{}", getSessionUser().getUserName(), user.getUserName(), user.getUserLoginName(), password); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/schedulejob/CheckLoginTimeDayJob.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/schedulejob/CheckLoginTimeDayJob.java new file mode 100644 index 0000000..3c344ac --- /dev/null +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/schedulejob/CheckLoginTimeDayJob.java @@ -0,0 +1,85 @@ +package cn.estsh.i3plus.core.apiservice.schedulejob; + +import cn.estsh.i3plus.core.api.iservice.busi.ISysUserService; +import cn.estsh.i3plus.platform.common.tool.TimeTool; +import cn.estsh.i3plus.platform.common.util.CommonConstWords; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.platform.bean.SysUser; +import cn.estsh.i3plus.pojo.platform.repository.SysUserRepository; +import cn.estsh.impp.framework.base.schedule.BaseImppScheduleJob; +import cn.estsh.impp.framework.boot.auth.AuthUtil; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import cn.estsh.impp.framework.boot.util.ImppRedis; +import cn.estsh.impp.framework.boot.util.RedisCacheTool; +import com.xxl.job.core.handler.annotation.XxlJob; +import io.swagger.annotations.ApiOperation; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.persistence.EntityManager; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +/** + * @Description : + * @Reference : + * @Author : + * @CreateDate : 2022-11-15 17:23 + * @Modify: + **/ +@DisallowConcurrentExecution +@ApiOperation("锁定长时间未登录用户job") +@Component +public class CheckLoginTimeDayJob extends BaseImppScheduleJob { + + @Autowired + private SysUserRepository userRDao; + + @Autowired + private EntityManager entityManager; + + @Resource(name = CommonConstWords.IMPP_REDIS_CORE) + protected ImppRedis redisCore; + + public CheckLoginTimeDayJob() { + super(CheckLoginTimeDayJob.class, "锁定长时间未登录用户"); + } + + @XxlJob("cn.estsh.i3plus.core.apiservice.schedulejob.CheckLoginTimeDayJob") + @Override + public void executeImppJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + boolean unLoginLongTimeOnOff = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_USER_UNLOGIN_LONG_TIME_LOCK, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + int unLoginDay = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT, CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT_DEFAULT); + + if (unLoginLongTimeOnOff && unLoginDay != 0) { + //获取unLoginDay之前的时间 +// long time = (long)unLoginDay * 86400000; +// TimeTool.pareDateToString + Date dateBefore = TimeTool.getDateBefore(new Date("yyyy-MM-dd HH:mm:ss"), unLoginDay); + String unLoginDayAgo = TimeTool.pareDateToString(dateBefore); +// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// String unLoginDayAgo = simpleDateFormat.format(new Date(System.currentTimeMillis() - time)); + + String hql = " select su from SysUser as su " + + "where su.userLoginLastDateTime <=:userLoginLastDateTime " + + "and su.userPasswordOverdue = :userPasswordOverdue"; + + List sysUserList = entityManager.createQuery(hql) + .setParameter("userLoginLastDateTime", unLoginDayAgo) + .setParameter("userPasswordOverdue", CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) + .getResultList(); + + for (SysUser user : sysUserList) { + user.setUserStatus(CommonEnumUtil.USER_STATUS.DISABLE.getValue()); + user.setLockType(CommonEnumUtil.LOCK_TYPE.NOT_LOGIN_A_LONG_TIME.getValue()); + userRDao.save(user); + } + + } + + } +} diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/login/strategy/DefaultLoginStrategy.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/login/strategy/DefaultLoginStrategy.java index 32c4a09..f5be7db 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/login/strategy/DefaultLoginStrategy.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/login/strategy/DefaultLoginStrategy.java @@ -56,7 +56,7 @@ public class DefaultLoginStrategy implements ISystemLoginStrategyService { public BiFunction login() { return (request, loginModel) -> { ResultBean result; - ValidatorBean.checkNotNull(loginModel.getLanguageCode(), "语言不能为空"); +// ValidatorBean.checkNotNull(loginModel.getLanguageCode(), "语言不能为空"); // TODO 后期移除,暂时用于避免自动登录后前台没有正确的传输组织代码信息 if ("null".equals(loginModel.getLanguageCode())) { loginModel.setLanguageCode(DEFAULT_LANGUAGE); @@ -124,7 +124,7 @@ public class DefaultLoginStrategy implements ISystemLoginStrategyService { SysConfig passwordExpireDays = RedisCacheTool.getSysConfigByConfigCode(CommonConstWords.CONFIG_PWD_EXPIRE_DAY_TIME); if (passwordExpireDays != null && Integer.parseInt(passwordExpireDays.getConfigValue()) > 0) { SysUser user = userService.getSysUserByLoginName(loginName); - if (StringUtils.isEmpty(user.getUserPasswordLastModifyTime())) { + if (StringUtils.isEmpty(user.getUserPasswordLastModifyTime()) && user.getUserPasswordOverdue() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) { throw new ExpiredCredentialsException("用户密码过期 请重新设置新密码"); } else { DateFormat df = new SimpleDateFormat(CommonConstWords.DATE_TIME_FORMAT_HH_MM_SS_RISK); @@ -135,7 +135,7 @@ public class DefaultLoginStrategy implements ISystemLoginStrategyService { throw new ImppBusiException("验证用户密码登录时间,时间解析错误"); } long dayGap = (System.currentTimeMillis() - lastModifyDate.getTime()) / (60 * 60 * 1000 * 24); - if ((int) dayGap >= Integer.parseInt(passwordExpireDays.getConfigValue())) { + if ((int) dayGap >= Integer.parseInt(passwordExpireDays.getConfigValue()) && user.getUserPasswordOverdue() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) { throw new ExpiredCredentialsException("用户密码过期 请重新设置新密码"); } } diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/PersonnelServiceService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/PersonnelServiceService.java index 5ecfcee..50016b6 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/PersonnelServiceService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/PersonnelServiceService.java @@ -1041,6 +1041,8 @@ public class PersonnelServiceService implements IPersonnelService { logRoleChange.setUserId(userId); logRoleChange.setPreviousRoles(previousRole); logRoleChange.setCurrentRoles(currentRole); + logRoleChange.setUserLoginName(user.getUserLoginName()); + logRoleChange.setDepartmentNameRdd(user.getDepartmentNameRdd()); ConvertBean.serviceModelInitialize(logRoleChange, AuthUtil.getSessionUser().getUserName()); logRoleChangeRepository.save(logRoleChange); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserSavePasswordService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserSavePasswordService.java index e83cf00..2a472c3 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserSavePasswordService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserSavePasswordService.java @@ -6,6 +6,7 @@ import cn.estsh.i3plus.core.apiservice.util.SysUserPasswordUtil; import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; import cn.estsh.i3plus.platform.common.tool.TimeTool; +import cn.estsh.i3plus.platform.common.util.CommonConstWords; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.jpa.dao.BaseRepository; @@ -16,11 +17,14 @@ import cn.estsh.i3plus.pojo.platform.repository.SysUserPasswordRepository; import cn.estsh.impp.framework.base.service.CrudService; import cn.estsh.impp.framework.boot.auth.AuthUtil; import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; +import cn.estsh.impp.framework.boot.util.ImppRedis; +import cn.estsh.impp.framework.boot.util.RedisCacheTool; import cn.estsh.impp.framework.boot.util.ValidatorBean; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @@ -45,6 +49,9 @@ public class SysUserSavePasswordService extends CrudService imp @Autowired private SysUserPasswordUtil userPasswordUtil; + @Resource(name = CommonConstWords.IMPP_REDIS_CORE) + protected ImppRedis redisCore; + @Override public BaseRepository getRepository() { return userPasswordRDao; @@ -93,12 +100,22 @@ public class SysUserSavePasswordService extends CrudService imp user.setUserLoginPassword(password); userPasswordUtil.checkPasswordSave(user); - userPasswordRDao.updateByProperties( - new String[]{"userId", "isDeleted"}, - new Object[]{user.getId(), CommonEnumUtil.IS_DEAL.NO.getValue()}, - new String[]{"isDeleted", "modifyDatetime", "modifyUser"}, - new Object[]{ - CommonEnumUtil.IS_DEAL.YES.getValue(), TimeTool.getNowTime(true), AuthUtil.getSessionUser().getUserName()}); + String frequencyDay = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY); + String redisKey = CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY+"_"+user.getId()+"_"+user.getUserLoginName(); + //校验密码修改次数 + Object redisfrequencyDay = redisCore.getObject(redisKey); + + if (redisfrequencyDay == null) { + redisCore.putObject(redisKey, frequencyDay, Integer.parseInt(frequencyDay)*CommonConstWords.REDIS_TIME_DAY_ONE); + user.setModifyPwdNum(1); + } else { + int modifyNum = 0; + Integer modifyUnlockNum = user.getModifyPwdNum(); + if (null != modifyUnlockNum) { + modifyNum = modifyUnlockNum; + } + user.setModifyPwdNum(modifyNum++); + } SysUserPassword pwd = new SysUserPassword(); pwd.setUserId(userId); @@ -108,6 +125,7 @@ public class SysUserSavePasswordService extends CrudService imp user.setUserLoginPasswordId(save.getId()); user.setUserPasswordLastModifyTime(TimeTool.getNowTime(true)); + user.setUserLoginPassword(SysUserPasswordUtil.encoder(password)); ConvertBean.serviceModelUpdate(user, AuthUtil.getSessionUser().getUserName()); userService.updateSysUser(user); } @@ -136,7 +154,10 @@ public class SysUserSavePasswordService extends CrudService imp user.setUserLoginPasswordId(save.getId()); // 松下需要 重置密码之后 重新登录重新设置密码 - user.setUserPasswordLastModifyTime(""); + user.setUserPasswordLastModifyTime(TimeTool.getNowTime(true)); + // 重置密码设置重置密码的时间,方便充值后重新技术校验密码重复次数 + user.setResetPasswordTime(TimeTool.getNowTime(true)); + user.setUserLoginPassword(SysUserPasswordUtil.encoder(password)); ConvertBean.serviceModelUpdate(user, AuthUtil.getSessionUser().getUserName()); userService.updateSysUser(user); } @@ -147,6 +168,24 @@ public class SysUserSavePasswordService extends CrudService imp user.setUserLoginPassword(newPwd); userPasswordUtil.checkPasswordSave(user); + //供应商,修改密码校验修改次数 + String frequencyDay = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY); + String redisKey = CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY+"_"+user.getId()+"_"+user.getUserLoginName(); + //校验密码修改次数 + Object redisfrequencyDay = redisCore.getObject(redisKey); + + if (redisfrequencyDay == null) { + redisCore.putObject(redisKey, frequencyDay, Integer.parseInt(frequencyDay)*CommonConstWords.REDIS_TIME_DAY_ONE); + user.setModifyPwdNum(1); + } else { + Integer modifyUnlockNum = user.getModifyPwdNum(); + int modifyNum = 0; + if(null != modifyUnlockNum){ + modifyNum = modifyUnlockNum; + } + user.setModifyPwdNum(++modifyNum); + } + userService.updateSysUser(user); //当前方法是不需要session,是在登陆前弹窗修改密码 //如果是首次登录修改密码,则设置登录次数为1 if(null == user.getUserLoginNum() || user.getUserLoginNum() == 0){ @@ -165,9 +204,9 @@ public class SysUserSavePasswordService extends CrudService imp pwd.setUserPassword(SysUserPasswordUtil.encoder(newPwd)); ConvertBean.serviceModelInitialize(pwd, loginName); SysUserPassword save = userPasswordRDao.save(pwd); - user.setUserLoginPasswordId(save.getId()); user.setUserPasswordLastModifyTime(TimeTool.getNowTime(true)); + user.setUserLoginPassword(SysUserPasswordUtil.encoder(newPwd)); ConvertBean.serviceModelUpdate(user, loginName); userService.updateSysUser(user); } @@ -185,6 +224,24 @@ public class SysUserSavePasswordService extends CrudService imp } @Override + public List findPasswordByPasswordAndResetPwdTime(String password,Long userId) { + List passwordList = new ArrayList<>(); + if(StringUtils.isBlank(password) || userId == null){ + return passwordList; + } + SysUser user = userService.getSysUserById(userId); + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(); + DdlPreparedPack.getStringEqualPack(password,"userPassword",ddlPackBean); + DdlPreparedPack.getNumEqualPack(userId,"userId",ddlPackBean); + //当重置密码时间不为空时,查出在重置密码之后所修改的密码 + if(null != user && user.getResetPasswordTime() != null){ + DdlPreparedPack.getStringBiggerPack(user.getResetPasswordTime(), "createDatetime",ddlPackBean); + } + List byHqlWhere = userPasswordRDao.findByHqlWhere(ddlPackBean); + return byHqlWhere; + } + + @Override public void updatePasswordByPwdIdAndNewPwd(Long pwdId, String newPwd) { try { SysUserPassword sup = userPasswordRDao.getById(pwdId); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserService.java index 435cc6e..3f7e943 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysUserService.java @@ -123,6 +123,9 @@ public class SysUserService implements ISysUserService { @Resource(name = CommonConstWords.IMPP_REDIS_SESSION) private ImppRedis redisSession; + @Resource(name = CommonConstWords.IMPP_REDIS_CORE) + protected ImppRedis redisCore; + @Override @ApiOperation(value = "用户登录", notes = "用户登录功能实现") @Transactional(propagation = Propagation.REQUIRED) @@ -140,6 +143,7 @@ public class SysUserService implements ISysUserService { if (user.getUserStatus() != CommonEnumUtil.USER_STATUS.ENABLE.getValue()) { throw new LockedAccountException("账号已被锁定"); } + user.setUserLoginPassword(password); //校验 用户 ResultBean result = passwordUtil.checkSysUserLogin(user); if (!result.isSuccess()) { @@ -300,6 +304,16 @@ public class SysUserService implements ISysUserService { } @Override + public void doLockAndStatusSysUserById(Long id,Integer status) { + SysUser user = userRDao.getById(id); + if (Objects.nonNull(user)) { + user.setUserStatus(CommonEnumUtil.USER_STATUS.LOCKING.getValue()); + user.setLockType(status); + userRDao.save(user); + } + } + + @Override @ApiOperation(value = "修改账号", notes = "批量修改账号状态") public void updateBatchSysUserStatus(Long[] ids, int status, SessionUser user) { LOGGER.debug("平台用户 SYS_USER DELETE By ids :{} status:{}, SessionUser :{}", ids, status, user); @@ -404,11 +418,16 @@ public class SysUserService implements ISysUserService { @Override @ApiOperation(value = "刷新账号", notes = "刷新账号登录信息") public void refreshUserLoginInformation(Long userId) { + String today = TimeTool.getToday(); + String redisKey = CommonConstWords.USER_LOGIN_ERROR + ":" + today + ":" + userId; + String redisAuthUnlockKey = CommonConstWords.USER_LOGIN_ERROR + ":" + "authUnlockKey" + ":" + today + ":" + userId; + String unlockRedisKey = CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUM_UNLOCK_TIME + "_" + userId; SysUser user = userRDao.getById(userId); user.setUserLoginLastDateTime(TimeTool.getNowTime(true)); user.setUserLoginNum(user.getUserLoginNum() + 1); userRDao.save(user); + redisCore.deleteKey(new String[]{redisKey, redisAuthUnlockKey, unlockRedisKey}); SysUserInfo userInfo = sysUserInfoRDao.getById(user.getUserInfoId()); userInfo.setUserLoginLastDateTime(TimeTool.getNowTime(true)); userInfo.setUserLoginNum(userInfo.getUserLoginNum() + 1); @@ -425,6 +444,29 @@ public class SysUserService implements ISysUserService { sysUserInfoRDao.updateByProperties(new String[]{"userLoginNum"}, new Object[]{loginNum}, userInfoDdlPackBean); } + @Override + public void updateUserLoginNumByHeadResetPwd(Long userId, Integer loginNum) { + int resetUpdatePwd = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_RESET_PASSWORD_HEAD_ONOFF, CommonConstWords.CONFIG_PWD_RESET_PASSWORD_HEAD_ONOFF_DEFAULT); + if (resetUpdatePwd == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) { + SysUser user = userRDao.getById(userId); + user.setUserLoginNum(loginNum); + userRDao.save(user); + DdlPackBean userInfoDdlPackBean = DdlPackBean.getDdlPackBean(); + DdlPreparedPack.getNumEqualPack(user.getUserInfoId(), "id", userInfoDdlPackBean); + sysUserInfoRDao.updateByProperties(new String[]{"userLoginNum"}, new Object[]{loginNum}, userInfoDdlPackBean); + } + } + + + @Override + public void updateUserModifyPwdNum(Long userId, Integer modifyPwdNum) { + SysUser user = userRDao.getById(userId); + String redisKey = CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY+"_"+user.getId()+"_"+user.getUserLoginName(); + user.setModifyPwdNum(modifyPwdNum); + userRDao.save(user); + redisCore.deleteKey(redisKey); + } + @Override public void refreshUserLoginDateTime(Long userId, Long userInfoId) { @@ -1074,6 +1116,16 @@ public class SysUserService implements ISysUserService { return new ListPager(userRDao.findByHqlWherePage(ddlPackBean, pager), pager); } + @Override + public List findUserNotLoginLongTime(String startDate, String endDate) { + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(); + DdlPreparedPack.getNumEqualPack(CommonEnumUtil.USER_STATUS.DISABLE.getValue(),"userStatus",ddlPackBean); + DdlPreparedPack.getNumEqualPack(CommonEnumUtil.LOCK_TYPE.NOT_LOGIN_A_LONG_TIME.getValue(),"lockType",ddlPackBean); + DdlPreparedPack.timeBuilder(startDate, endDate, "modifyDatetime", true, true, ddlPackBean); + List userNotLoginLongTimeList = userRDao.findByHqlWhere(ddlPackBean); + return userNotLoginLongTimeList; + } + /** * 账号数据排序 diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java index dabcf6c..37f7f1e 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java @@ -7,6 +7,7 @@ import cn.estsh.i3plus.platform.common.tool.EncryptTool; import cn.estsh.i3plus.platform.common.tool.TimeTool; import cn.estsh.i3plus.platform.common.util.CommonConstWords; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.platform.bean.SysConfig; import cn.estsh.i3plus.pojo.platform.bean.SysUser; import cn.estsh.i3plus.pojo.platform.bean.SysUserPassword; import cn.estsh.impp.framework.boot.exception.ImppBusiException; @@ -28,8 +29,10 @@ import org.springframework.util.ObjectUtils; import javax.annotation.Resource; import javax.naming.NamingException; import javax.naming.ldap.LdapContext; +import javax.persistence.EntityManager; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; +import java.text.ParseException; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -119,18 +122,22 @@ public class SysUserPasswordUtil { * @param user */ public void checkPasswordLogin(SysUser user) { - /* 密码 长度校验 */ - checkPasswordLength(user.getUserLoginPassword()); - /* 密码 大写字母校验 */ - checkPasswordUppercaseEnglish(user.getUserLoginPassword()); - /* 密码 小写字母校验 */ - checkPasswordlowerEnglish(user.getUserLoginPassword()); - /* 密码 数字校验 */ - checkPasswordNumber(user.getUserLoginPassword()); - /* 密码 特殊字符校验 */ - checkPasswordSpecial(user.getUserLoginPassword()); - /* 密码 密码正则校验 */ - checkPasswordRepeat(user.getUserLoginPassword()); + // + SysConfig sysConfig = RedisCacheTool.getSysConfigByConfigCode(CommonConstWords.CONFIG_PWD_LENGTH); + if(StringUtils.isEmpty(user.getUserPasswordLastModifyTime()) || user.getUserPasswordLastModifyTime().compareTo(sysConfig.getModifyDatetime()) >= 0) { + /* 密码 长度校验 */ + checkPasswordLength(user.getUserLoginPassword()); + /* 密码 大写字母校验 */ + checkPasswordUppercaseEnglish(user.getUserLoginPassword()); + /* 密码 小写字母校验 */ + checkPasswordlowerEnglish(user.getUserLoginPassword()); + /* 密码 数字校验 */ + checkPasswordNumber(user.getUserLoginPassword()); + /* 密码 特殊字符校验 */ + checkPasswordSpecial(user.getUserLoginPassword()); + /* 密码 密码正则校验 */ + checkPasswordRepeat(user.getUserLoginPassword()); + } } /******************************************** 用户保存密码检查 ********************************************/ @@ -150,6 +157,8 @@ public class SysUserPasswordUtil { checkPasswordRepeatDay(user); /* 密码 密码正则校验 */ checkPasswordRepeat(user.getUserLoginPassword()); + /* 密码 用户修改密码频次校验 */ + checkPasswordFrequency(user); } /** @@ -327,7 +336,7 @@ public class SysUserPasswordUtil { // List passwords = userPasswordService.findAllByBean(userPassword); //修改为查询这个账号最近的密码是否重复 - List passwords = userPasswordService.findPasswordByPassword(EncryptTool.hexMD5(user.getUserLoginPassword()),user.getId()); + List passwords = userPasswordService.findPasswordByPasswordAndResetPwdTime(EncryptTool.hexMD5(user.getUserLoginPassword()),user.getId()); int lastDay = Integer.MAX_VALUE; if (CollectionUtils.isNotEmpty(passwords)) { @@ -344,7 +353,7 @@ public class SysUserPasswordUtil { throw ImppExceptionBuilder.newInstance() .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail(String.format("最近%s天内,请勿使用重复密码",num)) + .setErrorDetail(String.format("最近%s次内,请勿使用重复密码",num)) .setErrorSolution("请重新输入") .build(); } @@ -400,6 +409,62 @@ public class SysUserPasswordUtil { } } + /** + * 密码 用户修改密码频次校验 + * + * @param user + */ + private void checkPasswordFrequency(SysUser user) { + String frequencyDay = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_DAY); + String frequencyNum = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_MODIFY_PWD_FREQUENCY_NUM); + + if (StringUtils.isNotBlank(frequencyDay) && StringUtils.isNotBlank(frequencyNum)) { + //获取到修改的次数count + Integer modifyUnlockNum = user.getModifyPwdNum(); + if(null!= modifyUnlockNum && modifyUnlockNum >= Integer.parseInt(frequencyNum)){ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("密码【%s】天只能修改【%s】次",frequencyDay,frequencyNum) + .setErrorSolution("修改次数过多") + .build(); + } + } + } + + /** + * 校验正确登录是否在自动锁定的时间 + * + * @param user + */ + private ResultBean checkAuthUnlockTime(SysUser user) { + //校验自动解锁次数是否达到三次 + if (null != user.getAutoUnlockNum() && user.getAutoUnlockNum() >= 3){ + //锁定账号并设定锁定类型 + userService.doLockAndStatusSysUserById(user.getId(),CommonEnumUtil.LOCK_TYPE.LOGGER_TOO_MANY_FAILURES.getValue()); + return ResultBean.fail() + .setCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorMsg(LocaleUtils.getLocaleRes("用户名或密码多次输入错误。用户已被锁定请联系管理员!")); + } + String unlockRedisKey = CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUM_UNLOCK_TIME + "_" + user.getId(); + String unlockTime = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUM_UNLOCK_TIME); + Object redisUnlockTime = redisCore.getObject(unlockRedisKey); + if(null != redisUnlockTime){ + try { + int secoundsBetweenTime = TimeTool.getSecoundsBetweenTime(1, redisUnlockTime.toString(), TimeTool.getNowTime(null)); + secoundsBetweenTime = Integer.parseInt(unlockTime) * 60 - secoundsBetweenTime; + return ResultBean.fail() + .setCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorMsg(LocaleUtils.getLocaleRes("登录失败次数过多。请【" + secoundsBetweenTime/60 + "】分【" + secoundsBetweenTime%60 + "】秒后再试")); + } catch (ParseException parseException) { + parseException.printStackTrace(); + LOGGER.error("时间计算异常", parseException); + } + } + + return ResultBean.success(); + } + /******************************************** 用户登录密码检查 ********************************************/ public ResultBean checkSysUserLogin(SysUser user) { @@ -429,7 +494,11 @@ public class SysUserPasswordUtil { if (!result.isSuccess()) { return result; } - + /* 判断自动锁定时间 */ + result = checkAuthUnlockTime(user); + if (!result.isSuccess()) { + return result; + } //登录时是否检查用户密码是否符合安全规则 try { int isLoginCheckPassword = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_LOGIN_CHECK_PASSWORD,CommonConstWords.CONFIG_LOGIN_CHECK_PASSWORD_DEFAULT); @@ -520,6 +589,8 @@ public class SysUserPasswordUtil { int loginErrorNumber = 0; String redisKey = CommonConstWords.USER_LOGIN_ERROR + ":" + today + ":" + userId; + String redisAuthUnlockKey = CommonConstWords.USER_LOGIN_ERROR + ":" + "authUnlockKey" + ":" + today + ":" + userId; + try { Object redisValue = redisCore.getObject(redisKey); if (Objects.nonNull(redisValue)) { @@ -529,7 +600,9 @@ public class SysUserPasswordUtil { LOGGER.error("获取登录异常次数错误,错误信息:{}", exception.getMessage()); } - if (Objects.equals(loginErrorNumberMax, loginErrorNumber)) { + Object authUnlockNum = redisCore.getObject(redisAuthUnlockKey); + + if (Objects.equals(loginErrorNumberMax, loginErrorNumber) && authUnlockNum != null && Integer.parseInt(authUnlockNum.toString())>=3) { // 锁定账号信息 userService.doLockSysUserById(userId); @@ -539,7 +612,9 @@ public class SysUserPasswordUtil { .setErrorDetail("账号已被锁定") .setErrorSolution("请联系系统管理员") .build(); - } else if (loginErrorNumber > loginErrorNumberMax) { + } else if (loginErrorNumber > loginErrorNumberMax && authUnlockNum != null && Integer.parseInt(authUnlockNum.toString())>=3) { + // 锁定账号信息 + userService.doLockSysUserById(userId); throw ImppExceptionBuilder.newInstance() .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) @@ -554,58 +629,46 @@ public class SysUserPasswordUtil { if (Objects.nonNull(resultBean)) { int num = loginErrorNumberMax - loginErrorNumber; - if (num == 0) { - resultBean.setErrorMsg(LocaleUtils.getLocaleRes("密码输入错误。用户已被锁定请联系管理员!")); - } else { - resultBean.setErrorMsg(String.format(LocaleUtils.getLocaleRes("密码输入错误。再输入错误 %s 次,用户将被锁定"), num)); - } - } - - redisCore.putObject(redisKey, loginErrorNumber, CommonConstWords.REDIS_TIME_DAY_ONE); - } - } - - /** - * 登录 检查密码有效期 - */ - private ResultBean checkLoginPasswordTimeOut(SysUser user) { - try { - int passwordDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_VALID_DAY, CommonConstWords.CONFIG_PWD_VALID_DAY_DEFAULT); - if (passwordDayMax > 0) { - - SysUserPassword password = userPasswordService.get(user.getUserLoginPasswordId()); - if (Objects.nonNull(password) && StringUtils.isNotBlank(password.getCreateDatetime())) { - int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true)); - if (day > passwordDayMax) { - // 锁定账号信息 - userService.doLockSysUserById(user.getId()); + if (num <= 0) { + int autoUnlockNum = 0; + String unlockTime = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUM_UNLOCK_TIME); + String unlockRedisKey = CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUM_UNLOCK_TIME + "_" + userId; -// throw ImppExceptionBuilder.newInstance() -// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) -// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) -// .setErrorDetail("账号密码已过期") -// .setErrorSolution("请联系系统管理员") -// .build(); - ImppBusiException exception = ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("账号密码已过期") - .setErrorSolution("请联系系统管理员") - .build(); - return ResultBean.fail(exception); + if (null != authUnlockNum) { + autoUnlockNum = Integer.parseInt(authUnlockNum.toString()); + } + Object redisUnlockTime = redisCore.getObject(unlockRedisKey); + + if (null == redisUnlockTime) { + redisCore.putObject(unlockRedisKey, TimeTool.getNowTime(null), Long.parseLong(unlockTime) * 60L); + redisCore.putObject(redisAuthUnlockKey, autoUnlockNum++, CommonConstWords.REDIS_TIME_DAY_ONE); + if(autoUnlockNum >= 3 ){ + userService.doLockAndStatusSysUserById(userId,CommonEnumUtil.LOCK_TYPE.LOGGER_TOO_MANY_FAILURES.getValue()); + redisCore.deleteKey(unlockRedisKey); + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("登录失败次数过多") + .setErrorSolution("请联系系统管理员") + .build(); + } + resultBean.setErrorMsg(LocaleUtils.getLocaleRes("用户名或密码输入错误。请【" + unlockTime + "】分钟后再试")); + } else { + try { + int secoundsBetweenTime = TimeTool.getSecoundsBetweenTime(1, redisUnlockTime.toString(), TimeTool.getNowTime(null)); + secoundsBetweenTime = Integer.parseInt(unlockTime) * 60 - secoundsBetweenTime; + resultBean.setErrorMsg(LocaleUtils.getLocaleRes("登录失败次数过多。请【" + secoundsBetweenTime/60 + "】分【" + secoundsBetweenTime%60 + "】秒后再试")); + } catch (ParseException parseException) { + parseException.printStackTrace(); + LOGGER.error("时间计算异常", parseException); + } } + } else { + resultBean.setErrorMsg(String.format(LocaleUtils.getLocaleRes("用户名或密码输入错误。还有 %s 次机会"), num)); } } - } catch (ImppBusiException e) { -// throw e; - e.printStackTrace(); - return ResultBean.fail(e); - } catch (Exception e) { - LOGGER.error("密码有效期处理异常,异常信息:{}", e.getMessage()); - e.printStackTrace(); - return ResultBean.fail(e); + redisCore.putObject(redisKey, loginErrorNumber, CommonConstWords.REDIS_TIME_DAY_ONE); } - return ResultBean.success(); } /** @@ -614,10 +677,11 @@ public class SysUserPasswordUtil { private ResultBean checkLoginTimeOut(SysUser user) { try { if (StringUtils.isBlank(user.getUserLoginLastDateTime())) { - return ResultBean.success("上次登录时间为空"); + return ResultBean.fail("上次登录时间为空"); } + boolean longTimenNotLogin = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_USER_UNLOGIN_LONG_TIME_LOCK, CommonEnumUtil.TRUE_OR_FALSE.FALSE); int loginDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT, CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT_DEFAULT); - if (loginDayMax > 0) { + if (longTimenNotLogin && loginDayMax > 0) { int day = TimeTool.getSecoundsBetweenTime(4, user.getUserLoginLastDateTime(), TimeTool.getNowTime(true)); if (day > loginDayMax) { @@ -651,6 +715,53 @@ public class SysUserPasswordUtil { return ResultBean.success(); } + /** + * 登录 检查密码有效期 + */ + private ResultBean checkLoginPasswordTimeOut(SysUser user) { + try { + boolean pwdExpireSwitch = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXPIRE_SWITCH, CommonEnumUtil.TRUE_OR_FALSE.FALSE); +// int passwordDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_VALID_DAY, CommonConstWords.CONFIG_PWD_VALID_DAY_DEFAULT); + Integer userPasswordOverdueValue = user.getUserPasswordOverdue(); + + if (pwdExpireSwitch && userPasswordOverdueValue == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) { + SysConfig sysConfigByConfigCode = RedisCacheTool.getSysConfigByConfigCode(CommonConstWords.CONFIG_PWD_EXPIRE_DAY_TIME); + String configValue = sysConfigByConfigCode.getConfigValue(); + SysUserPassword password = userPasswordService.get(user.getUserLoginPasswordId()); + if (Objects.nonNull(password) && StringUtils.isNotBlank(password.getCreateDatetime())) { + int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true)); + if (day > Integer.parseInt(configValue)) { + // 锁定账号信息 +// userService.doLockSysUserById(user.getId()); + +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("账号密码已过期") +// .setErrorSolution("请联系系统管理员") +// .build(); + ImppBusiException exception = ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.LOGIN_EXCEPTION_PASSWORD_EXPIRED.getCode()) + .setErrorDetail("账号密码已过期") + .setErrorSolution("请重新修改密码") + .build(); + return ResultBean.fail(exception); + } + } + } + } catch (ImppBusiException e) { +// throw e; + e.printStackTrace(); + return ResultBean.fail(e); + } catch (Exception e) { + LOGGER.error("密码有效期处理异常,异常信息:{}", e.getMessage()); + e.printStackTrace(); + return ResultBean.fail(e); + } + return ResultBean.success(); + } + /** * 第一次登录是否修改密码 diff --git a/pom.xml b/pom.xml index 2055206..6c78c26 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,13 @@ ${project.dependency.version} + + + com.xuxueli + xxl-job-core + 2.3.0 + + org.springframework spring-web