安全整改
parent
e4f0cb7f60
commit
b76ae7dc54
|
@ -4074,6 +4074,7 @@ CREATE TABLE system_user_role (
|
||||||
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
||||||
user_id bigint NOT NULL,
|
user_id bigint NOT NULL,
|
||||||
role_id bigint NOT NULL,
|
role_id bigint NOT NULL,
|
||||||
|
dept_id bigint NOT NULL,
|
||||||
creator varchar(64) DEFAULT '' NULL,
|
creator varchar(64) DEFAULT '' NULL,
|
||||||
create_time datetime DEFAULT CURRENT_TIMESTAMP NULL,
|
create_time datetime DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
updater varchar(64) DEFAULT '' NULL,
|
updater varchar(64) DEFAULT '' NULL,
|
||||||
|
@ -4085,6 +4086,7 @@ CREATE TABLE system_user_role (
|
||||||
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
||||||
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
||||||
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN system_user_role.dept_id IS '部门ID';
|
||||||
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
||||||
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
||||||
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
||||||
|
|
|
@ -4339,6 +4339,7 @@ CREATE TABLE system_user_role
|
||||||
id int8 NOT NULL,
|
id int8 NOT NULL,
|
||||||
user_id int8 NOT NULL,
|
user_id int8 NOT NULL,
|
||||||
role_id int8 NOT NULL,
|
role_id int8 NOT NULL,
|
||||||
|
dept_id int8 NOT NULL,
|
||||||
creator varchar(64) NULL DEFAULT '',
|
creator varchar(64) NULL DEFAULT '',
|
||||||
create_time timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
create_time timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updater varchar(64) NULL DEFAULT '',
|
updater varchar(64) NULL DEFAULT '',
|
||||||
|
@ -4353,6 +4354,7 @@ ALTER TABLE system_user_role
|
||||||
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
||||||
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
||||||
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN system_user_role.dept_id IS '部门ID';
|
||||||
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
||||||
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
||||||
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
||||||
|
|
|
@ -3581,6 +3581,7 @@ CREATE TABLE `system_user_role` (
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增编号',
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增编号',
|
||||||
`user_id` bigint NOT NULL COMMENT '用户ID',
|
`user_id` bigint NOT NULL COMMENT '用户ID',
|
||||||
`role_id` bigint NOT NULL COMMENT '角色ID',
|
`role_id` bigint NOT NULL COMMENT '角色ID',
|
||||||
|
`dept_id` bigint NOT NULL COMMENT '部门ID',
|
||||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
|
||||||
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
|
||||||
|
|
|
@ -4218,6 +4218,7 @@ CREATE TABLE system_user_role
|
||||||
id number NOT NULL,
|
id number NOT NULL,
|
||||||
user_id number NOT NULL,
|
user_id number NOT NULL,
|
||||||
role_id number NOT NULL,
|
role_id number NOT NULL,
|
||||||
|
dept_id number NOT NULL,
|
||||||
creator varchar2(64) DEFAULT '' NULL,
|
creator varchar2(64) DEFAULT '' NULL,
|
||||||
create_time date DEFAULT CURRENT_TIMESTAMP NULL,
|
create_time date DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
updater varchar2(64) DEFAULT '' NULL,
|
updater varchar2(64) DEFAULT '' NULL,
|
||||||
|
@ -4232,6 +4233,7 @@ ALTER TABLE system_user_role
|
||||||
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
COMMENT ON COLUMN system_user_role.id IS '自增编号';
|
||||||
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
COMMENT ON COLUMN system_user_role.user_id IS '用户ID';
|
||||||
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
COMMENT ON COLUMN system_user_role.role_id IS '角色ID';
|
||||||
|
COMMENT ON COLUMN system_user_role.dept_id IS '部门ID';
|
||||||
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
COMMENT ON COLUMN system_user_role.creator IS '创建者';
|
||||||
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
COMMENT ON COLUMN system_user_role.create_time IS '创建时间';
|
||||||
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
COMMENT ON COLUMN system_user_role.updater IS '更新者';
|
||||||
|
|
|
@ -10352,6 +10352,7 @@ CREATE TABLE system_user_role
|
||||||
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
id bigint NOT NULL PRIMARY KEY IDENTITY,
|
||||||
user_id bigint NOT NULL,
|
user_id bigint NOT NULL,
|
||||||
role_id bigint NOT NULL,
|
role_id bigint NOT NULL,
|
||||||
|
dept_id bigint NOT NULL,
|
||||||
creator nvarchar(64) DEFAULT '' NULL,
|
creator nvarchar(64) DEFAULT '' NULL,
|
||||||
create_time datetime2 DEFAULT CURRENT_TIMESTAMP NULL,
|
create_time datetime2 DEFAULT CURRENT_TIMESTAMP NULL,
|
||||||
updater nvarchar(64) DEFAULT '' NULL,
|
updater nvarchar(64) DEFAULT '' NULL,
|
||||||
|
@ -10382,6 +10383,13 @@ EXEC sp_addextendedproperty
|
||||||
'COLUMN', N'role_id'
|
'COLUMN', N'role_id'
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
EXEC sp_addextendedproperty
|
||||||
|
'MS_Description', N'部门ID',
|
||||||
|
'SCHEMA', N'dbo',
|
||||||
|
'TABLE', N'system_user_role',
|
||||||
|
'COLUMN', N'dept_id'
|
||||||
|
GO
|
||||||
|
|
||||||
EXEC sp_addextendedproperty
|
EXEC sp_addextendedproperty
|
||||||
'MS_Description', N'创建者',
|
'MS_Description', N'创建者',
|
||||||
'SCHEMA', N'dbo',
|
'SCHEMA', N'dbo',
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
|
||||||
|
|
||||||
|
@ -42,6 +43,12 @@ public class FileController {
|
||||||
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
|
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
|
||||||
MultipartFile file = uploadReqVO.getFile();
|
MultipartFile file = uploadReqVO.getFile();
|
||||||
String path = uploadReqVO.getPath();
|
String path = uploadReqVO.getPath();
|
||||||
|
String extname = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).toLowerCase();
|
||||||
|
if(StrUtil.isEmpty(extname)){
|
||||||
|
return error(3379,"只能上传图片文件!");
|
||||||
|
}
|
||||||
|
if(!".bmp,.jpg,.jpeg,.png".contains(extname))
|
||||||
|
return error(3379,"只能上传图片文件!");
|
||||||
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
import cn.iocoder.yudao.framework.common.validation.Mobile;
|
||||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
@ -28,7 +29,8 @@ public class AppAuthLoginReqVO {
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
||||||
@NotEmpty(message = "密码不能为空")
|
@NotEmpty(message = "密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
// ========== 绑定社交登录时,需要传递如下参数 ==========
|
// ========== 绑定社交登录时,需要传递如下参数 ==========
|
||||||
|
|
|
@ -21,7 +21,8 @@ public class AppMemberUserResetPasswordReqVO {
|
||||||
|
|
||||||
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
||||||
@NotEmpty(message = "新密码不能为空")
|
@NotEmpty(message = "新密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class AppMemberUserUpdatePasswordReqVO {
|
||||||
|
|
||||||
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
||||||
@NotEmpty(message = "新密码不能为空")
|
@NotEmpty(message = "新密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
@Schema(description = "手机验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
|
|
@ -28,7 +28,8 @@ public class AuthLoginReqVO {
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "buzhidao")
|
||||||
@NotEmpty(message = "密码不能为空")
|
@NotEmpty(message = "密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
// ========== 图片验证码相关 ==========
|
// ========== 图片验证码相关 ==========
|
||||||
|
|
|
@ -26,7 +26,8 @@ public class AuthRegisterReqVO {
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
@NotEmpty(message = "密码不能为空")
|
@NotEmpty(message = "密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
// ========== 图片验证码相关 ==========
|
// ========== 图片验证码相关 ==========
|
||||||
|
|
|
@ -57,7 +57,8 @@ public class TenantSaveReqVO {
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@AssertTrue(message = "用户账号、密码不能为空")
|
@AssertTrue(message = "用户账号、密码不能为空")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile;
|
package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
@ -12,12 +13,14 @@ public class UserProfileUpdatePasswordReqVO {
|
||||||
|
|
||||||
@Schema(description = "旧密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
@Schema(description = "旧密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
@NotEmpty(message = "旧密码不能为空")
|
@NotEmpty(message = "旧密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String oldPassword;
|
private String oldPassword;
|
||||||
|
|
||||||
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "654321")
|
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "654321")
|
||||||
@NotEmpty(message = "新密码不能为空")
|
@NotEmpty(message = "新密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,9 @@ public class UserSaveReqVO {
|
||||||
// ========== 仅【创建】时,需要传递的字段 ==========
|
// ========== 仅【创建】时,需要传递的字段 ==========
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
|
||||||
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@AssertTrue(message = "密码不能为空")
|
@AssertTrue(message = "密码不能为空")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
package cn.iocoder.yudao.module.system.controller.admin.user.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.Length;
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
@ -17,7 +18,9 @@ public class UserUpdatePasswordReqVO {
|
||||||
|
|
||||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
@NotEmpty(message = "密码不能为空")
|
@NotEmpty(message = "密码不能为空")
|
||||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
|
||||||
|
@Length(min = 8, max = 16, message = "密码长度为 8-16 位")
|
||||||
|
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$", message = "用户密码由 数字、字母 特殊字符(@#$%^&+=!之一)8-16位组成")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,5 +31,8 @@ public class UserRoleDO extends BaseDO {
|
||||||
* 角色 ID
|
* 角色 ID
|
||||||
*/
|
*/
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
/**
|
||||||
|
* 部门 ID
|
||||||
|
*/
|
||||||
|
private Long deptId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,9 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -47,5 +48,12 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
|
||||||
default List<AdminUserDO> selectListByDeptIds(Collection<Long> deptIds) {
|
default List<AdminUserDO> selectListByDeptIds(Collection<Long> deptIds) {
|
||||||
return selectList(AdminUserDO::getDeptId, deptIds);
|
return selectList(AdminUserDO::getDeptId, deptIds);
|
||||||
}
|
}
|
||||||
|
@Select("SELECT update_time FROM system_user_password_time WHERE user_id = #{userId}")
|
||||||
|
LocalDateTime getPasswordUpdateRecord(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
@Update("UPDATE system_user_password_time SET update_time = CURRENT_TIMESTAMP WHERE user_id = #{userId}")
|
||||||
|
void update_password_updatetime(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
@Insert("INSERT INTO system_user_password_time(user_id,update_time) values(#{userId},CURRENT_TIMESTAMP)")
|
||||||
|
void insertPasswordUpdatetime(@Param("userId") Long userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,4 +107,8 @@ public interface RedisKeyConstants {
|
||||||
*/
|
*/
|
||||||
String WXA_SUBSCRIBE_TEMPLATE = "wxa_subscribe_template";
|
String WXA_SUBSCRIBE_TEMPLATE = "wxa_subscribe_template";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录错误次数
|
||||||
|
*/
|
||||||
|
String LOGIN_ERROR_TIMES = "user_login_error_times";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.system.framework.datapermission.config;
|
package cn.iocoder.yudao.module.system.framework.datapermission.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
|
import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -20,6 +21,7 @@ public class DataPermissionConfiguration {
|
||||||
// dept
|
// dept
|
||||||
rule.addDeptColumn(AdminUserDO.class);
|
rule.addDeptColumn(AdminUserDO.class);
|
||||||
rule.addDeptColumn(DeptDO.class, "id");
|
rule.addDeptColumn(DeptDO.class, "id");
|
||||||
|
rule.addDeptColumn(UserRoleDO.class);
|
||||||
// user
|
// user
|
||||||
rule.addUserColumn(AdminUserDO.class, "id");
|
rule.addUserColumn(AdminUserDO.class, "id");
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package cn.iocoder.yudao.module.system.service.auth;
|
package cn.iocoder.yudao.module.system.service.auth;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||||
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
|
@ -14,6 +16,7 @@ import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
|
||||||
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
|
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||||
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
|
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
|
||||||
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
||||||
import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
|
import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
|
||||||
|
@ -31,9 +34,13 @@ import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
|
@ -64,6 +71,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
private CaptchaService captchaService;
|
private CaptchaService captchaService;
|
||||||
@Resource
|
@Resource
|
||||||
private SmsCodeApi smsCodeApi;
|
private SmsCodeApi smsCodeApi;
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码的开关,默认为 true
|
* 验证码的开关,默认为 true
|
||||||
|
@ -76,9 +85,30 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
|
final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
|
||||||
// 校验账号是否存在
|
// 校验账号是否存在
|
||||||
AdminUserDO user = userService.getUserByUsername(username);
|
AdminUserDO user = userService.getUserByUsername(username);
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.now();
|
||||||
|
LocalDateTime localDateTime1= userService.getPasswordUpdatetime(user.getId());
|
||||||
|
if (ChronoUnit.DAYS.between(localDateTime1, localDateTime) >= 90) {
|
||||||
|
//密码超过90天未修改
|
||||||
|
userService.updateUserStatus(user.getId(), 1);
|
||||||
|
throw exception(new ErrorCode(-333, "超过90天未修改密码,请联系管理员解锁"));
|
||||||
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
createLoginLog(null, username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
|
createLoginLog(null, username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
|
||||||
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
//用户登录密码错误次数限制
|
||||||
|
String key = RedisKeyConstants.LOGIN_ERROR_TIMES + ":" + user.getTenantId() + ":" + username;
|
||||||
|
String times = stringRedisTemplate.opsForValue().get(key);
|
||||||
|
if (StrUtil.isEmpty(times)) {
|
||||||
|
stringRedisTemplate.opsForValue().increment(key);
|
||||||
|
stringRedisTemplate.expire(key, 1, TimeUnit.DAYS); //一天内
|
||||||
|
}
|
||||||
|
|
||||||
|
long _times = stringRedisTemplate.opsForValue().increment(key);
|
||||||
|
if (_times >= 6) {
|
||||||
|
userService.updateUserStatus(user.getId(), 1);
|
||||||
|
throw exception(new ErrorCode(1_002_000_099, "账号密码不正确次数过多,账号已锁定!"));
|
||||||
|
} else
|
||||||
|
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||||
}
|
}
|
||||||
if (!userService.isPasswordMatch(password, user.getPassword())) {
|
if (!userService.isPasswordMatch(password, user.getPassword())) {
|
||||||
createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
|
createLoginLog(user.getId(), username, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
|
||||||
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||||
|
@ -219,6 +220,8 @@ public class PermissionServiceImpl implements PermissionService {
|
||||||
UserRoleDO entity = new UserRoleDO();
|
UserRoleDO entity = new UserRoleDO();
|
||||||
entity.setUserId(userId);
|
entity.setUserId(userId);
|
||||||
entity.setRoleId(roleId);
|
entity.setRoleId(roleId);
|
||||||
|
AdminUserDO adminUserDO = userService.getUser(userId);
|
||||||
|
entity.setDeptId(adminUserDO.getDeptId());
|
||||||
return entity;
|
return entity;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -215,5 +216,20 @@ public interface AdminUserService {
|
||||||
* @return 是否匹配
|
* @return 是否匹配
|
||||||
*/
|
*/
|
||||||
boolean isPasswordMatch(String rawPassword, String encodedPassword);
|
boolean isPasswordMatch(String rawPassword, String encodedPassword);
|
||||||
|
/**
|
||||||
|
* 取得密码修改的时间
|
||||||
|
* @Author atuchina
|
||||||
|
* @Date 2024/6/18 10:21
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDateTime getPasswordUpdatetime(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入密码修改时间
|
||||||
|
* @Author atuchina
|
||||||
|
* @Date 2024/6/18 10:37
|
||||||
|
* @param userId
|
||||||
|
*/
|
||||||
|
void insertPasswordUpdatetime(Long userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||||
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
||||||
|
@ -37,6 +38,7 @@ import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -83,6 +85,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
private FileApi fileApi;
|
private FileApi fileApi;
|
||||||
@Resource
|
@Resource
|
||||||
private ConfigApi configApi;
|
private ConfigApi configApi;
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -129,7 +133,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
|
|
||||||
// 2. 插入用户
|
// 2. 插入用户
|
||||||
AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
|
AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
|
||||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
user.setStatus(CommonStatusEnum.DISABLE.getStatus()); // 默认关闭
|
||||||
user.setPassword(encodePassword(registerReqVO.getPassword())); // 加密密码
|
user.setPassword(encodePassword(registerReqVO.getPassword())); // 加密密码
|
||||||
userMapper.insert(user);
|
userMapper.insert(user);
|
||||||
return user.getId();
|
return user.getId();
|
||||||
|
@ -196,6 +200,13 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
AdminUserDO updateObj = new AdminUserDO().setId(id);
|
AdminUserDO updateObj = new AdminUserDO().setId(id);
|
||||||
updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码
|
updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码
|
||||||
userMapper.updateById(updateObj);
|
userMapper.updateById(updateObj);
|
||||||
|
|
||||||
|
//更新密码修改时间表
|
||||||
|
if(userMapper.getPasswordUpdateRecord(id)!=null){
|
||||||
|
userMapper.update_password_updatetime(id);
|
||||||
|
}else{
|
||||||
|
userMapper.insertPasswordUpdatetime(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -224,6 +235,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
updateObj.setPassword(encodePassword(password)); // 加密密码
|
updateObj.setPassword(encodePassword(password)); // 加密密码
|
||||||
userMapper.updateById(updateObj);
|
userMapper.updateById(updateObj);
|
||||||
|
|
||||||
|
userMapper.update_password_updatetime(id);
|
||||||
// 3. 记录操作日志上下文
|
// 3. 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("user", user);
|
LogRecordContext.putVariable("user", user);
|
||||||
LogRecordContext.putVariable("newPassword", updateObj.getPassword());
|
LogRecordContext.putVariable("newPassword", updateObj.getPassword());
|
||||||
|
@ -232,7 +244,11 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
@Override
|
@Override
|
||||||
public void updateUserStatus(Long id, Integer status) {
|
public void updateUserStatus(Long id, Integer status) {
|
||||||
// 校验用户存在
|
// 校验用户存在
|
||||||
validateUserExists(id);
|
AdminUserDO oldUser = validateUserExists(id);
|
||||||
|
if(oldUser.getStatus()==1) {//用户登录错误缓存次数重置
|
||||||
|
String key = RedisKeyConstants.LOGIN_ERROR_TIMES + ":" + oldUser.getTenantId() + ":" + oldUser.getUsername();
|
||||||
|
stringRedisTemplate.delete(key);
|
||||||
|
}
|
||||||
// 更新状态
|
// 更新状态
|
||||||
AdminUserDO updateObj = new AdminUserDO();
|
AdminUserDO updateObj = new AdminUserDO();
|
||||||
updateObj.setId(id);
|
updateObj.setId(id);
|
||||||
|
@ -527,5 +543,17 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||||
private String encodePassword(String password) {
|
private String encodePassword(String password) {
|
||||||
return passwordEncoder.encode(password);
|
return passwordEncoder.encode(password);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public LocalDateTime getPasswordUpdatetime(Long userId){
|
||||||
|
LocalDateTime localDateTime = userMapper.getPasswordUpdateRecord(userId);
|
||||||
|
if(localDateTime==null){
|
||||||
|
userMapper.insertPasswordUpdatetime(userId);
|
||||||
|
return LocalDateTime.now();
|
||||||
|
}else
|
||||||
|
return localDateTime;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void insertPasswordUpdatetime(Long userId){
|
||||||
|
userMapper.insertPasswordUpdatetime(userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue