diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java b/continew-admin-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java index 0764d64a..05237f2c 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/enums/PasswordPolicyEnum.java @@ -16,9 +16,16 @@ package top.continew.admin.system.enums; +import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; import lombok.Getter; import lombok.RequiredArgsConstructor; +import top.continew.admin.common.constant.RegexConstants; import top.continew.admin.common.constant.SysConstants; +import top.continew.admin.system.model.entity.UserDO; +import top.continew.admin.system.service.UserPasswordHistoryService; +import top.continew.starter.core.util.validate.ValidationUtils; /** * 密码策略枚举 @@ -31,47 +38,110 @@ import top.continew.admin.common.constant.SysConstants; @RequiredArgsConstructor public enum PasswordPolicyEnum { - /** - * 登录密码错误锁定账号的次数 - */ - PASSWORD_ERROR_LOCK_COUNT(null, SysConstants.NO, 10), - - /** - * 登录密码错误锁定账号的时间(min) - */ - PASSWORD_ERROR_LOCK_MINUTES(null, 1, 1440), - - /** - * 密码到期提前提示(天) - */ - PASSWORD_EXPIRATION_WARNING_DAYS(null, SysConstants.NO, Integer.MAX_VALUE), - - /** - * 密码有效期(天) - */ - PASSWORD_EXPIRATION_DAYS(null, SysConstants.NO, 999), - - /** - * 密码重复使用规则 - */ - PASSWORD_REUSE_POLICY("不允许使用最近 %s 次的历史密码", 3, 32), - /** * 密码最小长度 */ - PASSWORD_MIN_LENGTH("密码最小长度为 %s 个字符", 8, 32), - - /** - * 密码是否允许包含正反序账号名 - */ - PASSWORD_ALLOW_CONTAIN_USERNAME("密码不允许包含正反序账号名", SysConstants.NO, SysConstants.YES), + PASSWORD_MIN_LENGTH("密码最小长度为 %s 个字符", 8, 32) { + @Override + public void validate(String password, int policyValue, UserDO user) { + // 最小长度校验 + ValidationUtils.throwIf(StrUtil.length(password) < policyValue, this.getDescription() + .formatted(policyValue)); + // 完整校验 + int passwordMaxLength = this.getMax(); + ValidationUtils.throwIf(!ReUtil.isMatch(RegexConstants.PASSWORD_TEMPLATE + .formatted(policyValue, passwordMaxLength), password), "密码长度为 {}-{} 个字符,支持大小写字母、数字、特殊字符,至少包含字母和数字", policyValue, passwordMaxLength); + } + }, /** * 密码是否必须包含特殊字符 */ - PASSWORD_CONTAIN_SPECIAL_CHARACTERS("密码必须包含特殊字符", SysConstants.NO, SysConstants.YES),; + PASSWORD_CONTAIN_SPECIAL_CHARACTERS("密码必须包含特殊字符", SysConstants.NO, SysConstants.YES) { + @Override + public void validate(String password, int policyValue, UserDO user) { + ValidationUtils.throwIf(policyValue == SysConstants.YES && !ReUtil + .isMatch(RegexConstants.SPECIAL_CHARACTER, password), this.getDescription()); + } + }, + + /** + * 密码是否允许包含正反序账号名 + */ + PASSWORD_ALLOW_CONTAIN_USERNAME("密码不允许包含正反序账号名", SysConstants.NO, SysConstants.YES) { + @Override + public void validate(String password, int policyValue, UserDO user) { + if (policyValue <= SysConstants.NO) { + String username = user.getUsername(); + ValidationUtils.throwIf(StrUtil.containsAnyIgnoreCase(password, username, StrUtil + .reverse(username)), this.getDescription()); + } + } + }, + + /** + * 密码重复使用规则 + */ + PASSWORD_REUSE_POLICY("不允许使用最近 %s 次的历史密码", 3, 32) { + @Override + public void validate(String password, int policyValue, UserDO user) { + UserPasswordHistoryService userPasswordHistoryService = SpringUtil + .getBean(UserPasswordHistoryService.class); + ValidationUtils.throwIf(userPasswordHistoryService.isPasswordReused(user + .getId(), password, policyValue), this.getDescription().formatted(policyValue)); + } + }, + + /** + * 登录密码错误锁定账号的次数 + */ + PASSWORD_ERROR_LOCK_COUNT(null, SysConstants.NO, 10) { + @Override + public void validate(String password, int policyValue, UserDO user) { + // 无需此处校验 + } + }, + + /** + * 登录密码错误锁定账号的时间(min) + */ + PASSWORD_ERROR_LOCK_MINUTES(null, 1, 1440) { + @Override + public void validate(String password, int policyValue, UserDO user) { + // 无需此处校验 + } + }, + + /** + * 密码到期提前提示(天) + */ + PASSWORD_EXPIRATION_WARNING_DAYS(null, SysConstants.NO, Integer.MAX_VALUE) { + @Override + public void validate(String password, int policyValue, UserDO user) { + // 无需此处校验 + } + }, + + /** + * 密码有效期(天) + */ + PASSWORD_EXPIRATION_DAYS(null, SysConstants.NO, 999) { + @Override + public void validate(String password, int policyValue, UserDO user) { + // 无需此处校验 + } + },; private final String description; private final Integer min; private final Integer max; + + /** + * 校验 + * + * @param password 密码 + * @param policyValue 策略值 + * @param user 用户信息 + */ + public abstract void validate(String password, int policyValue, UserDO user); } diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java index 504d4f5c..7b750c64 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java @@ -20,7 +20,6 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import com.alicp.jetcache.anno.CacheInvalidate; import com.alicp.jetcache.anno.CacheType; @@ -39,7 +38,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import top.continew.admin.auth.service.OnlineUserService; import top.continew.admin.common.constant.CacheConstants; -import top.continew.admin.common.constant.RegexConstants; import top.continew.admin.common.constant.SysConstants; import top.continew.admin.common.enums.DisEnableStatusEnum; import top.continew.admin.common.util.helper.LoginHelper; @@ -56,7 +54,6 @@ import top.continew.admin.system.model.resp.UserResp; import top.continew.admin.system.service.*; import top.continew.starter.core.constant.StringConstants; import top.continew.starter.core.util.validate.CheckUtils; -import top.continew.starter.core.util.validate.ValidationUtils; import top.continew.starter.extension.crud.model.query.PageQuery; import top.continew.starter.extension.crud.model.resp.PageResp; import top.continew.starter.extension.crud.service.CommonUserService; @@ -348,28 +345,16 @@ public class UserServiceImpl extends BaseServiceImpl