个人中心

pull/65/head
awenes 2023-10-06 15:26:33 +08:00
parent 0b2840e1f2
commit 92b2117058
6 changed files with 109 additions and 157 deletions

View File

@ -139,8 +139,9 @@ public interface AdministratorRepository extends LogicDeleteRepository<Administr
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Modifying @Modifying
@CacheEvict(allEntries = true) @CacheEvict(allEntries = true)
@Query(value = "update AdministratorEntity set password = :password where id = :id") @Query(value = "update AdministratorEntity set password =:password,lastUpdatePasswordTime = :lastUpdatePasswordTime where id=:id")
void updatePassword(@Param(value = "id") String id, @Param(value = "password") String password); Integer updatePassword(@Param(value = "id") Long id, @Param(value = "password") String password,
@Param(value = "lastUpdatePasswordTime") LocalDateTime lastUpdatePasswordTime);
/** /**
* *
@ -154,4 +155,29 @@ public interface AdministratorRepository extends LogicDeleteRepository<Administr
@Modifying @Modifying
@Query(value = "UPDATE administrator SET auth_total = (IFNULL(auth_total,0) +1),last_auth_ip = ?2,last_auth_time = ?3 WHERE id_ = ?1", nativeQuery = true) @Query(value = "UPDATE administrator SET auth_total = (IFNULL(auth_total,0) +1),last_auth_ip = ?2,last_auth_time = ?3 WHERE id_ = ?1", nativeQuery = true)
void updateAuthSucceedInfo(String id, String ip, LocalDateTime loginTime); void updateAuthSucceedInfo(String id, String ip, LocalDateTime loginTime);
/**
*
*
* @param id {@link Long}
* @param email {@link String}
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@CacheEvict(allEntries = true)
@Query(value = "UPDATE AdministratorEntity SET email =:email WHERE id=:id")
Integer updateEmail(@Param(value = "id") Long id, @Param(value = "email") String email);
/**
*
*
* @param id {@link Long}
* @param phone {@link String}
* @return {@link Integer}
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@CacheEvict(allEntries = true)
@Query(value = "update AdministratorEntity set phone =:phone where id=:id")
Integer updatePhone(@Param(value = "id") Long id, @Param(value = "phone") String phone);
} }

View File

@ -17,7 +17,6 @@
*/ */
import { ParamCheckType } from '@/constant'; import { ParamCheckType } from '@/constant';
import { request } from '@@/plugin-request/request'; import { request } from '@@/plugin-request/request';
import { GetBoundIdpList } from './data.d';
/** /**
* *
@ -25,7 +24,7 @@ import { GetBoundIdpList } from './data.d';
* @param encrypt * @param encrypt
*/ */
export async function prepareChangePhone(encrypt: string): Promise<API.ApiResult<boolean>> { export async function prepareChangePhone(encrypt: string): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/prepare_change_phone`, { return request(`/api/v1/user/profile/prepare_change_phone`, {
data: { encrypt: encrypt }, data: { encrypt: encrypt },
method: 'POST', method: 'POST',
skipErrorHandler: true, skipErrorHandler: true,
@ -34,25 +33,13 @@ export async function prepareChangePhone(encrypt: string): Promise<API.ApiResult
}); });
} }
export async function getBoundIdpList(): Promise<API.ApiResult<GetBoundIdpList[]>> {
return request(`/api/v1/account/bound_idp`, {
method: 'GET',
});
}
export async function unbindIdp(id: string): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/unbind_idp/${id}`, {
method: 'DELETE',
});
}
/** /**
* *
* *
* @param data * @param data
*/ */
export async function changePhone(data: Record<string, string>): Promise<API.ApiResult<boolean>> { export async function changePhone(data: Record<string, string>): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/change_phone`, { return request(`/api/v1/user/profile/change_phone`, {
data: data, data: data,
method: 'PUT', method: 'PUT',
}); });
@ -64,7 +51,7 @@ export async function changePhone(data: Record<string, string>): Promise<API.Api
* @param encrypt * @param encrypt
*/ */
export async function prepareChangeEmail(encrypt: string): Promise<API.ApiResult<boolean>> { export async function prepareChangeEmail(encrypt: string): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/prepare_change_email`, { return request(`/api/v1/user/profile/prepare_change_email`, {
data: { encrypt: encrypt }, data: { encrypt: encrypt },
method: 'POST', method: 'POST',
skipErrorHandler: true, skipErrorHandler: true,
@ -79,7 +66,7 @@ export async function prepareChangeEmail(encrypt: string): Promise<API.ApiResult
* @param data * @param data
*/ */
export async function changeEmail(data: Record<string, string>): Promise<API.ApiResult<boolean>> { export async function changeEmail(data: Record<string, string>): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/change_email`, { return request(`/api/v1/user/profile/change_email`, {
data: data, data: data,
method: 'PUT', method: 'PUT',
}); });
@ -91,7 +78,7 @@ export async function changeEmail(data: Record<string, string>): Promise<API.Api
* @param encrypt * @param encrypt
*/ */
export async function changePassword(encrypt: string): Promise<API.ApiResult<boolean>> { export async function changePassword(encrypt: string): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/change_password`, { return request(`/api/v1/user/profile/change_password`, {
data: { encrypt: encrypt }, data: { encrypt: encrypt },
method: 'PUT', method: 'PUT',
skipErrorHandler: true, skipErrorHandler: true,
@ -106,7 +93,7 @@ export async function changePassword(encrypt: string): Promise<API.ApiResult<boo
* @param encrypt * @param encrypt
*/ */
export async function changeBaseInfo(encrypt: string): Promise<API.ApiResult<boolean>> { export async function changeBaseInfo(encrypt: string): Promise<API.ApiResult<boolean>> {
return request(`/api/v1/account/change_info`, { return request(`/api/v1/user/profile/change_info`, {
data: { encrypt: encrypt }, data: { encrypt: encrypt },
method: 'PUT', method: 'PUT',
}); });
@ -134,7 +121,7 @@ export async function userParamCheck(
* *
*/ */
export async function prepareChangePassword(encrypt: string): Promise<API.ApiResult<boolean>> { export async function prepareChangePassword(encrypt: string): Promise<API.ApiResult<boolean>> {
return request('/api/v1/account/prepare_change_password', { return request('/api/v1/user/profile/prepare_change_password', {
method: 'POST', method: 'POST',
data: { encrypt: encrypt }, data: { encrypt: encrypt },
skipErrorHandler: true, skipErrorHandler: true,

View File

@ -25,7 +25,6 @@ import cn.topiam.employee.audit.event.type.EventType;
import cn.topiam.employee.console.pojo.update.user.*; import cn.topiam.employee.console.pojo.update.user.*;
import cn.topiam.employee.console.service.user.UserProfileService; import cn.topiam.employee.console.service.user.UserProfileService;
import cn.topiam.employee.support.result.ApiRestResult; import cn.topiam.employee.support.result.ApiRestResult;
import cn.topiam.employee.support.web.decrypt.DecryptRequestBody;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@ -50,7 +49,7 @@ public class UserProfileController {
@Audit(type = EventType.MODIFY_ACCOUNT_INFO_PORTAL) @Audit(type = EventType.MODIFY_ACCOUNT_INFO_PORTAL)
@Operation(summary = "修改账户信息") @Operation(summary = "修改账户信息")
@PutMapping("/change_info") @PutMapping("/change_info")
public ApiRestResult<Boolean> changeInfo(@DecryptRequestBody @RequestBody @Validated UpdateUserInfoRequest param) { public ApiRestResult<Boolean> changeInfo(@RequestBody @Validated UpdateUserInfoRequest param) {
Boolean result = userProfileService.changeInfo(param); Boolean result = userProfileService.changeInfo(param);
return ApiRestResult.ok(result); return ApiRestResult.ok(result);
} }
@ -63,7 +62,7 @@ public class UserProfileController {
@Audit(type = EventType.PREPARE_MODIFY_PASSWORD) @Audit(type = EventType.PREPARE_MODIFY_PASSWORD)
@Operation(summary = "准备修改账户密码") @Operation(summary = "准备修改账户密码")
@PostMapping("/prepare_change_password") @PostMapping("/prepare_change_password")
public ApiRestResult<Boolean> prepareChangePassword(@DecryptRequestBody @RequestBody @Validated PrepareChangePasswordRequest param) { public ApiRestResult<Boolean> prepareChangePassword(@RequestBody @Validated PrepareChangePasswordRequest param) {
return ApiRestResult.ok(userProfileService.prepareChangePassword(param)); return ApiRestResult.ok(userProfileService.prepareChangePassword(param));
} }
@ -75,7 +74,7 @@ public class UserProfileController {
@Audit(type = EventType.MODIFY_USER_PASSWORD_PORTAL) @Audit(type = EventType.MODIFY_USER_PASSWORD_PORTAL)
@Operation(summary = "修改账户密码") @Operation(summary = "修改账户密码")
@PutMapping("/change_password") @PutMapping("/change_password")
public ApiRestResult<Boolean> changePassword(@DecryptRequestBody @RequestBody @Validated ChangePasswordRequest param) { public ApiRestResult<Boolean> changePassword(@RequestBody @Validated ChangePasswordRequest param) {
return ApiRestResult.ok(userProfileService.changePassword(param)); return ApiRestResult.ok(userProfileService.changePassword(param));
} }
@ -87,7 +86,7 @@ public class UserProfileController {
@Audit(type = EventType.PREPARE_MODIFY_PHONE) @Audit(type = EventType.PREPARE_MODIFY_PHONE)
@Operation(summary = "准备修改手机") @Operation(summary = "准备修改手机")
@PostMapping("/prepare_change_phone") @PostMapping("/prepare_change_phone")
public ApiRestResult<Boolean> prepareChangePhone(@DecryptRequestBody @RequestBody @Validated PrepareChangePhoneRequest param) { public ApiRestResult<Boolean> prepareChangePhone(@RequestBody @Validated PrepareChangePhoneRequest param) {
return ApiRestResult.ok(userProfileService.prepareChangePhone(param)); return ApiRestResult.ok(userProfileService.prepareChangePhone(param));
} }
@ -111,7 +110,7 @@ public class UserProfileController {
@Audit(type = EventType.PREPARE_MODIFY_EMAIL) @Audit(type = EventType.PREPARE_MODIFY_EMAIL)
@Operation(summary = "准备修改邮箱") @Operation(summary = "准备修改邮箱")
@PostMapping("/prepare_change_email") @PostMapping("/prepare_change_email")
public ApiRestResult<Boolean> prepareChangeEmail(@DecryptRequestBody @RequestBody @Validated PrepareChangeEmailRequest param) { public ApiRestResult<Boolean> prepareChangeEmail(@RequestBody @Validated PrepareChangeEmailRequest param) {
return ApiRestResult.ok(userProfileService.prepareChangeEmail(param)); return ApiRestResult.ok(userProfileService.prepareChangeEmail(param));
} }
@ -145,7 +144,7 @@ public class UserProfileController {
*/ */
@Operation(summary = "忘记密码预认证") @Operation(summary = "忘记密码预认证")
@PostMapping(PREPARE_FORGET_PASSWORD) @PostMapping(PREPARE_FORGET_PASSWORD)
public ApiRestResult<Boolean> prepareForgetPassword(@DecryptRequestBody @RequestBody @Validated PrepareForgetPasswordRequest param) { public ApiRestResult<Boolean> prepareForgetPassword(@RequestBody @Validated PrepareForgetPasswordRequest param) {
return ApiRestResult return ApiRestResult
.ok(userProfileService.prepareForgetPassword(param.getRecipient(), param.getCode())); .ok(userProfileService.prepareForgetPassword(param.getRecipient(), param.getCode()));
} }
@ -157,7 +156,7 @@ public class UserProfileController {
*/ */
@Operation(summary = "忘记密码") @Operation(summary = "忘记密码")
@PutMapping(FORGET_PASSWORD) @PutMapping(FORGET_PASSWORD)
public ApiRestResult<Boolean> forgetPassword(@DecryptRequestBody @RequestBody @Validated ForgetPasswordRequest forgetPasswordRequest) { public ApiRestResult<Boolean> forgetPassword(@RequestBody @Validated ForgetPasswordRequest forgetPasswordRequest) {
return ApiRestResult.ok(userProfileService.forgetPassword(forgetPasswordRequest)); return ApiRestResult.ok(userProfileService.forgetPassword(forgetPasswordRequest));
} }

View File

@ -20,8 +20,8 @@ package cn.topiam.employee.console.converter.user;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import cn.topiam.employee.common.entity.account.UserDetailEntity;
import cn.topiam.employee.common.entity.account.UserEntity; import cn.topiam.employee.common.entity.account.UserEntity;
import cn.topiam.employee.common.entity.setting.AdministratorEntity;
import cn.topiam.employee.console.pojo.update.user.UpdateUserInfoRequest; import cn.topiam.employee.console.pojo.update.user.UpdateUserInfoRequest;
/** /**
@ -39,9 +39,7 @@ public interface UserProfileConverter {
* @param param {@link UpdateUserInfoRequest} * @param param {@link UpdateUserInfoRequest}
* @return {@link UserEntity} * @return {@link UserEntity}
*/ */
@Mapping(target = "passwordPlainText", ignore = true)
@Mapping(target = "deleted", ignore = true) @Mapping(target = "deleted", ignore = true)
@Mapping(target = "identitySourceId", ignore = true)
@Mapping(target = "phoneVerified", ignore = true) @Mapping(target = "phoneVerified", ignore = true)
@Mapping(target = "phoneAreaCode", ignore = true) @Mapping(target = "phoneAreaCode", ignore = true)
@Mapping(target = "username", ignore = true) @Mapping(target = "username", ignore = true)
@ -55,34 +53,11 @@ public interface UserProfileConverter {
@Mapping(target = "lastAuthTime", ignore = true) @Mapping(target = "lastAuthTime", ignore = true)
@Mapping(target = "lastAuthIp", ignore = true) @Mapping(target = "lastAuthIp", ignore = true)
@Mapping(target = "id", ignore = true) @Mapping(target = "id", ignore = true)
@Mapping(target = "externalId", ignore = true)
@Mapping(target = "expireDate", ignore = true)
@Mapping(target = "expand", ignore = true) @Mapping(target = "expand", ignore = true)
@Mapping(target = "emailVerified", ignore = true) @Mapping(target = "emailVerified", ignore = true)
@Mapping(target = "email", ignore = true) @Mapping(target = "email", ignore = true)
@Mapping(target = "dataOrigin", ignore = true)
@Mapping(target = "createTime", ignore = true) @Mapping(target = "createTime", ignore = true)
@Mapping(target = "createBy", ignore = true) @Mapping(target = "createBy", ignore = true)
@Mapping(target = "authTotal", ignore = true) @Mapping(target = "authTotal", ignore = true)
UserEntity userUpdateParamConvertToUserEntity(UpdateUserInfoRequest param); AdministratorEntity userUpdateParamConvertToAdministratorEntity(UpdateUserInfoRequest param);
/**
*
*
* @param param {@link UpdateUserInfoRequest}
* @return {@link UserDetailEntity}
*/
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "website", ignore = true)
@Mapping(target = "idType", ignore = true)
@Mapping(target = "userId", ignore = true)
@Mapping(target = "remark", ignore = true)
@Mapping(target = "idCard", ignore = true)
@Mapping(target = "address", ignore = true)
@Mapping(target = "id", ignore = true)
@Mapping(target = "updateTime", ignore = true)
@Mapping(target = "updateBy", ignore = true)
@Mapping(target = "createTime", ignore = true)
@Mapping(target = "createBy", ignore = true)
UserDetailEntity userUpdateParamConvertToUserDetailsEntity(UpdateUserInfoRequest param);
} }

View File

@ -233,7 +233,7 @@ public class AdministratorServiceImpl implements AdministratorService {
Base64.getUrlDecoder().decode(password.getBytes(StandardCharsets.UTF_8)), Base64.getUrlDecoder().decode(password.getBytes(StandardCharsets.UTF_8)),
StandardCharsets.UTF_8); StandardCharsets.UTF_8);
password = passwordEncoder.encode(password); password = passwordEncoder.encode(password);
administratorRepository.updatePassword(id, password); administratorRepository.updatePassword(Long.valueOf(id), password, LocalDateTime.now());
AuditContext.setTarget(Target.builder().id(id).type(TargetType.ADMINISTRATOR).build()); AuditContext.setTarget(Target.builder().id(id).type(TargetType.ADMINISTRATOR).build());
// 下线登录中已重置密码的管理员 // 下线登录中已重置密码的管理员
removeSession(entity.getUsername()); removeSession(entity.getUsername());

View File

@ -36,17 +36,14 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import cn.topiam.employee.common.entity.account.UserDetailEntity;
import cn.topiam.employee.common.entity.account.UserEntity; import cn.topiam.employee.common.entity.account.UserEntity;
import cn.topiam.employee.common.entity.setting.AdministratorEntity;
import cn.topiam.employee.common.enums.MailType; import cn.topiam.employee.common.enums.MailType;
import cn.topiam.employee.common.enums.MessageNoticeChannel; import cn.topiam.employee.common.enums.MessageNoticeChannel;
import cn.topiam.employee.common.enums.SmsType; import cn.topiam.employee.common.enums.SmsType;
import cn.topiam.employee.common.exception.PasswordValidatedFailException; import cn.topiam.employee.common.exception.PasswordValidatedFailException;
import cn.topiam.employee.common.exception.UserNotFoundException; import cn.topiam.employee.common.exception.UserNotFoundException;
import cn.topiam.employee.common.repository.account.UserDetailRepository; import cn.topiam.employee.common.repository.setting.AdministratorRepository;
import cn.topiam.employee.common.repository.account.UserIdpRepository;
import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.console.converter.user.UserProfileConverter; import cn.topiam.employee.console.converter.user.UserProfileConverter;
import cn.topiam.employee.console.pojo.update.user.*; import cn.topiam.employee.console.pojo.update.user.*;
import cn.topiam.employee.console.service.user.UserProfileService; import cn.topiam.employee.console.service.user.UserProfileService;
@ -56,7 +53,6 @@ import cn.topiam.employee.support.context.ServletContextHelp;
import cn.topiam.employee.support.exception.BadParamsException; import cn.topiam.employee.support.exception.BadParamsException;
import cn.topiam.employee.support.exception.InfoValidityFailException; import cn.topiam.employee.support.exception.InfoValidityFailException;
import cn.topiam.employee.support.exception.TopIamException; import cn.topiam.employee.support.exception.TopIamException;
import cn.topiam.employee.support.security.password.PasswordPolicyManager;
import cn.topiam.employee.support.security.util.SecurityUtils; import cn.topiam.employee.support.security.util.SecurityUtils;
import cn.topiam.employee.support.util.BeanUtils; import cn.topiam.employee.support.util.BeanUtils;
import cn.topiam.employee.support.util.PhoneNumberUtils; import cn.topiam.employee.support.util.PhoneNumberUtils;
@ -73,8 +69,9 @@ import static cn.topiam.employee.support.util.EmailUtils.isEmailValidate;
import static cn.topiam.employee.support.util.PhoneNumberUtils.isPhoneValidate; import static cn.topiam.employee.support.util.PhoneNumberUtils.isPhoneValidate;
/** /**
*
* @author TopIAM * @author TopIAM
* Created by support@topiam.cn on 2022/4/3 22:20 * Created by support@topiam.cn on 2022/10/3 22:20
*/ */
@Slf4j @Slf4j
@Service @Service
@ -86,20 +83,12 @@ public class UserProfileServiceImpl implements UserProfileService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean changeInfo(UpdateUserInfoRequest param) { public Boolean changeInfo(UpdateUserInfoRequest param) {
//用户信息 //用户信息
UserEntity toUserEntity = userProfileConverter.userUpdateParamConvertToUserEntity(param); AdministratorEntity administrator = userProfileConverter
UserEntity user = userRepository .userUpdateParamConvertToAdministratorEntity(param);
AdministratorEntity user = administratorRepository
.findById(Long.valueOf(SecurityUtils.getCurrentUser().getId())).orElseThrow(); .findById(Long.valueOf(SecurityUtils.getCurrentUser().getId())).orElseThrow();
BeanUtils.merge(toUserEntity, user, LAST_MODIFIED_BY, LAST_MODIFIED_TIME); BeanUtils.merge(administrator, user, LAST_MODIFIED_BY, LAST_MODIFIED_TIME);
userRepository.save(user); administratorRepository.save(user);
//用户详情
String currentUserId = SecurityUtils.getCurrentUserId();
UserDetailEntity detail = userDetailsRepository.findByUserId(Long.valueOf(currentUserId))
.orElse(new UserDetailEntity().setUserId(user.getId()));
UserDetailEntity toUserDetailsEntity = userProfileConverter
.userUpdateParamConvertToUserDetailsEntity(param);
toUserDetailsEntity.setId(detail.getId());
BeanUtils.merge(toUserDetailsEntity, detail, LAST_MODIFIED_BY, LAST_MODIFIED_TIME);
userDetailsRepository.save(detail);
return true; return true;
} }
@ -107,22 +96,22 @@ public class UserProfileServiceImpl implements UserProfileService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean changePassword(ChangePasswordRequest param) { public Boolean changePassword(ChangePasswordRequest param) {
//获取用户 //获取用户
UserEntity user = getCurrentUser(); AdministratorEntity administrator = getCurrentUser();
Boolean checkOtp = otpContextHelp.checkOtp( Boolean checkOtp = otpContextHelp.checkOtp(
MessageNoticeChannel.SMS == param.getChannel() ? SmsType.UPDATE_PASSWORD.getCode() MessageNoticeChannel.SMS == param.getChannel() ? SmsType.UPDATE_PASSWORD.getCode()
: MailType.UPDATE_PASSWORD.getCode(), : MailType.UPDATE_PASSWORD.getCode(),
param.getChannel(), param.getChannel(),
MessageNoticeChannel.SMS == param.getChannel() ? user.getPhone() : user.getEmail(), MessageNoticeChannel.SMS == param.getChannel() ? administrator.getPhone()
: administrator.getEmail(),
param.getVerifyCode()); param.getVerifyCode());
if (!checkOtp) { if (!checkOtp) {
throw new InfoValidityFailException(EX000102.getMessage()); throw new InfoValidityFailException(EX000102.getMessage());
} }
// 校验密码
passwordPolicyManager.validate(user, param.getNewPassword());
//修改密码 //修改密码
userRepository.updateUserPassword(Long.valueOf(SecurityUtils.getCurrentUser().getId()), administratorRepository.updatePassword(Long.valueOf(SecurityUtils.getCurrentUser().getId()),
passwordEncoder.encode(param.getNewPassword()), LocalDateTime.now()); passwordEncoder.encode(param.getNewPassword()), LocalDateTime.now());
logger.info("用户ID: [{}] 用户名: [{}] 修改密码成功", user.getId(), user.getUsername()); logger.info("用户ID: [{}] 用户名: [{}] 修改密码成功", administrator.getId(),
administrator.getUsername());
//异步下线所有用户 //异步下线所有用户
removeSession(SecurityUtils.getCurrentUserName()); removeSession(SecurityUtils.getCurrentUserName());
//@formatter:on //@formatter:on
@ -132,7 +121,7 @@ public class UserProfileServiceImpl implements UserProfileService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean prepareChangePhone(PrepareChangePhoneRequest param) { public Boolean prepareChangePhone(PrepareChangePhoneRequest param) {
UserEntity user = validatedPassword(param.getPassword()); AdministratorEntity user = validatedPassword(param.getPassword());
// 发送短信验证码 // 发送短信验证码
if (StringUtils.isNotBlank(user.getPhone())) { if (StringUtils.isNotBlank(user.getPhone())) {
otpContextHelp.sendOtp(param.getPhone(), SmsType.UPDATE_PHONE.getCode(), otpContextHelp.sendOtp(param.getPhone(), SmsType.UPDATE_PHONE.getCode(),
@ -152,7 +141,7 @@ public class UserProfileServiceImpl implements UserProfileService {
*/ */
@Override @Override
public Boolean changePhone(ChangePhoneRequest param) { public Boolean changePhone(ChangePhoneRequest param) {
UserEntity user = getCurrentUser(); AdministratorEntity user = getCurrentUser();
Boolean checkOtp; Boolean checkOtp;
if (StringUtils.isNotBlank(user.getPhone())) { if (StringUtils.isNotBlank(user.getPhone())) {
checkOtp = otpContextHelp.checkOtp(SmsType.UPDATE_PHONE.getCode(), checkOtp = otpContextHelp.checkOtp(SmsType.UPDATE_PHONE.getCode(),
@ -165,12 +154,14 @@ public class UserProfileServiceImpl implements UserProfileService {
throw new InfoValidityFailException(EX000102.getMessage()); throw new InfoValidityFailException(EX000102.getMessage());
} }
// 校验是否已经存在 // 校验是否已经存在
UserEntity byEmail = userRepository.findByPhone(param.getPhone()); Optional<AdministratorEntity> optionalAdministrator = administratorRepository
if (Objects.nonNull(byEmail) && !user.getId().equals(byEmail.getId())) { .findByPhone(param.getPhone());
if (optionalAdministrator.isPresent()
&& !user.getId().equals(optionalAdministrator.get().getId())) {
throw new TopIamException("系统中已存在[" + param.getPhone() + "]手机号, 请先解绑"); throw new TopIamException("系统中已存在[" + param.getPhone() + "]手机号, 请先解绑");
} }
Long id = Long.valueOf(SecurityUtils.getCurrentUser().getId()); Long id = Long.valueOf(SecurityUtils.getCurrentUser().getId());
userRepository.updateUserPhone(id, param.getPhone()); administratorRepository.updatePhone(id, param.getPhone());
// 修改手机号成功发送短信 // 修改手机号成功发送短信
LinkedHashMap<String, String> parameter = Maps.newLinkedHashMap(); LinkedHashMap<String, String> parameter = Maps.newLinkedHashMap();
parameter.put(USERNAME, user.getUsername()); parameter.put(USERNAME, user.getUsername());
@ -186,7 +177,7 @@ public class UserProfileServiceImpl implements UserProfileService {
*/ */
@Override @Override
public Boolean prepareChangeEmail(PrepareChangeEmailRequest param) { public Boolean prepareChangeEmail(PrepareChangeEmailRequest param) {
UserEntity user = validatedPassword(param.getPassword()); AdministratorEntity user = validatedPassword(param.getPassword());
// 发送邮箱验证码 // 发送邮箱验证码
if (StringUtils.isNotBlank(user.getEmail())) { if (StringUtils.isNotBlank(user.getEmail())) {
otpContextHelp.sendOtp(param.getEmail(), MailType.UPDATE_BIND_MAIL.getCode(), otpContextHelp.sendOtp(param.getEmail(), MailType.UPDATE_BIND_MAIL.getCode(),
@ -207,9 +198,9 @@ public class UserProfileServiceImpl implements UserProfileService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean changeEmail(ChangeEmailRequest param) { public Boolean changeEmail(ChangeEmailRequest param) {
UserEntity user = getCurrentUser(); AdministratorEntity administrator = getCurrentUser();
Boolean checkOtp; Boolean checkOtp;
if (StringUtils.isNotBlank(user.getEmail())) { if (StringUtils.isNotBlank(administrator.getEmail())) {
checkOtp = otpContextHelp.checkOtp(MailType.UPDATE_BIND_MAIL.getCode(), checkOtp = otpContextHelp.checkOtp(MailType.UPDATE_BIND_MAIL.getCode(),
MessageNoticeChannel.MAIL, param.getEmail(), param.getOtp()); MessageNoticeChannel.MAIL, param.getEmail(), param.getOtp());
} else { } else {
@ -220,18 +211,20 @@ public class UserProfileServiceImpl implements UserProfileService {
throw new InfoValidityFailException(EX000102.getMessage()); throw new InfoValidityFailException(EX000102.getMessage());
} }
// 校验是否已经存在 // 校验是否已经存在
UserEntity byEmail = userRepository.findByEmail(param.getEmail()); Optional<AdministratorEntity> optionalAdministrator = administratorRepository
if (Objects.nonNull(byEmail) && !user.getId().equals(byEmail.getId())) { .findByEmail(param.getEmail());
if (optionalAdministrator.isPresent()
&& !administrator.getId().equals(optionalAdministrator.get().getId())) {
throw new TopIamException("系统中已存在[" + param.getEmail() + "]邮箱, 请先解绑"); throw new TopIamException("系统中已存在[" + param.getEmail() + "]邮箱, 请先解绑");
} }
userRepository.updateUserEmail(Long.valueOf(SecurityUtils.getCurrentUser().getId()), administratorRepository.updateEmail(Long.valueOf(SecurityUtils.getCurrentUser().getId()),
param.getEmail()); param.getEmail());
return true; return true;
} }
@Override @Override
public Boolean prepareChangePassword(PrepareChangePasswordRequest param) { public Boolean prepareChangePassword(PrepareChangePasswordRequest param) {
UserEntity user = getCurrentUser(); AdministratorEntity user = getCurrentUser();
// 发送短信验证码 // 发送短信验证码
if (MessageNoticeChannel.SMS == param.getChannel()) { if (MessageNoticeChannel.SMS == param.getChannel()) {
otpContextHelp.sendOtp(user.getPhone(), SmsType.UPDATE_PASSWORD.getCode(), otpContextHelp.sendOtp(user.getPhone(), SmsType.UPDATE_PASSWORD.getCode(),
@ -247,26 +240,25 @@ public class UserProfileServiceImpl implements UserProfileService {
public Boolean forgetPasswordCode(String recipient) { public Boolean forgetPasswordCode(String recipient) {
if (isEmailValidate(recipient)) { if (isEmailValidate(recipient)) {
// 验证在库中是否有邮箱 // 验证在库中是否有邮箱
Optional<UserEntity> byEmail = Optional Optional<AdministratorEntity> byEmail = administratorRepository.findByEmail(recipient);
.ofNullable(userRepository.findByEmail(recipient));
if (byEmail.isPresent()) { if (byEmail.isPresent()) {
otpContextHelp.sendOtp(recipient, MailType.FORGET_PASSWORD.getCode(), otpContextHelp.sendOtp(recipient, MailType.FORGET_PASSWORD.getCode(),
MessageNoticeChannel.MAIL); MessageNoticeChannel.MAIL);
return true; return true;
} }
log.warn("忘记密码: : 邮箱: [{}] 不存在", recipient); log.warn("忘记密码: 邮箱: [{}] 不存在", recipient);
} else if (isPhoneValidate(recipient)) { } else if (isPhoneValidate(recipient)) {
// 验证在库中是否有手机号 // 验证在库中是否有手机号
Optional<UserEntity> byPhone = Optional Optional<AdministratorEntity> byPhone = administratorRepository
.ofNullable(userRepository.findByPhone(PhoneNumberUtils.getPhoneNumber(recipient))); .findByPhone(PhoneNumberUtils.getPhoneNumber(recipient));
if (byPhone.isPresent()) { if (byPhone.isPresent()) {
otpContextHelp.sendOtp(recipient, SmsType.FORGET_PASSWORD.getCode(), otpContextHelp.sendOtp(recipient, SmsType.FORGET_PASSWORD.getCode(),
MessageNoticeChannel.SMS); MessageNoticeChannel.SMS);
return true; return true;
} }
log.warn("忘记密码: : 手机号: [{}] 不存在", recipient); log.warn("忘记密码: 手机号: [{}] 不存在", recipient);
} }
log.error("忘记密码: : 接受者: [{}] 格式错误", recipient); log.error("忘记密码: 接受者: [{}] 格式错误", recipient);
throw new BadParamsException("请输入正确的手机号或邮箱"); throw new BadParamsException("请输入正确的手机号或邮箱");
} }
@ -274,16 +266,15 @@ public class UserProfileServiceImpl implements UserProfileService {
public Boolean prepareForgetPassword(String recipient, String code) { public Boolean prepareForgetPassword(String recipient, String code) {
// 校验验证码 // 校验验证码
Boolean checkOtp = false; Boolean checkOtp = false;
Optional<UserEntity> user = Optional.empty(); Optional<AdministratorEntity> user = Optional.empty();
if (isEmailValidate(recipient)) { if (isEmailValidate(recipient)) {
user = Optional.ofNullable(userRepository.findByEmail(recipient)); user = administratorRepository.findByEmail(recipient);
if (user.isPresent()) { if (user.isPresent()) {
checkOtp = otpContextHelp.checkOtp(MailType.FORGET_PASSWORD.getCode(), checkOtp = otpContextHelp.checkOtp(MailType.FORGET_PASSWORD.getCode(),
MessageNoticeChannel.MAIL, recipient, code); MessageNoticeChannel.MAIL, recipient, code);
} }
} else if (isPhoneValidate(recipient)) { } else if (isPhoneValidate(recipient)) {
user = Optional user = administratorRepository.findByPhone(PhoneNumberUtils.getPhoneNumber(recipient));
.ofNullable(userRepository.findByPhone(PhoneNumberUtils.getPhoneNumber(recipient)));
if (user.isPresent()) { if (user.isPresent()) {
checkOtp = otpContextHelp.checkOtp(SmsType.FORGET_PASSWORD.getCode(), checkOtp = otpContextHelp.checkOtp(SmsType.FORGET_PASSWORD.getCode(),
MessageNoticeChannel.SMS, recipient, code); MessageNoticeChannel.SMS, recipient, code);
@ -316,15 +307,15 @@ public class UserProfileServiceImpl implements UserProfileService {
return false; return false;
} }
//修改密码 //修改密码
Optional<UserEntity> user = userRepository.findById(Long.valueOf(userId)); Optional<AdministratorEntity> user = administratorRepository.findById(Long.valueOf(userId));
if (user.isPresent()) { if (user.isPresent()) {
UserEntity userEntity = user.get(); AdministratorEntity administratorEntity = user.get();
userRepository.updateUserPassword(userEntity.getId(), administratorRepository.updatePassword(administratorEntity.getId(),
passwordEncoder.encode(forgetPasswordRequest.getNewPassword()), passwordEncoder.encode(forgetPasswordRequest.getNewPassword()),
LocalDateTime.now()); LocalDateTime.now());
logger.info("忘记密码: 用户ID: [{}] 用户名: [{}] 修改密码成功", userEntity.getId(), logger.info("忘记密码: 用户ID: [{}] 用户名: [{}] 修改密码成功", administratorEntity.getId(),
userEntity.getUsername()); administratorEntity.getUsername());
removeSession(userEntity.getUsername()); removeSession(administratorEntity.getUsername());
stringRedisTemplate.delete(redisTokenId); stringRedisTemplate.delete(redisTokenId);
return true; return true;
} }
@ -351,9 +342,10 @@ public class UserProfileServiceImpl implements UserProfileService {
* *
* @return {@link UserEntity} * @return {@link UserEntity}
*/ */
public UserEntity getCurrentUser() { public AdministratorEntity getCurrentUser() {
String userId = SecurityUtils.getCurrentUserId(); String userId = SecurityUtils.getCurrentUserId();
Optional<UserEntity> optional = userRepository.findById(Long.valueOf(userId)); Optional<AdministratorEntity> optional = administratorRepository
.findById(Long.valueOf(userId));
if (optional.isPresent()) { if (optional.isPresent()) {
return optional.get(); return optional.get();
} }
@ -368,8 +360,8 @@ public class UserProfileServiceImpl implements UserProfileService {
* @param password {@link String} * @param password {@link String}
* @return {@link UserEntity} * @return {@link UserEntity}
*/ */
public UserEntity validatedPassword(String password) { public AdministratorEntity validatedPassword(String password) {
UserEntity user = getCurrentUser(); AdministratorEntity user = getCurrentUser();
boolean matches = passwordEncoder.matches(password, user.getPassword()); boolean matches = passwordEncoder.matches(password, user.getPassword());
if (!matches) { if (!matches) {
logger.error("用户ID: [{}] 用户名: [{}] 密码匹配失败", user.getId(), user.getUsername()); logger.error("用户ID: [{}] 用户名: [{}] 密码匹配失败", user.getId(), user.getUsername());
@ -381,84 +373,57 @@ public class UserProfileServiceImpl implements UserProfileService {
/** /**
* Executor * Executor
*/ */
private final Executor executor; private final Executor executor;
/** /**
* AccountConverter * AccountConverter
*/ */
private final UserProfileConverter userProfileConverter; private final UserProfileConverter userProfileConverter;
/** /**
* PasswordEncoder * PasswordEncoder
*/ */
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
/** /**
* UserRepository * AdministratorRepository
*/ */
private final UserRepository userRepository; private final AdministratorRepository administratorRepository;
/**
* Repository
*/
private final UserDetailRepository userDetailsRepository;
/** /**
* SessionRegistry * SessionRegistry
*/ */
private final SessionRegistry sessionRegistry; private final SessionRegistry sessionRegistry;
/** /**
* OtpContextHelp * OtpContextHelp
*/ */
private final OtpContextHelp otpContextHelp; private final OtpContextHelp otpContextHelp;
/** /**
* SmsMsgEventPublish * SmsMsgEventPublish
*/ */
private final SmsMsgEventPublish smsMsgEventPublish; private final SmsMsgEventPublish smsMsgEventPublish;
/** /**
* StringRedisTemplate * StringRedisTemplate
*/ */
private final StringRedisTemplate stringRedisTemplate; private final StringRedisTemplate stringRedisTemplate;
/**
* PasswordPolicyManager
*/
private final PasswordPolicyManager<UserEntity> passwordPolicyManager;
/**
* IdentityProviderRepository
*/
private final IdentityProviderRepository identityProviderRepository;
/**
* UserAuthnBindRepository
*/
private final UserIdpRepository userIdpRepository;
public UserProfileServiceImpl(AsyncConfigurer asyncConfigurer, public UserProfileServiceImpl(AsyncConfigurer asyncConfigurer,
UserProfileConverter userProfileConverter, UserProfileConverter userProfileConverter,
PasswordEncoder passwordEncoder, UserRepository userRepository, PasswordEncoder passwordEncoder,
UserDetailRepository userDetailsRepository, AdministratorRepository administratorRepository,
SessionRegistry sessionRegistry, OtpContextHelp otpContextHelp, SessionRegistry sessionRegistry, OtpContextHelp otpContextHelp,
SmsMsgEventPublish smsMsgEventPublish, SmsMsgEventPublish smsMsgEventPublish,
StringRedisTemplate stringRedisTemplate, StringRedisTemplate stringRedisTemplate) {
PasswordPolicyManager<UserEntity> passwordPolicyManager,
IdentityProviderRepository identityProviderRepository,
UserIdpRepository userIdpRepository) {
this.executor = asyncConfigurer.getAsyncExecutor(); this.executor = asyncConfigurer.getAsyncExecutor();
this.userProfileConverter = userProfileConverter; this.userProfileConverter = userProfileConverter;
this.passwordEncoder = passwordEncoder; this.passwordEncoder = passwordEncoder;
this.userRepository = userRepository; this.administratorRepository = administratorRepository;
this.userDetailsRepository = userDetailsRepository;
this.sessionRegistry = sessionRegistry; this.sessionRegistry = sessionRegistry;
this.otpContextHelp = otpContextHelp; this.otpContextHelp = otpContextHelp;
this.smsMsgEventPublish = smsMsgEventPublish; this.smsMsgEventPublish = smsMsgEventPublish;
this.stringRedisTemplate = stringRedisTemplate; this.stringRedisTemplate = stringRedisTemplate;
this.passwordPolicyManager = passwordPolicyManager;
this.identityProviderRepository = identityProviderRepository;
this.userIdpRepository = userIdpRepository;
} }
} }