Commit 8d22ed8bea2b1bdab0d90113bcaab0f3437a0734
Committed by
芋道源码
1 parent
182511b6
!1156 feat: 支持短信重置后台密码
* feat: 支持短信重置后台密码 * 重构管理后台验证码的验证流程
Showing
11 changed files
with
154 additions
and
51 deletions
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
| @@ -43,6 +43,7 @@ public interface ErrorCodeConstants { | @@ -43,6 +43,7 @@ public interface ErrorCodeConstants { | ||
| 43 | ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用"); | 43 | ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用"); |
| 44 | ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})!"); | 44 | ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过租户最大租户配额({})!"); |
| 45 | ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空"); | 45 | ErrorCode USER_IMPORT_INIT_PASSWORD = new ErrorCode(1_002_003_009, "初始密码不能为空"); |
| 46 | + ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_002_003_010, "该手机号尚未注册"); | ||
| 46 | 47 | ||
| 47 | // ========== 部门模块 1-002-004-000 ========== | 48 | // ========== 部门模块 1-002-004-000 ========== |
| 48 | ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门"); | 49 | ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门"); |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/sms/SmsSceneEnum.java
| @@ -21,7 +21,9 @@ public enum SmsSceneEnum implements IntArrayValuable { | @@ -21,7 +21,9 @@ public enum SmsSceneEnum implements IntArrayValuable { | ||
| 21 | MEMBER_UPDATE_PASSWORD(3, "user-update-password", "会员用户 - 修改密码"), | 21 | MEMBER_UPDATE_PASSWORD(3, "user-update-password", "会员用户 - 修改密码"), |
| 22 | MEMBER_RESET_PASSWORD(4, "user-reset-password", "会员用户 - 忘记密码"), | 22 | MEMBER_RESET_PASSWORD(4, "user-reset-password", "会员用户 - 忘记密码"), |
| 23 | 23 | ||
| 24 | - ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"); | 24 | + ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录"), |
| 25 | + ADMIN_MEMBER_REGISTER(22, "admin-sms-register", "后台用户 - 手机号注册"), | ||
| 26 | + ADMIN_MEMBER_RESET_PASSWORD(23, "admin-reset-password", "后台用户 - 忘记密码"); | ||
| 25 | 27 | ||
| 26 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray(); | 28 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray(); |
| 27 | 29 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
| @@ -7,7 +7,14 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | @@ -7,7 +7,14 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 7 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 7 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 8 | import cn.iocoder.yudao.framework.security.config.SecurityProperties; | 8 | import cn.iocoder.yudao.framework.security.config.SecurityProperties; |
| 9 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | 9 | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| 10 | -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 10 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO; |
| 11 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO; | ||
| 12 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO; | ||
| 13 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO; | ||
| 14 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthResetPasswordReqVO; | ||
| 15 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSmsLoginReqVO; | ||
| 16 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSmsSendReqVO; | ||
| 17 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSocialLoginReqVO; | ||
| 11 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; | 18 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; |
| 12 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | 19 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; |
| 13 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; | 20 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; |
| @@ -23,14 +30,19 @@ import io.swagger.v3.oas.annotations.Operation; | @@ -23,14 +30,19 @@ import io.swagger.v3.oas.annotations.Operation; | ||
| 23 | import io.swagger.v3.oas.annotations.Parameter; | 30 | import io.swagger.v3.oas.annotations.Parameter; |
| 24 | import io.swagger.v3.oas.annotations.Parameters; | 31 | import io.swagger.v3.oas.annotations.Parameters; |
| 25 | import io.swagger.v3.oas.annotations.tags.Tag; | 32 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 26 | -import lombok.extern.slf4j.Slf4j; | ||
| 27 | -import org.springframework.validation.annotation.Validated; | ||
| 28 | -import org.springframework.web.bind.annotation.*; | ||
| 29 | - | ||
| 30 | import jakarta.annotation.Resource; | 33 | import jakarta.annotation.Resource; |
| 31 | import jakarta.annotation.security.PermitAll; | 34 | import jakarta.annotation.security.PermitAll; |
| 32 | import jakarta.servlet.http.HttpServletRequest; | 35 | import jakarta.servlet.http.HttpServletRequest; |
| 33 | import jakarta.validation.Valid; | 36 | import jakarta.validation.Valid; |
| 37 | +import lombok.extern.slf4j.Slf4j; | ||
| 38 | +import org.springframework.validation.annotation.Validated; | ||
| 39 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 40 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 41 | +import org.springframework.web.bind.annotation.RequestBody; | ||
| 42 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 43 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 44 | +import org.springframework.web.bind.annotation.RestController; | ||
| 45 | + | ||
| 34 | import java.util.Collections; | 46 | import java.util.Collections; |
| 35 | import java.util.List; | 47 | import java.util.List; |
| 36 | import java.util.Set; | 48 | import java.util.Set; |
| @@ -139,6 +151,14 @@ public class AuthController { | @@ -139,6 +151,14 @@ public class AuthController { | ||
| 139 | return success(true); | 151 | return success(true); |
| 140 | } | 152 | } |
| 141 | 153 | ||
| 154 | + @PostMapping("/reset-password") | ||
| 155 | + @PermitAll | ||
| 156 | + @Operation(summary = "重置密码") | ||
| 157 | + public CommonResult<Boolean> resetPassword(@RequestBody @Valid AuthResetPasswordReqVO reqVO) { | ||
| 158 | + authService.resetPassword(reqVO); | ||
| 159 | + return success(true); | ||
| 160 | + } | ||
| 161 | + | ||
| 142 | // ========== 社交登录相关 ========== | 162 | // ========== 社交登录相关 ========== |
| 143 | 163 | ||
| 144 | @GetMapping("/social-auth-redirect") | 164 | @GetMapping("/social-auth-redirect") |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java
| @@ -19,7 +19,7 @@ import jakarta.validation.constraints.Pattern; | @@ -19,7 +19,7 @@ import jakarta.validation.constraints.Pattern; | ||
| 19 | @NoArgsConstructor | 19 | @NoArgsConstructor |
| 20 | @AllArgsConstructor | 20 | @AllArgsConstructor |
| 21 | @Builder | 21 | @Builder |
| 22 | -public class AuthLoginReqVO { | 22 | +public class AuthLoginReqVO extends CaptchaVerificationReqVO { |
| 23 | 23 | ||
| 24 | @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudaoyuanma") | 24 | @Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudaoyuanma") |
| 25 | @NotEmpty(message = "登录账号不能为空") | 25 | @NotEmpty(message = "登录账号不能为空") |
| @@ -32,13 +32,6 @@ public class AuthLoginReqVO { | @@ -32,13 +32,6 @@ public class AuthLoginReqVO { | ||
| 32 | @Length(min = 4, max = 16, message = "密码长度为 4-16 位") | 32 | @Length(min = 4, max = 16, message = "密码长度为 4-16 位") |
| 33 | private String password; | 33 | private String password; |
| 34 | 34 | ||
| 35 | - // ========== 图片验证码相关 ========== | ||
| 36 | - | ||
| 37 | - @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED, | ||
| 38 | - example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==") | ||
| 39 | - @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class) | ||
| 40 | - private String captchaVerification; | ||
| 41 | - | ||
| 42 | // ========== 绑定社交登录时,需要传递如下参数 ========== | 35 | // ========== 绑定社交登录时,需要传递如下参数 ========== |
| 43 | 36 | ||
| 44 | @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | 37 | @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举值", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| @@ -51,11 +44,6 @@ public class AuthLoginReqVO { | @@ -51,11 +44,6 @@ public class AuthLoginReqVO { | ||
| 51 | @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") | 44 | @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") |
| 52 | private String socialState; | 45 | private String socialState; |
| 53 | 46 | ||
| 54 | - /** | ||
| 55 | - * 开启验证码的 Group | ||
| 56 | - */ | ||
| 57 | - public interface CodeEnableGroup {} | ||
| 58 | - | ||
| 59 | @AssertTrue(message = "授权码不能为空") | 47 | @AssertTrue(message = "授权码不能为空") |
| 60 | public boolean isSocialCodeValid() { | 48 | public boolean isSocialCodeValid() { |
| 61 | return socialType == null || StrUtil.isNotEmpty(socialCode); | 49 | return socialType == null || StrUtil.isNotEmpty(socialCode); |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthRegisterReqVO.java
| @@ -9,7 +9,7 @@ import jakarta.validation.constraints.*; | @@ -9,7 +9,7 @@ import jakarta.validation.constraints.*; | ||
| 9 | 9 | ||
| 10 | @Schema(description = "管理后台 - Register Request VO") | 10 | @Schema(description = "管理后台 - Register Request VO") |
| 11 | @Data | 11 | @Data |
| 12 | -public class AuthRegisterReqVO { | 12 | +public class AuthRegisterReqVO extends CaptchaVerificationReqVO { |
| 13 | 13 | ||
| 14 | @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao") | 14 | @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao") |
| 15 | @NotBlank(message = "用户账号不能为空") | 15 | @NotBlank(message = "用户账号不能为空") |
| @@ -26,12 +26,4 @@ public class AuthRegisterReqVO { | @@ -26,12 +26,4 @@ public class AuthRegisterReqVO { | ||
| 26 | @NotEmpty(message = "密码不能为空") | 26 | @NotEmpty(message = "密码不能为空") |
| 27 | @Length(min = 4, max = 16, message = "密码长度为 4-16 位") | 27 | @Length(min = 4, max = 16, message = "密码长度为 4-16 位") |
| 28 | private String password; | 28 | private String password; |
| 29 | - | ||
| 30 | - // ========== 图片验证码相关 ========== | ||
| 31 | - | ||
| 32 | - @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED, | ||
| 33 | - example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==") | ||
| 34 | - @NotEmpty(message = "验证码不能为空", groups = AuthLoginReqVO.CodeEnableGroup.class) | ||
| 35 | - private String captchaVerification; | ||
| 36 | - | ||
| 37 | } | 29 | } |
| 38 | \ No newline at end of file | 30 | \ No newline at end of file |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthResetPasswordReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.controller.admin.auth.vo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.Mobile; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import jakarta.validation.constraints.NotEmpty; | ||
| 6 | +import lombok.AllArgsConstructor; | ||
| 7 | +import lombok.Builder; | ||
| 8 | +import lombok.Data; | ||
| 9 | +import lombok.NoArgsConstructor; | ||
| 10 | +import org.hibernate.validator.constraints.Length; | ||
| 11 | + | ||
| 12 | +@Schema(description = "管理后台 - 短信重置账号密码 Request VO") | ||
| 13 | +@Data | ||
| 14 | +@NoArgsConstructor | ||
| 15 | +@AllArgsConstructor | ||
| 16 | +@Builder | ||
| 17 | +public class AuthResetPasswordReqVO { | ||
| 18 | + | ||
| 19 | + @Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1234") | ||
| 20 | + @NotEmpty(message = "密码不能为空") | ||
| 21 | + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") | ||
| 22 | + private String password; | ||
| 23 | + | ||
| 24 | + @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13312341234") | ||
| 25 | + @NotEmpty(message = "手机号不能为空") | ||
| 26 | + @Mobile | ||
| 27 | + private String mobile; | ||
| 28 | + | ||
| 29 | + @Schema(description = "手机短信验证码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456") | ||
| 30 | + @NotEmpty(message = "手机手机短信验证码不能为空") | ||
| 31 | + private String code; | ||
| 32 | +} | ||
| 0 | \ No newline at end of file | 33 | \ No newline at end of file |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java
| @@ -17,7 +17,7 @@ import jakarta.validation.constraints.NotNull; | @@ -17,7 +17,7 @@ import jakarta.validation.constraints.NotNull; | ||
| 17 | @NoArgsConstructor | 17 | @NoArgsConstructor |
| 18 | @AllArgsConstructor | 18 | @AllArgsConstructor |
| 19 | @Builder | 19 | @Builder |
| 20 | -public class AuthSmsSendReqVO { | 20 | +public class AuthSmsSendReqVO extends CaptchaVerificationReqVO { |
| 21 | 21 | ||
| 22 | @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudaoyuanma") | 22 | @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudaoyuanma") |
| 23 | @NotEmpty(message = "手机号不能为空") | 23 | @NotEmpty(message = "手机号不能为空") |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/CaptchaVerificationReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.controller.admin.auth.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +@Schema(description = "管理后台 - 验证码 Request VO") | ||
| 8 | +@Data | ||
| 9 | +public class CaptchaVerificationReqVO { | ||
| 10 | + | ||
| 11 | + // ========== 图片验证码相关 ========== | ||
| 12 | + @Schema(description = "验证码,验证码开启时,需要传递", requiredMode = Schema.RequiredMode.REQUIRED, | ||
| 13 | + example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==") | ||
| 14 | + @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class) | ||
| 15 | + private String captchaVerification; | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 开启验证码的 Group | ||
| 19 | + */ | ||
| 20 | + public interface CodeEnableGroup { | ||
| 21 | + } | ||
| 22 | +} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java
| @@ -52,7 +52,7 @@ public interface AdminAuthService { | @@ -52,7 +52,7 @@ public interface AdminAuthService { | ||
| 52 | * @param reqVO 登录信息 | 52 | * @param reqVO 登录信息 |
| 53 | * @return 登录结果 | 53 | * @return 登录结果 |
| 54 | */ | 54 | */ |
| 55 | - AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO) ; | 55 | + AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO); |
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | * 社交快捷登录,使用 code 授权码 | 58 | * 社交快捷登录,使用 code 授权码 |
| @@ -78,4 +78,11 @@ public interface AdminAuthService { | @@ -78,4 +78,11 @@ public interface AdminAuthService { | ||
| 78 | */ | 78 | */ |
| 79 | AuthLoginRespVO register(AuthRegisterReqVO createReqVO); | 79 | AuthLoginRespVO register(AuthRegisterReqVO createReqVO); |
| 80 | 80 | ||
| 81 | + /** | ||
| 82 | + * 重置密码 | ||
| 83 | + * | ||
| 84 | + * @param reqVO 验证码信息 | ||
| 85 | + */ | ||
| 86 | + void resetPassword(AuthResetPasswordReqVO reqVO); | ||
| 87 | + | ||
| 81 | } | 88 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
| @@ -8,9 +8,17 @@ import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | @@ -8,9 +8,17 @@ import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | 8 | import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; |
| 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; | 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; |
| 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 11 | +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; | ||
| 11 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 12 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 12 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | 13 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; |
| 13 | -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 14 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO; |
| 15 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO; | ||
| 16 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO; | ||
| 17 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthResetPasswordReqVO; | ||
| 18 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSmsLoginReqVO; | ||
| 19 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSmsSendReqVO; | ||
| 20 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthSocialLoginReqVO; | ||
| 21 | +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.CaptchaVerificationReqVO; | ||
| 14 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; | 22 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; |
| 15 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | 23 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| 16 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | 24 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| @@ -22,6 +30,7 @@ import cn.iocoder.yudao.module.system.service.logger.LoginLogService; | @@ -22,6 +30,7 @@ import cn.iocoder.yudao.module.system.service.logger.LoginLogService; | ||
| 22 | import cn.iocoder.yudao.module.system.service.member.MemberService; | 30 | import cn.iocoder.yudao.module.system.service.member.MemberService; |
| 23 | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; | 31 | import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; |
| 24 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; | 32 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; |
| 33 | +import cn.iocoder.yudao.module.system.service.tenant.TenantService; | ||
| 25 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; | 34 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| 26 | import com.google.common.annotations.VisibleForTesting; | 35 | import com.google.common.annotations.VisibleForTesting; |
| 27 | import com.xingyuv.captcha.model.common.ResponseModel; | 36 | import com.xingyuv.captcha.model.common.ResponseModel; |
| @@ -32,12 +41,20 @@ import jakarta.validation.Validator; | @@ -32,12 +41,20 @@ import jakarta.validation.Validator; | ||
| 32 | import lombok.extern.slf4j.Slf4j; | 41 | import lombok.extern.slf4j.Slf4j; |
| 33 | import org.springframework.beans.factory.annotation.Value; | 42 | import org.springframework.beans.factory.annotation.Value; |
| 34 | import org.springframework.stereotype.Service; | 43 | import org.springframework.stereotype.Service; |
| 44 | +import org.springframework.transaction.annotation.Transactional; | ||
| 35 | 45 | ||
| 36 | import java.util.Objects; | 46 | import java.util.Objects; |
| 37 | 47 | ||
| 38 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 48 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 39 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | 49 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| 40 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | 50 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS; |
| 51 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_LOGIN_CAPTCHA_CODE_ERROR; | ||
| 52 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_LOGIN_USER_DISABLED; | ||
| 53 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_MOBILE_NOT_EXISTS; | ||
| 54 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_REGISTER_CAPTCHA_CODE_ERROR; | ||
| 55 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_THIRD_LOGIN_NOT_BIND; | ||
| 56 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_MOBILE_NOT_EXISTS; | ||
| 57 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; | ||
| 41 | 58 | ||
| 42 | /** | 59 | /** |
| 43 | * Auth Service 实现类 | 60 | * Auth Service 实现类 |
| @@ -64,6 +81,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -64,6 +81,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 64 | private CaptchaService captchaService; | 81 | private CaptchaService captchaService; |
| 65 | @Resource | 82 | @Resource |
| 66 | private SmsCodeApi smsCodeApi; | 83 | private SmsCodeApi smsCodeApi; |
| 84 | + @Resource | ||
| 85 | + private TenantService tenantService; | ||
| 67 | 86 | ||
| 68 | /** | 87 | /** |
| 69 | * 验证码的开关,默认为 true | 88 | * 验证码的开关,默认为 true |
| @@ -111,6 +130,13 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -111,6 +130,13 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 111 | 130 | ||
| 112 | @Override | 131 | @Override |
| 113 | public void sendSmsCode(AuthSmsSendReqVO reqVO) { | 132 | public void sendSmsCode(AuthSmsSendReqVO reqVO) { |
| 133 | + // 如果是重置密码场景,需要校验图形验证码是否正确 | ||
| 134 | + if (Objects.equals(SmsSceneEnum.ADMIN_MEMBER_RESET_PASSWORD.getScene(), reqVO.getScene())) { | ||
| 135 | + ResponseModel response = doValidateCaptcha(reqVO); | ||
| 136 | + if (!response.isSuccess()) { | ||
| 137 | + throw exception(AUTH_REGISTER_CAPTCHA_CODE_ERROR, response.getRepMsg()); | ||
| 138 | + } | ||
| 139 | + } | ||
| 114 | // 登录场景,验证是否存在 | 140 | // 登录场景,验证是否存在 |
| 115 | if (userService.getUserByMobile(reqVO.getMobile()) == null) { | 141 | if (userService.getUserByMobile(reqVO.getMobile()) == null) { |
| 116 | throw exception(AUTH_MOBILE_NOT_EXISTS); | 142 | throw exception(AUTH_MOBILE_NOT_EXISTS); |
| @@ -174,16 +200,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -174,16 +200,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 174 | 200 | ||
| 175 | @VisibleForTesting | 201 | @VisibleForTesting |
| 176 | void validateCaptcha(AuthLoginReqVO reqVO) { | 202 | void validateCaptcha(AuthLoginReqVO reqVO) { |
| 177 | - // 如果验证码关闭,则不进行校验 | ||
| 178 | - if (!captchaEnable) { | ||
| 179 | - return; | ||
| 180 | - } | 203 | + ResponseModel response = doValidateCaptcha(reqVO); |
| 181 | // 校验验证码 | 204 | // 校验验证码 |
| 182 | - ValidationUtils.validate(validator, reqVO, AuthLoginReqVO.CodeEnableGroup.class); | ||
| 183 | - CaptchaVO captchaVO = new CaptchaVO(); | ||
| 184 | - captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification()); | ||
| 185 | - ResponseModel response = captchaService.verification(captchaVO); | ||
| 186 | - // 验证不通过 | ||
| 187 | if (!response.isSuccess()) { | 205 | if (!response.isSuccess()) { |
| 188 | // 创建登录失败日志(验证码不正确) | 206 | // 创建登录失败日志(验证码不正确) |
| 189 | createLoginLog(null, reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.CAPTCHA_CODE_ERROR); | 207 | createLoginLog(null, reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, LoginResultEnum.CAPTCHA_CODE_ERROR); |
| @@ -191,6 +209,17 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -191,6 +209,17 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 191 | } | 209 | } |
| 192 | } | 210 | } |
| 193 | 211 | ||
| 212 | + private ResponseModel doValidateCaptcha(CaptchaVerificationReqVO reqVO) { | ||
| 213 | + // 如果验证码关闭,则不进行校验 | ||
| 214 | + if (!captchaEnable) { | ||
| 215 | + return ResponseModel.success(); | ||
| 216 | + } | ||
| 217 | + ValidationUtils.validate(validator, reqVO, CaptchaVerificationReqVO.CodeEnableGroup.class); | ||
| 218 | + CaptchaVO captchaVO = new CaptchaVO(); | ||
| 219 | + captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification()); | ||
| 220 | + return captchaService.verification(captchaVO); | ||
| 221 | + } | ||
| 222 | + | ||
| 194 | private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) { | 223 | private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) { |
| 195 | // 插入登陆日志 | 224 | // 插入登陆日志 |
| 196 | createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS); | 225 | createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS); |
| @@ -261,19 +290,28 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -261,19 +290,28 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 261 | 290 | ||
| 262 | @VisibleForTesting | 291 | @VisibleForTesting |
| 263 | void validateCaptcha(AuthRegisterReqVO reqVO) { | 292 | void validateCaptcha(AuthRegisterReqVO reqVO) { |
| 264 | - // 如果验证码关闭,则不进行校验 | ||
| 265 | - if (!captchaEnable) { | ||
| 266 | - return; | ||
| 267 | - } | ||
| 268 | - // 校验验证码 | ||
| 269 | - ValidationUtils.validate(validator, reqVO, AuthLoginReqVO.CodeEnableGroup.class); | ||
| 270 | - CaptchaVO captchaVO = new CaptchaVO(); | ||
| 271 | - captchaVO.setCaptchaVerification(reqVO.getCaptchaVerification()); | ||
| 272 | - ResponseModel response = captchaService.verification(captchaVO); | 293 | + ResponseModel response = doValidateCaptcha(reqVO); |
| 273 | // 验证不通过 | 294 | // 验证不通过 |
| 274 | if (!response.isSuccess()) { | 295 | if (!response.isSuccess()) { |
| 275 | throw exception(AUTH_REGISTER_CAPTCHA_CODE_ERROR, response.getRepMsg()); | 296 | throw exception(AUTH_REGISTER_CAPTCHA_CODE_ERROR, response.getRepMsg()); |
| 276 | } | 297 | } |
| 277 | } | 298 | } |
| 278 | 299 | ||
| 300 | + @Override | ||
| 301 | + @Transactional(rollbackFor = Exception.class) | ||
| 302 | + public void resetPassword(AuthResetPasswordReqVO reqVO) { | ||
| 303 | + AdminUserDO userByMobile = userService.getUserByMobile(reqVO.getMobile()); | ||
| 304 | + if (userByMobile == null) { | ||
| 305 | + throw exception(USER_MOBILE_NOT_EXISTS); | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + smsCodeApi.useSmsCode(new SmsCodeUseReqDTO() | ||
| 309 | + .setCode(reqVO.getCode()) | ||
| 310 | + .setMobile(reqVO.getMobile()) | ||
| 311 | + .setScene(SmsSceneEnum.ADMIN_MEMBER_RESET_PASSWORD.getScene()) | ||
| 312 | + .setUsedIp(getClientIP()) | ||
| 313 | + ); | ||
| 314 | + | ||
| 315 | + userService.updateUserPassword(userByMobile.getId(), reqVO.getPassword()); | ||
| 316 | + } | ||
| 279 | } | 317 | } |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
| @@ -296,7 +296,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | @@ -296,7 +296,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | ||
| 296 | @Test | 296 | @Test |
| 297 | public void testValidateCaptcha_constraintViolationException() { | 297 | public void testValidateCaptcha_constraintViolationException() { |
| 298 | // 准备参数 | 298 | // 准备参数 |
| 299 | - AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class).setCaptchaVerification(null); | 299 | + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); |
| 300 | + reqVO.setCaptchaVerification(null); | ||
| 300 | 301 | ||
| 301 | // mock 验证码打开 | 302 | // mock 验证码打开 |
| 302 | ReflectUtil.setFieldValue(authService, "captchaEnable", true); | 303 | ReflectUtil.setFieldValue(authService, "captchaEnable", true); |