From 3994142ace6cd6ce9d094b8a4ceed080a2b2ec33 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Thu, 16 May 2024 23:49:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E7=AD=96=E7=95=A5-=E5=AF=86=E7=A0=81=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/UserPasswordHistoryMapper.java | 38 +++++++++++ .../admin/system/model/entity/FileDO.java | 5 -- .../model/entity/UserPasswordHistoryDO.java | 67 +++++++++++++++++++ .../admin/system/service/RoleDeptService.java | 2 +- .../admin/system/service/RoleMenuService.java | 2 +- .../service/UserPasswordHistoryService.java | 45 +++++++++++++ .../admin/system/service/UserRoleService.java | 4 +- .../admin/system/service/UserService.java | 2 +- .../impl/UserPasswordHistoryServiceImpl.java | 67 +++++++++++++++++++ .../system/service/impl/UserServiceImpl.java | 17 +++-- .../mapper/UserPasswordHistoryMapper.xml | 16 +++++ .../changelog/mysql/continew-admin_data.sql | 2 +- .../changelog/mysql/continew-admin_table.sql | 9 +++ .../postgresql/continew-admin_data.sql | 2 +- .../postgresql/continew-admin_table.sql | 14 ++++ 15 files changed, 276 insertions(+), 16 deletions(-) create mode 100644 continew-admin-system/src/main/java/top/continew/admin/system/mapper/UserPasswordHistoryMapper.java create mode 100644 continew-admin-system/src/main/java/top/continew/admin/system/model/entity/UserPasswordHistoryDO.java create mode 100644 continew-admin-system/src/main/java/top/continew/admin/system/service/UserPasswordHistoryService.java create mode 100644 continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserPasswordHistoryServiceImpl.java create mode 100644 continew-admin-system/src/main/resources/mapper/UserPasswordHistoryMapper.xml diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/mapper/UserPasswordHistoryMapper.java b/continew-admin-system/src/main/java/top/continew/admin/system/mapper/UserPasswordHistoryMapper.java new file mode 100644 index 00000000..52aa7176 --- /dev/null +++ b/continew-admin-system/src/main/java/top/continew/admin/system/mapper/UserPasswordHistoryMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.admin.system.mapper; + +import org.apache.ibatis.annotations.Param; +import top.continew.starter.data.mybatis.plus.base.BaseMapper; +import top.continew.admin.system.model.entity.UserPasswordHistoryDO; + +/** + * 用户历史密码 Mapper + * + * @author Charles7c + * @since 2024/5/16 21:58 + */ +public interface UserPasswordHistoryMapper extends BaseMapper { + + /** + * 删除过期历史密码 + * + * @param userId 用户 ID + * @param count 保留 N 个历史 + */ + void deleteExpired(@Param("userId") Long userId, @Param("count") int count); +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/FileDO.java b/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/FileDO.java index 1bdcb00e..c22eba9a 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/FileDO.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/FileDO.java @@ -17,8 +17,6 @@ package top.continew.admin.system.model.entity; import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import org.dromara.x.file.storage.core.FileInfo; @@ -43,9 +41,6 @@ public class FileDO extends BaseDO { @Serial private static final long serialVersionUID = 1L; - @TableId(type = IdType.ASSIGN_ID) - private Long id; - /** * 名称 */ diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/UserPasswordHistoryDO.java b/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/UserPasswordHistoryDO.java new file mode 100644 index 00000000..9c2e45cd --- /dev/null +++ b/continew-admin-system/src/main/java/top/continew/admin/system/model/entity/UserPasswordHistoryDO.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.admin.system.model.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 用户历史密码实体 + * + * @author Charles7c + * @since 2024/5/16 21:58 + */ +@Data +@NoArgsConstructor +@TableName("sys_user_password_history") +public class UserPasswordHistoryDO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 用户 ID + */ + private Long userId; + + /** + * 密码 + */ + private String password; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + public UserPasswordHistoryDO(Long userId, String password) { + this.userId = userId; + this.password = password; + } +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleDeptService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleDeptService.java index cb857d78..4489bf45 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleDeptService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleDeptService.java @@ -31,7 +31,7 @@ public interface RoleDeptService { * * @param deptIds 部门 ID 列表 * @param roleId 角色 ID - * @return true:成功;false:无变更/失败 + * @return 是否新增成功(true:成功;false:无变更/失败) */ boolean add(List deptIds, Long roleId); diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java index cd9b5940..3f541b79 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleMenuService.java @@ -31,7 +31,7 @@ public interface RoleMenuService { * * @param menuIds 菜单 ID 列表 * @param roleId 角色 ID - * @return true:成功;false:无变更/失败 + * @return 是否新增成功(true:成功;false:无变更/失败) */ boolean add(List menuIds, Long roleId); diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/UserPasswordHistoryService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserPasswordHistoryService.java new file mode 100644 index 00000000..f5e8dea1 --- /dev/null +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserPasswordHistoryService.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.admin.system.service; + +/** + * 用户历史密码业务接口 + * + * @author Charles7c + * @since 2024/5/16 21:58 + */ +public interface UserPasswordHistoryService { + + /** + * 新增 + * + * @param userId 用户 ID + * @param password 密码 + * @param count 保留 N 个历史 + */ + void add(Long userId, String password, int count); + + /** + * 密码是否为重复使用 + * + * @param userId 用户 ID + * @param password 密码 + * @param count 最近 N 次 + * @return 是否为重复使用 + */ + boolean isPasswordReused(Long userId, String password, int count); +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/UserRoleService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserRoleService.java index b0d4a0fa..53f15663 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/UserRoleService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserRoleService.java @@ -31,7 +31,7 @@ public interface UserRoleService { * * @param roleIds 角色 ID 列表 * @param userId 用户 ID - * @return true:成功;false:无变更/失败 + * @return 是否新增成功(true:成功;false:无变更/失败) */ boolean add(List roleIds, Long userId); @@ -54,7 +54,7 @@ public interface UserRoleService { * 根据角色 ID 判断是否已被用户关联 * * @param roleIds 角色 ID 列表 - * @return true:已关联;false:未关联 + * @return 是否已关联(true:已关联;false:未关联) */ boolean isRoleIdExists(List roleIds); } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/UserService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserService.java index eefcee34..cfe8c43d 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/UserService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/UserService.java @@ -145,5 +145,5 @@ public interface UserService extends BaseService list = baseMapper.lambdaQuery() + .select(UserPasswordHistoryDO::getPassword) + .eq(UserPasswordHistoryDO::getUserId, userId) + .orderByDesc(UserPasswordHistoryDO::getCreateTime) + .last("LIMIT %s".formatted(count)) + .list(); + if (CollUtil.isEmpty(list)) { + return false; + } + // 校验是否重复使用历史密码 + List passwordList = list.stream().map(UserPasswordHistoryDO::getPassword).toList(); + return passwordList.stream().anyMatch(p -> passwordEncoder.matches(password, p)); + } +} \ No newline at end of file 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 cfd72d0b..504d4f5c 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 @@ -88,6 +88,7 @@ public class UserServiceImpl extends BaseServiceImpl + + + + DELETE FROM sys_user_password_history + WHERE id NOT IN ( + SELECT * FROM ( + SELECT id + FROM sys_user_password_history + WHERE user_id = #{userId} + ORDER BY create_time DESC + LIMIT #{count} + ) t1 + ) + + \ No newline at end of file diff --git a/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_data.sql b/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_data.sql index d09ab452..04f8706c 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_data.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_data.sql @@ -121,7 +121,7 @@ VALUES ('密码有效期(天)', 'PASSWORD_EXPIRATION_DAYS', NULL, '0', '取值范围为 0-999(0 表示永久有效)。', NULL, NULL), ('密码重复使用规则', 'PASSWORD_REUSE_POLICY', NULL, '5', '不允许使用最近 N 次密码,取值范围为 3-32。', NULL, NULL), ('密码最小长度', 'PASSWORD_MIN_LENGTH', NULL, '8', '取值范围为 8-32。', NULL, NULL), -('密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '0', '', NULL, NULL), +('密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '1', '', NULL, NULL), ('密码是否必须包含特殊字符', 'PASSWORD_CONTAIN_SPECIAL_CHARACTERS', NULL, '0', '', NULL, NULL); -- 初始化默认字典 diff --git a/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_table.sql b/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_table.sql index 523a55da..5533915d 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_table.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/mysql/continew-admin_table.sql @@ -95,6 +95,15 @@ CREATE TABLE IF NOT EXISTS `sys_user` ( INDEX `idx_update_user`(`update_user`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; +CREATE TABLE IF NOT EXISTS `sys_user_password_history` ( + `id` bigint(20) NOT NULL COMMENT 'ID', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `password` varchar(255) NOT NULL COMMENT '密码', + `create_time` datetime NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户历史密码表'; + CREATE TABLE IF NOT EXISTS `sys_user_social` ( `source` varchar(255) NOT NULL COMMENT '来源', `open_id` varchar(255) NOT NULL COMMENT '开放ID', diff --git a/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_data.sql b/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_data.sql index 79d04e2d..1e576463 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_data.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_data.sql @@ -121,7 +121,7 @@ VALUES ('密码有效期(天)', 'PASSWORD_EXPIRATION_DAYS', NULL, '0', '取值范围为 0-999(0 表示永久有效)。', NULL, NULL), ('密码重复使用规则', 'PASSWORD_REUSE_POLICY', NULL, '5', '不允许使用最近 N 次密码,取值范围为 3-32。', NULL, NULL), ('密码最小长度', 'PASSWORD_MIN_LENGTH', NULL, '8', '取值范围为 8-32。', NULL, NULL), -('密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '0', '', NULL, NULL), +('密码是否允许包含正反序账号名', 'PASSWORD_ALLOW_CONTAIN_USERNAME', NULL, '1', '', NULL, NULL), ('密码是否必须包含特殊字符', 'PASSWORD_CONTAIN_SPECIAL_CHARACTERS', NULL, '0', '', NULL, NULL); -- 初始化默认字典 diff --git a/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_table.sql b/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_table.sql index 72ddcc53..b7396aa8 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_table.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/postgresql/continew-admin_table.sql @@ -158,6 +158,20 @@ COMMENT ON COLUMN "sys_user"."update_user" IS '修改人'; COMMENT ON COLUMN "sys_user"."update_time" IS '修改时间'; COMMENT ON TABLE "sys_user" IS '用户表'; +CREATE TABLE IF NOT EXISTS "sys_user_password_history" ( + "id" int8 NOT NULL, + "user_id" int8 NOT NULL, + "password" varchar(255) NOT NULL, + "create_time" timestamp NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "idx_uph_user_id" ON "sys_user_password_history" ("user_id"); +COMMENT ON COLUMN "sys_user_password_history"."id" IS 'ID'; +COMMENT ON COLUMN "sys_user_password_history"."user_id" IS '用户ID'; +COMMENT ON COLUMN "sys_user_password_history"."password" IS '密码'; +COMMENT ON COLUMN "sys_user_password_history"."create_time" IS '创建时间'; +COMMENT ON TABLE "sys_user_password_history" IS '用户历史密码表'; + CREATE TABLE IF NOT EXISTS "sys_user_social" ( "source" varchar(255) NOT NULL, "open_id" varchar(255) NOT NULL,