From 8783b9a33feb6734b5d5d2150dd9510c5e4e4a33 Mon Sep 17 00:00:00 2001 From: "wei.peng" <123456> Date: Mon, 15 Jun 2020 18:46:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=AF=86=E7=A0=81=E8=A7=84=E5=88=99?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E5=AE=8C=E6=88=90):=20=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=99=BB=E5=BD=95,=E5=AF=86=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/api/iservice/busi/IPersonnelService.java | 5 +- .../api/iservice/busi/ISysUserPasswordService.java | 13 + .../core/api/iservice/busi/ISysUserService.java | 2 +- .../controller/base/WhiteController.java | 14 +- .../controller/busi/PersonnelController.java | 15 +- .../controller/busi/SysUserController.java | 110 +++-- .../apiservice/mq/MdmDataSyncQueueReceiver.java | 68 +-- .../serviceimpl/base/SystemLoginService.java | 74 ++- .../serviceimpl/busi/PersonnelServiceService.java | 176 +++---- .../busi/SysUserSavePasswordService.java | 57 +++ .../serviceimpl/busi/SysUserService.java | 59 ++- .../core/apiservice/util/SysUserPasswordUtil.java | 505 +++++++++++++++++++++ 12 files changed, 854 insertions(+), 244 deletions(-) create mode 100644 modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/IPersonnelService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/IPersonnelService.java index 24017d5..3c512df 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/IPersonnelService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/IPersonnelService.java @@ -186,8 +186,8 @@ public interface IPersonnelService { @ApiOperation(value = "组织关系检查") void checkSysOrganizeRef(Long organizeId); - @ApiOperation(value = "密码规则校验") - void checkSysUserPassword(String password); +// @ApiOperation(value = "密码规则校验") +// void checkSysUserPassword(String password); // @ApiOperation(value = "岗位关系检查") // void refreshUpdateMenuRdd(Long menuId); @@ -207,6 +207,7 @@ public interface IPersonnelService { @ApiOperation(value = "刷新用户岗位") void refreshRefSysUserInfoPosition(Long userInfoId, Long[] positionIds); + // /** // * 根据组织代码查询组织信息 // * @return 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 b3a8f8d..1bce21d 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 @@ -2,6 +2,7 @@ package cn.estsh.i3plus.core.api.iservice.busi; import cn.estsh.i3plus.pojo.platform.bean.SysUserPassword; import cn.estsh.impp.framework.base.service.ICrudService; +import io.swagger.annotations.ApiOperation; import java.util.List; @@ -14,4 +15,16 @@ import java.util.List; **/ public interface ISysUserPasswordService extends ICrudService { + /** + * 修改用户密码 + * @param userId 用户ID + * @param password 旧密码 + * @param newPwd 新密码 + */ + @ApiOperation(value = "修改用户密码") + void updatePassword(Long userId,String password,String newPwd); + + @ApiOperation(value = "重置用户密码") + void updatePassword(Long userId,String password); + } 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 fc4655e..8df4140 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 @@ -58,7 +58,7 @@ public interface ISysUserService { * @param sysUser */ @ApiOperation(value = "修改账号信息",notes = "修改账号信息") - void updateSysUser(SysUser sysUser) throws Exception; + void updateSysUser(SysUser sysUser); /** * 修改账号密码 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 2a7991f..a7d4527 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 @@ -150,7 +150,6 @@ public class WhiteController extends CoreBaseController { LOGGER.info("用户登陆 loginName:{} loginPwd:{} languageCode:{}",loginName,loginPwd,languageCode); ResultBean result = null; - Exception userLoginException = null; CommonEnumUtil.USER_LOGIN_STATUS userLoginStatus = CommonEnumUtil.USER_LOGIN_STATUS.LOGIN_SUCCESS; try { @@ -173,25 +172,16 @@ public class WhiteController extends CoreBaseController { recordSysUserLog(user.getUser().getUserInfoId(), loginName,CommonEnumUtil.USER_LOGIN_STATUS.LOGIN_SUCCESS.getValue(), ipAddr); AuthUtil.setOrganize(user.getUser().getOrganize()); } catch (IncorrectCredentialsException e) { - // 密码错误 - Integer num = systemLoginService.doLoginPasswordError(loginName, ipAddr); - num = CommonConstWords.USER_LOGIN_ERROR_MAX_NUM - num; result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_PASSWORD); - if(num == 0){ - result.setErrorMsg("密码输入错误。用户已被锁定请联系管理员!"); - }else { - result.setErrorMsg("密码输入错误。再输入错误"+ num +"次,用户将被锁定。"); - } + userPasswordUtil.checkLoginErrorNumber(loginName,result,e); userLoginStatus = CommonEnumUtil.USER_LOGIN_STATUS.WRONG_PASSWORD; - userLoginException = e; } catch (CredentialsException e) { // 用户名或密码错误 result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_NAME); // 记录登录记录 userLoginStatus = CommonEnumUtil.USER_LOGIN_STATUS.WRONG_USERNAME_OR_PASSWORD; - userLoginException = e; } catch (LockedAccountException e) { // 账号已锁定 result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_LOCKING); @@ -216,7 +206,6 @@ public class WhiteController extends CoreBaseController { // 记录登录记录 userLoginStatus = CommonEnumUtil.USER_LOGIN_STATUS.SYSTEM_ERROR; - userLoginException = e; } catch (Exception e) { result = ResultBean.fail(e.getMessage()).setCode(ImppExceptionEnum.SYSTEM_EXCEPTION.getCode()) .setErrorMsg(LocaleUtils.getEnumLocaleResDesc(ImppExceptionEnum.SYSTEM_EXCEPTION, ImppExceptionEnum.SYSTEM_EXCEPTION.getDescription())); @@ -226,7 +215,6 @@ public class WhiteController extends CoreBaseController { }finally { // 记录登录记录 recordSysUserLog(null, loginName,userLoginStatus.getValue(), ipAddr); - userPasswordUtil.checkLoginErrorNumber(loginName,result,userLoginException); } LOGGER.info("会员{}登陆登录完成 , 登录耗时:{}",loginName,(System.currentTimeMillis() - startTime)); 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 619b683..f31f3a4 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 @@ -1,6 +1,7 @@ package cn.estsh.i3plus.core.apiservice.controller.busi; import cn.estsh.i3plus.core.api.iservice.busi.*; +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.EncryptTool; @@ -70,6 +71,9 @@ public class PersonnelController extends CoreBaseController { @Autowired private ISysDepartmentService departmentService; + @Autowired + private SysUserPasswordUtil userPasswordUtil; + /** * 添加用户信息 * @param model 用户信息 @@ -86,7 +90,7 @@ public class PersonnelController extends CoreBaseController { SysUserInfo info = model.getSysUserInfo(); checkUserDetailModel(model, false); - personnelService.checkSysUserPassword(model.getUserLoginPassword()); + userPasswordUtil.checkPasswordSave(user); personnelService.checkSysUserOnly(user); if (StringUtils.isBlank(info.getUserJoinDate())) { @@ -163,7 +167,6 @@ public class PersonnelController extends CoreBaseController { SysUserInfo info = model.getSysUserInfo(); checkUserDetailModel(model, true); - personnelService.checkSysUserPassword(model.getUserLoginPassword()); personnelService.checkSysUserOnly(user); SysUserInfo userInfo = personnelService.getSysUserInfoById(info.getId()); @@ -226,11 +229,6 @@ public class PersonnelController extends CoreBaseController { // 关系 刷新 refreshRef(sysUser, userInfo, model); - // 更新 密码 - if(StringUtils.isNotBlank(user.getUserLoginPassword())){ - sysUser.setUserLoginPassword(user.getUserLoginPassword()); - refreshSysUserPassword(sysUser); - } personnelService.saveSysUser(sysUser); personnelService.saveSysUserInfo(userInfo); @@ -252,12 +250,9 @@ public class PersonnelController extends CoreBaseController { @ApiOperation(value = "修改用户信息", notes = "返回内容添加用户信息") public ResultBean updateUserModel(UserDetailModel model) { try { - startMultiService(); - checkUserModel(model); SysUser user = personnelService.getSysUserById(Long.parseLong(model.getUserId())); initUser(model, user); - personnelService.checkSysUserPassword(model.getUserLoginPassword()); personnelService.checkSysUserOnly(user); SysDepartment userDepartment = departmentService.get(Long.parseLong(model.getUserDepartmentId())); 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 1d2819f..11013fc 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 @@ -1,6 +1,7 @@ package cn.estsh.i3plus.core.apiservice.controller.busi; import cn.estsh.i3plus.core.api.iservice.busi.*; +import cn.estsh.i3plus.core.apiservice.util.SysUserPasswordUtil; import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.tool.EncryptTool; import cn.estsh.i3plus.platform.common.tool.StringTool; @@ -60,6 +61,9 @@ public class SysUserController extends CoreBaseController{ @Autowired private ICoreMemTreeService coreMemTreeService; + @Autowired + private ISysUserPasswordService userPasswordService; + /** * 新增系统用户 * @param sysUser 用户 @@ -250,17 +254,12 @@ public class SysUserController extends CoreBaseController{ @ApiOperation(value = "修改密码", notes = "修改当前登录用户密码") public ResultBean updateSysUserPassword(String password,String newPwd) { try { - startMultiService(); - SessionUser sessionUser = AuthUtil.getSessionUser(); // 数据校验 ValidatorBean.checkNotNull(password, "旧密码不能为空"); ValidatorBean.checkNotNull(newPwd, "新密码不能为空"); - personnelService.checkSysUserPassword(newPwd); - - sysUserService.updateSysUserPassword(sessionUser.getUser().getId(),password,newPwd.trim()); - + userPasswordService.updatePassword(sessionUser.getUser().getId(),password,newPwd.trim()); return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); } catch(ImppBusiException busExcep){ return ResultBean.fail(busExcep); @@ -420,8 +419,7 @@ public class SysUserController extends CoreBaseController{ String password = RandomStringUtils.random(6, true, false); - user.setUserLoginPassword(EncryptTool.hexMD5(password)); - sysUserService.updateSysUser(user); + userPasswordService.updatePassword(user.getId(),password); String content = "系统提示:\n" + "\t"+getSessionUser().getUserName()+"使用密码重置功能帮您重置了【"+user.getUserLoginName()+"】账号的密码," + @@ -503,54 +501,54 @@ public class SysUserController extends CoreBaseController{ return ImppExceptionBuilder.newInstance().buildExceptionResult(e); } } - - /** - * 通过邮箱的验证码修改密码 - * @param password 新密码 - * @param email 邮箱 - * @param verification 验证码不能为空 - * @return 处理结果 - */ - @PostMapping("/password/update-verification") - @ApiOperation(value = "修改密码",notes = "通过邮箱的验证码修改密码") - public ResultBean getEmailVerification(String password,String email,String verification){ - try { - ValidatorBean.checkNotNull(verification,"验证码不能为空"); - ValidatorBean.checkNotNull(password,"新密码不能为空"); - ValidatorBean.checkNotNull(email,"邮件不能为空"); - - personnelService.checkSysUserPassword(password); - - String redisKey = CommonConstWords.SESSION_VERIFICATION_USER_EMAIL + "_" + getSessionUser().getUserId(); - Object redisValue = redisCore.getObject(redisKey); - if(redisValue != null){ - if(redisValue.toString().indexOf(verification) >= 0 ){ - if(redisValue.toString().indexOf(email) >= 0 ){ - SysUser user = sysUserService.getSysUserByEmail(email); - user.setUserLoginPassword(EncryptTool.hexMD5(password)); - sysUserService.updateSysUser(user); - return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); - }else { - return ResultBean.fail("操作失败") - .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) - .setErrorMsg("请勿修改邮箱信息"); - } - }else { - return ResultBean.fail("操作失败") - .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) - .setErrorMsg("验证码错误请重新输入"); - } - }else { - return ResultBean.fail("操作失败") - .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) - .setErrorMsg("验证码已过期"); - } - } catch (ImppBusiException busExcep) { - return ResultBean.fail(busExcep); - } catch (Exception e) { - return ImppExceptionBuilder.newInstance().buildExceptionResult(e); - } - } +// TODO 密码待修复 +// /** +// * 通过邮箱的验证码修改密码 +// * @param password 新密码 +// * @param email 邮箱 +// * @param verification 验证码不能为空 +// * @return 处理结果 +// */ +// @PostMapping("/password/update-verification") +// @ApiOperation(value = "修改密码",notes = "通过邮箱的验证码修改密码") +// public ResultBean getEmailVerification(String password,String email,String verification){ +// try { +// ValidatorBean.checkNotNull(verification,"验证码不能为空"); +// ValidatorBean.checkNotNull(password,"新密码不能为空"); +// ValidatorBean.checkNotNull(email,"邮件不能为空"); +// +// personnelService.checkSysUserPassword(password); +// +// String redisKey = CommonConstWords.SESSION_VERIFICATION_USER_EMAIL + "_" + getSessionUser().getUserId(); +// Object redisValue = redisCore.getObject(redisKey); +// if(redisValue != null){ +// if(redisValue.toString().indexOf(verification) >= 0 ){ +// if(redisValue.toString().indexOf(email) >= 0 ){ +// SysUser user = sysUserService.getSysUserByEmail(email); +// user.setUserLoginPassword(EncryptTool.hexMD5(password)); +// sysUserService.updateSysUser(user); +// return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); +// }else { +// return ResultBean.fail("操作失败") +// .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) +// .setErrorMsg("请勿修改邮箱信息"); +// } +// }else { +// return ResultBean.fail("操作失败") +// .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) +// .setErrorMsg("验证码错误请重新输入"); +// } +// }else { +// return ResultBean.fail("操作失败") +// .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()) +// .setErrorMsg("验证码已过期"); +// } +// } catch (ImppBusiException busExcep) { +// return ResultBean.fail(busExcep); +// } catch (Exception e) { +// return ImppExceptionBuilder.newInstance().buildExceptionResult(e); +// } +// } /** * 修改用户操作组织id diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/mq/MdmDataSyncQueueReceiver.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/mq/MdmDataSyncQueueReceiver.java index b3300c8..0637367 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/mq/MdmDataSyncQueueReceiver.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/mq/MdmDataSyncQueueReceiver.java @@ -1,34 +1,34 @@ -package cn.estsh.i3plus.core.apiservice.mq; - -import cn.estsh.i3plus.core.apiservice.serviceimpl.mdm.SysToolSyncDataService; -import cn.estsh.i3plus.pojo.mdm.bean.busi.core.MdmGearCoreBusiExtd; -import com.rabbitmq.client.Channel; -import org.springframework.amqp.core.Message; -import org.springframework.amqp.rabbit.annotation.RabbitListener; -import org.springframework.stereotype.Component; - -import static cn.estsh.i3plus.platform.common.util.MdmConstWords.QUEUE_MDM_SYNC_DATA_CORE; - -/** - * @Description : - * @Reference : - * @Author : yunhao - * @CreateDate : 2020-05-28 16:54 - * @Modify: - **/ -@Component -public class MdmDataSyncQueueReceiver extends BaseMdmDataSyncQueueReceiver { - - /** - * 初始化类关系 - */ - public MdmDataSyncQueueReceiver() { - putMdmDataRef(SysToolSyncDataService.class, MdmGearCoreBusiExtd.mdmMasterClass, MdmGearCoreBusiExtd.class); - } - - @Override - @RabbitListener(queues = QUEUE_MDM_SYNC_DATA_CORE) - public void syncMasterData(String syncDataStr, Channel channel, Message message) { - processSyncMasterData(syncDataStr, channel, message); - } -} +//package cn.estsh.i3plus.core.apiservice.mq; +// +//import cn.estsh.i3plus.core.apiservice.serviceimpl.mdm.SysToolSyncDataService; +//import cn.estsh.i3plus.pojo.mdm.bean.busi.core.MdmGearCoreBusiExtd; +//import com.rabbitmq.client.Channel; +//import org.springframework.amqp.core.Message; +//import org.springframework.amqp.rabbit.annotation.RabbitListener; +//import org.springframework.stereotype.Component; +// +//import static cn.estsh.i3plus.platform.common.util.MdmConstWords.QUEUE_MDM_SYNC_DATA_CORE; +// +///** +// * @Description : +// * @Reference : +// * @Author : yunhao +// * @CreateDate : 2020-05-28 16:54 +// * @Modify: +// **/ +//@Component +//public class MdmDataSyncQueueReceiver extends BaseMdmDataSyncQueueReceiver { +// +// /** +// * 初始化类关系 +// */ +// public MdmDataSyncQueueReceiver() { +// putMdmDataRef(SysToolSyncDataService.class, MdmGearCoreBusiExtd.mdmMasterClass, MdmGearCoreBusiExtd.class); +// } +// +// @Override +// @RabbitListener(queues = QUEUE_MDM_SYNC_DATA_CORE) +// public void syncMasterData(String syncDataStr, Channel channel, Message message) { +// processSyncMasterData(syncDataStr, channel, message); +// } +//} diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SystemLoginService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SystemLoginService.java index 9f39965..e52716b 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SystemLoginService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SystemLoginService.java @@ -1,7 +1,9 @@ package cn.estsh.i3plus.core.apiservice.serviceimpl.base; import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService; +import cn.estsh.i3plus.core.api.iservice.busi.ISysUserPasswordService; import cn.estsh.i3plus.core.apiservice.util.SysUserPasswordUtil; +import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.tool.EncryptTool; import cn.estsh.i3plus.platform.common.util.CommonConstWords; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; @@ -10,22 +12,29 @@ import cn.estsh.i3plus.pojo.base.shirotoken.SaAdminToken; import cn.estsh.i3plus.pojo.base.shirotoken.UserToken; import cn.estsh.i3plus.pojo.platform.bean.SessionUser; import cn.estsh.i3plus.pojo.platform.bean.SysUser; +import cn.estsh.i3plus.pojo.platform.bean.SysUserPassword; import cn.estsh.i3plus.pojo.platform.repository.SysUserRepository; import cn.estsh.impp.framework.boot.auth.AuthUtil; import cn.estsh.impp.framework.boot.util.ImppLdapUtils; import cn.estsh.impp.framework.boot.util.ImppRedis; import cn.estsh.impp.framework.boot.util.ImppSwitchUtil; +import cn.estsh.impp.framework.boot.util.ValidatorBean; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; import org.apache.shiro.authc.CredentialsException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.LockedAccountException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.util.Objects; /** * @Description : 用户登陆方法 @@ -41,9 +50,14 @@ public class SystemLoginService implements ISystemLoginService { @Autowired private SysUserRepository sysUserRDao; + @Lazy @Autowired private SysUserPasswordUtil userPasswordUtil; + @Lazy + @Autowired + private ISysUserPasswordService passwordService; + /** * 核心的缓存 */ @@ -125,33 +139,55 @@ public class SystemLoginService implements ISystemLoginService { public SysUser getUserLoginInfo(String loginName,String pwd) { SysUser user = sysUserRDao.getByProperty( new String[]{"userLoginName","isValid"}, - new Object[]{loginName,CommonEnumUtil.IS_VAILD.VAILD.getValue()} - ); + new Object[]{loginName,CommonEnumUtil.IS_VAILD.VAILD.getValue()}); + if(user == null){ //用户不存在 throw new CredentialsException("用户不存在"); - }else { - if(user.getUserStatus() != CommonEnumUtil.USER_STATUS.ENABLE.getValue()){ - throw new LockedAccountException("账号已被锁定"); - } - try { - // 密码加密 - pwd = EncryptTool.hexMD5(pwd); - } catch (Exception e) { - LOGGER.error("登录密码加密出错。"); - throw new IncorrectCredentialsException("登陆密码错误"); - } + } + + if(user.getUserStatus() != CommonEnumUtil.USER_STATUS.ENABLE.getValue()){ + throw new LockedAccountException("账号已被锁定"); + } - // 登录AD 域检查 + // 登录AD 域检查 + if(ImppSwitchUtil.isLoginActiveDirectory()){ userPasswordUtil.checkActiveDirectory(user); + return user; + } - // 登录密码校验 - if (!StringUtils.equals(user.getUserLoginPassword(), pwd)) { //密码不符 - LOGGER.error("密码验证错误。"); - throw new IncorrectCredentialsException("登陆密码错误"); + SysUserPassword password = null; + String passwordStr = user.getUserLoginPassword(); + try { + if(Objects.nonNull(user.getUserLoginPasswordId()) && user.getUserLoginPasswordId() > 0){ + password = passwordService.get(user.getUserLoginPasswordId()); + }else{ + if(StringUtils.equals(user.getUserLoginPassword(),SysUserPasswordUtil.encoder(pwd))){ + SysUserPassword userPassword = new SysUserPassword(user.getId(), SysUserPasswordUtil.encoder(pwd)); + ConvertBean.serviceModelInitialize(userPassword,user.getUserName()); + password = passwordService.insert(userPassword); + + user.setUserLoginPassword(null); + user.setUserLoginPasswordId(password.getId()); + + sysUserRDao.save(user); + } + } + + if(Objects.nonNull(password)){ + passwordStr = password.getUserPassword(); } - return user; + if (StringUtils.equals(passwordStr,SysUserPasswordUtil.encoder(pwd))){ + return user; + } + LOGGER.error("密码验证错误。"); + } catch (Exception e) { + LOGGER.error("登录密码加密出错[Exception]"); } + + throw new IncorrectCredentialsException("登陆密码错误"); + + } /** 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 5b354d2..2bf98c3 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 @@ -5,6 +5,7 @@ import cn.estsh.i3plus.core.api.iservice.busi.*; import cn.estsh.i3plus.core.apiservice.util.HqlModelPack; import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; import cn.estsh.i3plus.platform.common.tool.StringTool; +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.bean.ListPager; @@ -22,6 +23,7 @@ import cn.estsh.i3plus.pojo.platform.sqlpack.CoreHqlPack; 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 io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -673,22 +675,22 @@ public class PersonnelServiceService implements IPersonnelService { public Integer checkSysUserResetPassword(SysUser user) { LOGGER.info("平台用户岗位 SysUser user:{}", user); Integer num = 0; -// if(user != null){ -// String day = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.format(new Date()); -// String redisKey = CommonConstWords.REDIS_PREFIX_USER_RESET_PASSWORD + "-" + day + "-" + user.getId(); -// Object redisValue = redisCore.getObject(redisKey); -// num = redisValue == null ? 1 : Integer.parseInt(redisValue.toString()) + 1; -// -// if(num > CommonConstWords.LOCK_USER_RESET_PASSWORD){ -// throw ImppExceptionBuilder.newInstance() -// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) -// .setErrorCode(ImppExceptionEnum.USER_PERMISSION_RUN_OUT.getCode()) -// .setErrorDetail("重置密码次数已使用完毕") -// .setErrorSolution("请明日再次使用") -// .build(); -// } -// redisCore.putObject(redisKey,num,CommonConstWords.REDIS_TIME_DAY_ONE); -// } + if(user != null){ + String redisKey = CommonConstWords.REDIS_PREFIX_USER_RESET_PASSWORD + ":" + TimeTool.getToday() + ":" + user.getId(); + Object redisValue = redisCore.getObject(redisKey); + num = redisValue == null ? 1 : Integer.parseInt(redisValue.toString()) + 1; + + int numMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_RESET_PASSWORD, CommonConstWords.CONFIG_PWD_RESET_PASSWORD_DEFAULT); + if(num > numMax){ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.USER_PERMISSION_RUN_OUT.getCode()) + .setErrorDetail("重置密码次数已使用完毕") + .setErrorSolution("请明日再次使用") + .build(); + } + redisCore.putObject(redisKey,num,CommonConstWords.REDIS_TIME_DAY_ONE); + } return num; } @@ -826,77 +828,77 @@ public class PersonnelServiceService implements IPersonnelService { } } - @Override - public void checkSysUserPassword(String password) { - LOGGER.info("平台用户 SysUser password:{}", password); - - if(StringUtils.isNotBlank(password)){ - // 密码长度校验 - String redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_LENGTH; - SysConfig config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); - - if(!checkPasswordLength(config,password)){ - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("密码长度不够"+config.getConfigValue()+"位") - .setErrorSolution("请重新输入") - .build(); - } - - // 密码小写校验 - redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_LOWER_ENGLISH; - config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); - - if(!checkPasswordLowerEnglish(config,password)){ - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("密码必须包含小写英文") - .setErrorSolution("请重新输入") - .build(); - } - - // 密码大写校验 - redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_UPPERCASE_ENGLISH; - config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); - - if(!checkPasswordUpperEnglish(config,password)){ - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("密码必须包含大写英文") - .setErrorSolution("请重新输入") - .build(); - } - - // 密码特殊字符 - redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_SPECIAL_CHAR; - config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); - - if(!checkPasswordSpecialChar(config,password)){ - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("密码必须包含特殊字符") - .setErrorSolution("请重新输入") - .build(); - } - - // 密码特殊字符 - redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_NUMBER; - config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); - - if(!checkPasswordNumber(config,password)){ - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) - .setErrorDetail("密码必须包含数字") - .setErrorSolution("请重新输入") - .build(); - } - } - } +// @Override +// public void checkSysUserPassword(String password) { +// LOGGER.info("平台用户 SysUser password:{}", password); +// +// if(StringUtils.isNotBlank(password)){ +// // 密码长度校验 +// String redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_LENGTH; +// SysConfig config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); +// +// if(!checkPasswordLength(config,password)){ +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("密码长度不够"+config.getConfigValue()+"位") +// .setErrorSolution("请重新输入") +// .build(); +// } +// +// // 密码小写校验 +// redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_LOWER_ENGLISH; +// config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); +// +// if(!checkPasswordLowerEnglish(config,password)){ +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("密码必须包含小写英文") +// .setErrorSolution("请重新输入") +// .build(); +// } +// +// // 密码大写校验 +// redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_UPPERCASE_ENGLISH; +// config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); +// +// if(!checkPasswordUpperEnglish(config,password)){ +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("密码必须包含大写英文") +// .setErrorSolution("请重新输入") +// .build(); +// } +// +// // 密码特殊字符 +// redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_SPECIAL_CHAR; +// config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); +// +// if(!checkPasswordSpecialChar(config,password)){ +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("密码必须包含特殊字符") +// .setErrorSolution("请重新输入") +// .build(); +// } +// +// // 密码特殊字符 +// redisKey = CommonConstWords.REDIS_PREFIX_CACHE_CONFIG + "_" + CommonConstWords.CONFIG_PWD_EXIST_NUMBER; +// config = (SysConfig) systemInitService.getDataFromCache(redisKey, SysConfig.class); +// +// if(!checkPasswordNumber(config,password)){ +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) +// .setErrorDetail("密码必须包含数字") +// .setErrorSolution("请重新输入") +// .build(); +// } +// } +// } // @Override // public void refreshUpdateMenuRdd(Long menuId) { 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 fc5f6fc..3388760 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 @@ -1,14 +1,28 @@ package cn.estsh.i3plus.core.apiservice.serviceimpl.busi; import cn.estsh.i3plus.core.api.iservice.busi.ISysUserPasswordService; +import cn.estsh.i3plus.core.api.iservice.busi.ISysUserService; +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.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.jpa.dao.BaseRepository; +import cn.estsh.i3plus.pojo.platform.bean.SysUser; import cn.estsh.i3plus.pojo.platform.bean.SysUserPassword; 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.ValidatorBean; +import org.apache.commons.collections.CollectionUtils; +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 java.util.List; + /** * @Description : * @Reference : @@ -23,10 +37,53 @@ public class SysUserSavePasswordService extends CrudService imp @Autowired private SysUserPasswordRepository userPasswordRDao; + @Autowired + private ISysUserService userService; @Override public BaseRepository getRepository() { return userPasswordRDao; } + @Override + public void updatePassword(Long userId, String password, String newPwd) { + SysUser user = userService.getSysUserById(userId); + ValidatorBean.checkNotNull(user,"不存在的用户信息"); + + SysUserPassword userPassword = userPasswordRDao.getById(user.getUserLoginPasswordId()); + ValidatorBean.checkNotNull(userPassword,"不存在的用户密码信息"); + if(StringUtils.equals(userPassword.getUserPassword(),password)){ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("原始密码错误") + .setErrorSolution("请重新操作") + .build(); + } + + updatePassword(userId, newPwd); + } + + @Override + public void updatePassword(Long userId, String password) { + SysUser user = userService.getSysUserById(userId); + ValidatorBean.checkNotNull(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()}); + + SysUserPassword pwd = new SysUserPassword(); + pwd.setUserId(userId); + pwd.setUserPassword(SysUserPasswordUtil.encoder(password)); + ConvertBean.serviceModelInitialize(pwd,AuthUtil.getSessionUser()); + SysUserPassword save = userPasswordRDao.save(pwd); + + user.setUserLoginPasswordId(save.getId()); + ConvertBean.serviceModelUpdate(user,AuthUtil.getSessionUser().getUserName()); + userService.updateSysUser(user); + } } 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 d03048c..980ae07 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 @@ -2,6 +2,7 @@ package cn.estsh.i3plus.core.apiservice.serviceimpl.busi; import cn.estsh.i3plus.core.api.iservice.busi.*; import cn.estsh.i3plus.core.apiservice.dao.IUserPermissionDao; +import cn.estsh.i3plus.core.apiservice.util.SysUserPasswordUtil; import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.tool.EncryptTool; import cn.estsh.i3plus.platform.common.tool.StringTool; @@ -26,6 +27,7 @@ import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; 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 io.swagger.annotations.ApiOperation; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -122,6 +124,11 @@ public class SysUserService implements ISysUserService { @Autowired private ISysFileService fileService; + @Autowired + private SysUserPasswordUtil passwordUtil; + + @Autowired ISysUserPasswordService userPasswordService; + @Resource(name = CommonConstWords.IMPP_REDIS_RES) private ImppRedis redisRes; @@ -207,7 +214,7 @@ public class SysUserService implements ISysUserService { @Override @ApiOperation(value = "修改账号", notes = "修改账号信息") - public void updateSysUser(SysUser sysUser) throws Exception{ + public void updateSysUser(SysUser sysUser) { LOGGER.debug("平台用户 SYS_USER SysUser :{}", sysUser); userRDao.save(sysUser); } @@ -217,27 +224,35 @@ public class SysUserService implements ISysUserService { public void updateSysUserPassword(Long userId, String password, String newPwd) throws Exception { LOGGER.debug("平台用户 SYS_USER Override:{} password:{} newPwd:{}", userId,password,newPwd); SysUser user = userRDao.getById(userId); - if(user != null){ - String pwdMd5 = EncryptTool.hexMD5(password); - if(pwdMd5.equals(user.getUserLoginPassword())){ - user.setUserLoginPassword(EncryptTool.hexMD5(newPwd)); - userRDao.save(user); - }else { - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) - .setErrorDetail("旧密码错误") - .setErrorSolution("请重新输入") - .build(); - } - }else { - throw ImppExceptionBuilder.newInstance() - .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) - .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode()) - .setErrorDetail("用户不存在") - .setErrorSolution("请重新操作") - .build(); - } + ValidatorBean.checkNotNull(user,"用户不存在"); + + user.setUserLoginPassword(newPwd); + passwordUtil.checkPasswordSave(user); + + userPasswordService.update(null); + + +// if(user != null){ +// String pwdMd5 = EncryptTool.hexMD5(password); +// if(pwdMd5.equals(user.getUserLoginPassword())){ +// user.setUserLoginPassword(EncryptTool.hexMD5(newPwd)); +// userRDao.save(user); +// }else { +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) +// .setErrorDetail("旧密码错误") +// .setErrorSolution("请重新输入") +// .build(); +// } +// }else { +// throw ImppExceptionBuilder.newInstance() +// .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) +// .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode()) +// .setErrorDetail("用户不存在") +// .setErrorSolution("请重新操作") +// .build(); +// } } @Override 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 new file mode 100644 index 0000000..0b7f1d8 --- /dev/null +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/SysUserPasswordUtil.java @@ -0,0 +1,505 @@ +package cn.estsh.i3plus.core.apiservice.util; + +import cn.estsh.i3plus.core.api.iservice.busi.ISysUserPasswordService; +import cn.estsh.i3plus.core.api.iservice.busi.ISysUserService; +import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; +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.SysUser; +import cn.estsh.i3plus.pojo.platform.bean.SysUserPassword; +import cn.estsh.impp.framework.boot.exception.ImppBusiException; +import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; +import cn.estsh.impp.framework.boot.util.*; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.naming.NamingException; +import javax.naming.ldap.LdapContext; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Objects; +import java.util.regex.Pattern; + +/** + * @Description : + * @Reference : + * @Author : wei.peng + * @CreateDate : 20-6-8 上午10:10 + * @Modify: + **/ +@Component +public class SysUserPasswordUtil { + public static final Logger LOGGER = LoggerFactory.getLogger(SysUserPasswordUtil.class); + + @Autowired + private ISysUserPasswordService userPasswordService; + + @Lazy + @Autowired + private ISysUserService userService; + + @Resource(name = CommonConstWords.IMPP_REDIS_CORE) + protected ImppRedis redisCore; + + /** + * 密码加密 返回加密信息 + * @param password + * @return + */ + public static final String encoder(String password){ + try { + return EncryptTool.hexMD5(password); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("密码加密失败") + .setErrorSolution("请重新操作") + .build(); + } + + /******************************************** 用户保存密码检查 ********************************************/ + + public void checkPasswordSave(SysUser user) { + /* 密码 长度校验 */ + checkPasswordLength(user.getUserLoginPassword()); + /* 密码 大写字母校验 */ + checkPasswordUppercaseEnglish(user.getUserLoginPassword()); + /* 密码 小写字母校验 */ + checkPasswordlowerEnglish(user.getUserLoginPassword()); + /* 密码 数字校验 */ + checkPasswordNumber(user.getUserLoginPassword()); + /* 密码 特殊字符校验 */ + checkPasswordSpecial(user.getUserLoginPassword()); + /* 密码 重复使用校验 */ + checkPasswordRepeatDay(user); + /* 密码 密码正则校验 */ + checkPasswordRepeat(user.getUserLoginPassword()); + } + + /** + * 密码长度检查 + * + * @param content + */ + private void checkPasswordLength(String content) { + int length = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_LENGTH, CommonConstWords.CONFIG_PWD_LENGTH_DEFAULT); + + if (StringUtils.isBlank(content) || StringUtils.length(content) < length) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("长度不够" + length + "位") + .setErrorSolution("请重新输入") + .build(); + } + } + + /** + * 密码 大写字母检查 + * + * @param content + */ + private void checkPasswordUppercaseEnglish(String content) { + boolean isUppercaseEnglish = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXIST_UPPERCASE_ENGLISH, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + + if (StringUtils.isNotBlank(content) && isUppercaseEnglish) { + char[] chars = content.toCharArray(); + int num = 0; + + for (char ch : chars) { + // Chart ASCLL 编码比对 A-Z + if (ch >= 65 && ch <= 90) { + ++num; + } + } + + if (num <= 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("必须包含大写英文") + .setErrorSolution("请重新输入") + .build(); + } + } + } + + /** + * 密码 小写字母检查 + * + * @param content + */ + private void checkPasswordlowerEnglish(String content) { + boolean isUppercaseEnglish = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXIST_LOWER_ENGLISH, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + + if (StringUtils.isNotBlank(content) && isUppercaseEnglish) { + char[] chars = content.toCharArray(); + int num = 0; + + for (char ch : chars) { + // Chart ASCLL 编码比对 a-z + if (ch >= 97 && ch <= 122) { + ++num; + } + } + + if (num <= 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("必须包含小写英文") + .setErrorSolution("请重新输入") + .build(); + } + } + } + + /** + * 密码 数字检查 + * + * @param content + */ + private void checkPasswordNumber(String content) { + boolean isUppercaseEnglish = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXIST_NUMBER, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + + if (StringUtils.isNotBlank(content) && isUppercaseEnglish) { + char[] chars = content.toCharArray(); + int num = 0; + + for (char ch : chars) { + // Chart ASCLL 编码比对 0-9 + if (ch >= 48 && ch <= 57) { + ++num; + } + } + + if (num <= 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("必须包含数字") + .setErrorSolution("请重新输入") + .build(); + } + } + } + + /** + * 密码 特殊字符检查 + * + * @param content + */ + private void checkPasswordSpecial(String content) { + boolean isUppercaseEnglish = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXIST_NUMBER, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + + if (StringUtils.isNotBlank(content) && isUppercaseEnglish) { + char[] chars = content.toCharArray(); + int num = 0; + + for (char ch : chars) { + // Chart ASCLL 编码比对 特殊字符 + if ((ch >= 32 && ch <= 47)|| (ch >= 58 && ch <= 64)|| + (ch >= 91 && ch <= 96)|| (ch >= 123 && ch <= 126)) { + ++num; + } + } + + if (num <= 0) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("必须包含数字") + .setErrorSolution("请重新输入") + .build(); + } + } + } + + /** + * 密码 中文字符检查 + * + * @param content + */ + private void checkPasswordSpecialCn(String content) { + boolean isUppercaseEnglish = RedisCacheTool.getSysConfigBooleanVal(CommonConstWords.CONFIG_PWD_EXIST_SPECIAL_CHAR, CommonEnumUtil.TRUE_OR_FALSE.FALSE); + + if (StringUtils.isNotBlank(content) && isUppercaseEnglish) { + if (!Pattern.compile("[\u4e00-\u9fa5]").matcher(content).find()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("必须包含中文字符") + .setErrorSolution("请重新输入") + .build(); + } + } + } + + /** + * 近期密码重复检查 + * + * @param user + */ + private void checkPasswordRepeatDay(SysUser user) { + int num = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_PWD_REPEAT_DAY, CommonConstWords.CONFIG_PWD_REPEAT_DAY_DEFAULT); + if (num > 0) { + try { + SysUserPassword userPassword = new SysUserPassword(); + userPassword.setUserId(user.getId()); + userPassword.setUserPassword(EncryptTool.hexMD5(user.getUserLoginPassword())); + + List passwords = userPasswordService.findAllByBean(userPassword); + + int lastDay = Integer.MAX_VALUE; + if (CollectionUtils.isNotEmpty(passwords)) { + for (SysUserPassword password : passwords) { + int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true)); + if (day < lastDay) { + lastDay = day; + } + } + } + + if (lastDay <= num) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("请勿使用重复密码") + .setErrorSolution("请重新输入") + .build(); + } + } catch (Exception e) { + e.printStackTrace(); + LOGGER.error("密码加密错误,异常信息:{}", e.getMessage()); + } + } + } + + /** + * 密码 正则表达式教研 + * + * @param content + */ + private void checkPasswordRepeat(String content) { + String regulars = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_PWD_REPEAT_REGULARS); + + if (StringUtils.isNotBlank(regulars) && regulars.indexOf(",") != -1) { + String[] split = regulars.split(","); + + try { + for (String compile : split) { + if(StringUtils.isNotBlank(compile)){ + if (!Pattern.compile(compile).matcher(content).find()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("正则【"+compile+"】密码校验不通过") + .setErrorSolution("请重新输入") + .build(); + } + } + } + }catch (ImppBusiException e){ + // 业务异常 抛出 + throw e; + }catch (Exception e){ + e.printStackTrace(); + } + } + } + + + + /******************************************** 用户登录密码检查 ********************************************/ + public void checkSysUserLogin(SysUser user) { + if(ImppSwitchUtil.isLoginActiveDirectory()){ + // 使用AD域账号登录 + checkActiveDirectory(user); + }else{ + /* 检查密码有效期 */ + checkLoginPasswordTimeOut(user); + /* 登录 长时间未登录锁定 */ + checkLoginTimeOut(user); + } + } + + /** + * 账号 ActiveDirectory 登录集成 + * @param user + */ + public void checkActiveDirectory(SysUser user) { + if(ImppSwitchUtil.isLoginActiveDirectory()){ + String activeDirectoryUrl = RedisCacheTool.getSysConfigStrVal(CommonConstWords.CONFIG_PWD_ACTIVE_DIRECTORY_URL); + + if (StringUtils.isNotBlank(activeDirectoryUrl)) { + LdapContext context = ImppLdapUtils.getLdapContext(activeDirectoryUrl, user.getUserLoginName(), user.getUserLoginPassword()); + if(Objects.isNull(context)){ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("ActiveDirectory 登录失败请重新登录") + .setErrorSolution("请重新操作") + .build(); + } + + try { + // 释放链接资源 + context.close(); + } catch (NamingException e) { + e.printStackTrace(); + } + }else{ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("ActiveDirectory 未配置链接地址") + .setErrorSolution("请联系管理员") + .build(); + } + } + } + + /** + * 登录 错误次数检查 + */ + public void checkLoginErrorNumber(String loginName, ResultBean resultBean, Exception e) { + SysUser user = userService.getSysUserByLoginName(loginName); + if(Objects.nonNull(user)){ + checkLoginErrorNumber(user.getId(), resultBean, e); + } + } + + /** + * 登录 失败次数检查 + * @param userId + * @param resultBean + * @param e + */ + public void checkLoginErrorNumber(Long userId, ResultBean resultBean, Exception e) { + int loginErrorNumberMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUMBER, CommonConstWords.CONFIG_USER_LOGIN_ERROR_NUMBER_DEFAULT); + String today = TimeTool.getToday(); + + int loginErrorNumber = 0; + String redisKey = CommonConstWords.USER_LOGIN_ERROR + ":" + today + ":" + userId; + try { + Object redisValue = redisCore.getObject(redisKey); + if(Objects.nonNull(redisValue)){ + loginErrorNumber = (Integer)redisValue; + } + }catch (Exception exception){ + LOGGER.error("获取登录异常次数错误,错误信息:{}", exception.getMessage()); + } + + if(Objects.equals(loginErrorNumberMax,loginErrorNumber)){ + // 锁定账号信息 + userService.doLockSysUserById(userId); + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("账号已被锁定") + .setErrorSolution("请联系系统管理员") + .build(); + }else if(loginErrorNumber > loginErrorNumberMax){ + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("账号已锁定") + .setErrorSolution("请联系系统管理员") + .build(); + } + + // 登录异常 更新登录失败次数 + if(Objects.nonNull(e)){ + ++loginErrorNumber; + + if(Objects.nonNull(resultBean)){ + int num = loginErrorNumberMax - loginErrorNumber; + if(num == 0){ + resultBean.setErrorMsg(resultBean.getErrorMsg() + "密码输入错误。用户已被锁定请联系管理员!"); + }else{ + resultBean.setErrorMsg(resultBean.getErrorMsg() + "密码输入错误。再输入错误"+ num +"次,用户将被锁定"); + } + } + + redisCore.putObject(redisKey,loginErrorNumber,CommonConstWords.REDIS_TIME_DAY_ONE); + } + } + + /** + * 登录 检查密码有效期 + */ + private void 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)){ + int day = TimeTool.getSecoundsBetweenTime(4, password.getCreateDatetime(), TimeTool.getNowTime(true)); + if(day > passwordDayMax){ + // 锁定账号信息 + userService.doLockSysUserById(user.getId()); + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("账号密码已过期") + .setErrorSolution("请联系系统管理员") + .build(); + } + } + } + }catch (ImppBusiException e){ + throw e; + }catch (Exception e){ + LOGGER.error("密码有效期处理异常,异常信息:{}", e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 登录 长时间未登录锁定 + */ + private void checkLoginTimeOut(SysUser user) { + try { + int loginDayMax = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT, CommonConstWords.CONFIG_USER_LOGIN_DAY_OUT_DEFAULT); + if(loginDayMax > 0){ + + int day = TimeTool.getSecoundsBetweenTime(4, user.getUserLoginLastDateTime(), TimeTool.getNowTime(true)); + if(day > loginDayMax){ + // 锁定账号信息 + userService.doLockSysUserById(user.getId()); + + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.NOT_CONFIG_EXCEPTION.getCode()) + .setErrorDetail("长时间未登录账号已被锁定") + .setErrorSolution("请联系系统管理员") + .build(); + } + } + }catch (ImppBusiException e){ + throw e; + }catch (Exception e){ + LOGGER.error("密码有效期处理异常,异常信息:{}", e.getMessage()); + e.printStackTrace(); + } + } + +}