Showing
8 changed files
with
147 additions
and
84 deletions
application/src/main/java/org/thingsboard/server/controller/yunteng/AbstractUserAccount.java
0 → 100644
1 | +package org.thingsboard.server.controller.yunteng; | |
2 | + | |
3 | +import lombok.RequiredArgsConstructor; | |
4 | +import org.springframework.context.ApplicationEventPublisher; | |
5 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
6 | +import org.thingsboard.server.common.data.edge.EdgeEventActionType; | |
7 | +import org.thingsboard.server.common.data.exception.ThingsboardException; | |
8 | +import org.thingsboard.server.common.data.id.TenantId; | |
9 | +import org.thingsboard.server.common.data.security.UserCredentials; | |
10 | +import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; | |
11 | +import org.thingsboard.server.controller.BaseController; | |
12 | +import org.thingsboard.server.dao.user.UserService; | |
13 | +import org.thingsboard.server.service.security.model.SecurityUser; | |
14 | +import org.thingsboard.server.service.security.system.SystemSecurityService; | |
15 | + | |
16 | +@RequiredArgsConstructor | |
17 | +public class AbstractUserAccount extends BaseController { | |
18 | + protected final UserService tbUserService; | |
19 | + protected final ApplicationEventPublisher eventPublisher; | |
20 | + protected final SystemSecurityService systemSecurityService; | |
21 | + protected final BCryptPasswordEncoder passwordEncoder; | |
22 | + protected void updatePassword(String resetPassword,SecurityUser securityUser) throws ThingsboardException { | |
23 | + try { | |
24 | + UserCredentials userCredentials = | |
25 | + tbUserService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId()); | |
26 | + systemSecurityService.validatePassword( | |
27 | + securityUser.getTenantId(), resetPassword, userCredentials); | |
28 | + userCredentials.setPassword(passwordEncoder.encode(resetPassword)); | |
29 | + tbUserService.replaceUserCredentials(securityUser.getTenantId(), userCredentials); | |
30 | + sendEntityNotificationMsg( | |
31 | + getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED); | |
32 | + eventPublisher.publishEvent(new UserAuthDataChangedEvent(securityUser.getId())); | |
33 | + } catch (Exception e) { | |
34 | + throw handleException(e); | |
35 | + } | |
36 | + } | |
37 | +} | ... | ... |
1 | 1 | package org.thingsboard.server.controller.yunteng; |
2 | 2 | |
3 | 3 | import lombok.RequiredArgsConstructor; |
4 | +import org.springframework.context.ApplicationEventPublisher; | |
5 | +import org.springframework.security.access.prepost.PreAuthorize; | |
6 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
4 | 7 | import org.springframework.web.bind.annotation.*; |
5 | 8 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
9 | +import org.thingsboard.server.common.data.id.TenantId; | |
10 | +import org.thingsboard.server.common.data.id.UserId; | |
11 | +import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException; | |
12 | +import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; | |
13 | +import org.thingsboard.server.common.data.yunteng.core.utils.AccountProperties; | |
14 | +import org.thingsboard.server.common.data.yunteng.dto.UserDTO; | |
6 | 15 | import org.thingsboard.server.common.data.yunteng.dto.request.SendResetPasswordEmailMsg; |
7 | 16 | import org.thingsboard.server.controller.BaseController; |
17 | +import org.thingsboard.server.dao.user.UserService; | |
8 | 18 | import org.thingsboard.server.dao.yunteng.service.YtUserService; |
19 | +import org.thingsboard.server.service.security.model.SecurityUser; | |
20 | +import org.thingsboard.server.service.security.system.SystemSecurityService; | |
21 | + | |
22 | +import java.util.UUID; | |
9 | 23 | |
10 | 24 | @RestController |
11 | 25 | @RequestMapping("/api/yt/tenant") |
12 | -@RequiredArgsConstructor | |
13 | -@Deprecated | |
14 | -public class YtTenantController extends BaseController { | |
26 | +public class YtTenantController extends AbstractUserAccount { | |
15 | 27 | |
16 | 28 | private final YtUserService userService; |
29 | + private final AccountProperties accountProperties; | |
30 | + public YtTenantController(UserService tbUserService, ApplicationEventPublisher eventPublisher, | |
31 | + SystemSecurityService systemSecurityService, | |
32 | + BCryptPasswordEncoder passwordEncoder, | |
33 | + YtUserService userService, | |
34 | + AccountProperties accountProperties) { | |
35 | + super(tbUserService,eventPublisher,systemSecurityService,passwordEncoder); | |
36 | + this.userService = userService; | |
37 | + this.accountProperties = accountProperties; | |
38 | + } | |
17 | 39 | |
18 | 40 | @PostMapping("/resetPassword/{userId}") |
41 | + @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") | |
19 | 42 | public void resetPassword(@PathVariable("userId") String userId) throws ThingsboardException { |
20 | - userService.resetPassword( | |
21 | - userId, getCurrentUser().isPtSysadmin(), getCurrentUser().getCurrentTenantId()); | |
43 | + //check is tenant account | |
44 | + UserDTO userDTO = userService.checkAccount(userId,2); | |
45 | + if(null == userDTO){ | |
46 | + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
47 | + } | |
48 | + //update | |
49 | + String resetPassword = accountProperties.getDefaultPassword(); | |
50 | + SecurityUser securityUser = new SecurityUser(); | |
51 | + securityUser.setId(new UserId(UUID.fromString(userDTO.getTbUser()))); | |
52 | + securityUser.setTenantId(new TenantId(UUID.fromString(userDTO.getTenantId()))); | |
53 | + updatePassword(resetPassword,securityUser); | |
54 | + userService.resetPassword(userId, getCurrentUser().getCurrentTenantId(),resetPassword); | |
22 | 55 | } |
23 | 56 | |
57 | + | |
24 | 58 | @PostMapping("/sendRestPasswordMsg") |
25 | 59 | public void resetPassword(@RequestBody SendResetPasswordEmailMsg msg) { |
26 | 60 | userService.sendRestPasswordMsg(msg); | ... | ... |
... | ... | @@ -4,7 +4,6 @@ import io.swagger.annotations.Api; |
4 | 4 | import io.swagger.annotations.ApiOperation; |
5 | 5 | import io.swagger.annotations.ApiResponse; |
6 | 6 | import io.swagger.annotations.ApiResponses; |
7 | -import lombok.RequiredArgsConstructor; | |
8 | 7 | import org.apache.commons.lang3.StringUtils; |
9 | 8 | import org.springframework.context.ApplicationEventPublisher; |
10 | 9 | import org.springframework.http.ResponseEntity; |
... | ... | @@ -22,11 +21,9 @@ import org.thingsboard.server.common.data.id.*; |
22 | 21 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
23 | 22 | import org.thingsboard.server.common.data.security.Authority; |
24 | 23 | import org.thingsboard.server.common.data.security.UserCredentials; |
25 | -import org.thingsboard.server.common.data.security.event.UserAuthDataChangedEvent; | |
26 | 24 | import org.thingsboard.server.common.data.yunteng.common.AddGroup; |
27 | 25 | import org.thingsboard.server.common.data.yunteng.common.DeleteGroup; |
28 | 26 | import org.thingsboard.server.common.data.yunteng.common.UpdateGroup; |
29 | -import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants; | |
30 | 27 | import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException; |
31 | 28 | import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage; |
32 | 29 | import org.thingsboard.server.common.data.yunteng.core.utils.AccountProperties; |
... | ... | @@ -41,13 +38,13 @@ import org.thingsboard.server.common.data.yunteng.enums.OrderTypeEnum; |
41 | 38 | import org.thingsboard.server.common.data.yunteng.enums.RoleEnum; |
42 | 39 | import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; |
43 | 40 | import org.thingsboard.server.common.data.yunteng.utils.tools.ResponseResult; |
44 | -import org.thingsboard.server.controller.BaseController; | |
45 | 41 | import org.thingsboard.server.dao.user.UserService; |
46 | 42 | import org.thingsboard.server.dao.yunteng.service.YtUserService; |
47 | 43 | import org.thingsboard.server.service.security.model.SecurityUser; |
48 | 44 | import org.thingsboard.server.service.security.permission.Operation; |
49 | 45 | import org.thingsboard.server.service.security.permission.Resource; |
50 | 46 | import org.thingsboard.server.service.security.system.SystemSecurityService; |
47 | + | |
51 | 48 | import javax.servlet.http.HttpServletResponse; |
52 | 49 | import java.io.IOException; |
53 | 50 | import java.util.HashMap; |
... | ... | @@ -58,16 +55,20 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant. |
58 | 55 | |
59 | 56 | @RestController |
60 | 57 | @RequestMapping("api/yt/user") |
61 | -@RequiredArgsConstructor | |
62 | 58 | @Api(value = "用户接口") |
63 | -public class YtUserController extends BaseController { | |
64 | - private final BCryptPasswordEncoder passwordEncoder; | |
59 | +public class YtUserController extends AbstractUserAccount { | |
60 | + | |
65 | 61 | private final YtUserService userService; |
66 | - private final UserService tbUserService; | |
67 | - private final ApplicationEventPublisher eventPublisher; | |
68 | - private final SystemSecurityService systemSecurityService; | |
69 | 62 | private final AccountProperties accountProperties; |
70 | - | |
63 | + public YtUserController(UserService tbUserService, ApplicationEventPublisher eventPublisher, | |
64 | + SystemSecurityService systemSecurityService, | |
65 | + BCryptPasswordEncoder passwordEncoder, | |
66 | + YtUserService userService, | |
67 | + AccountProperties accountProperties) { | |
68 | + super(tbUserService,eventPublisher,systemSecurityService,passwordEncoder); | |
69 | + this.userService = userService; | |
70 | + this.accountProperties = accountProperties; | |
71 | + } | |
71 | 72 | @GetMapping("{userId}") |
72 | 73 | public ResponseEntity<UserDTO> getUser(@PathVariable("userId") String userId) |
73 | 74 | throws ThingsboardException { |
... | ... | @@ -262,21 +263,7 @@ public class YtUserController extends BaseController { |
262 | 263 | userService.validateChangePasswordAccount(accountReqDTO); |
263 | 264 | String resetPassword = accountReqDTO.getResetPassword(); |
264 | 265 | if (!getCurrentUser().isPtAdmin()) { |
265 | - try { | |
266 | - // 除开平台管理员,都要调用TB密码修改 | |
267 | - SecurityUser securityUser = getCurrentUser(); | |
268 | - UserCredentials userCredentials = | |
269 | - tbUserService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId()); | |
270 | - systemSecurityService.validatePassword( | |
271 | - securityUser.getTenantId(), resetPassword, userCredentials); | |
272 | - userCredentials.setPassword(passwordEncoder.encode(resetPassword)); | |
273 | - tbUserService.replaceUserCredentials(securityUser.getTenantId(), userCredentials); | |
274 | - sendEntityNotificationMsg( | |
275 | - getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED); | |
276 | - eventPublisher.publishEvent(new UserAuthDataChangedEvent(securityUser.getId())); | |
277 | - } catch (Exception e) { | |
278 | - throw handleException(e); | |
279 | - } | |
266 | + updatePassword(resetPassword,getCurrentUser()); | |
280 | 267 | } |
281 | 268 | return ResponseResult.success(userService.changePassword(user)); |
282 | 269 | } | ... | ... |
... | ... | @@ -23,8 +23,7 @@ public class UserDTO extends BaseDTO { |
23 | 23 | @NotEmpty(message = "姓名不能为空或字符串", groups = AddGroup.class) |
24 | 24 | private String realName; |
25 | 25 | |
26 | - @JsonInclude(JsonInclude.Include.NON_NULL) | |
27 | - private String password; | |
26 | + private transient String password; | |
28 | 27 | |
29 | 28 | @JsonInclude(JsonInclude.Include.NON_NULL) |
30 | 29 | private String activateToken; | ... | ... |
... | ... | @@ -82,9 +82,9 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
82 | 82 | private final AccountProperties accountProperties; |
83 | 83 | |
84 | 84 | @Override |
85 | - public List<UserDetailsDTO> findUserDetailsByUsername(String username,String tenantId) { | |
85 | + public List<UserDetailsDTO> findUserDetailsByUsername(String username, String tenantId) { | |
86 | 86 | // 多个租户可能存在多个username相同的情况 |
87 | - return baseMapper.findUserDetailsByUserName(username,tenantId); | |
87 | + return baseMapper.findUserDetailsByUserName(username, tenantId); | |
88 | 88 | } |
89 | 89 | |
90 | 90 | @Override |
... | ... | @@ -167,7 +167,8 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
167 | 167 | if (null != userDTO.getId()) { |
168 | 168 | User user = baseMapper.selectById(userDTO.getId()); |
169 | 169 | if (user.getPhoneNumber().equals(userDTO.getPhoneNumber()) |
170 | - && user.getEmail()!=null && user.getEmail().equals(userDTO.getEmail())) { | |
170 | + && user.getEmail() != null | |
171 | + && user.getEmail().equals(userDTO.getEmail())) { | |
171 | 172 | needCheck = false; |
172 | 173 | } |
173 | 174 | } |
... | ... | @@ -342,6 +343,7 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
342 | 343 | record -> { |
343 | 344 | fillUserStatus(record); |
344 | 345 | record.setHasPassword(StringUtils.isNotBlank(record.getActivateToken())); |
346 | + record.setPassword(null); | |
345 | 347 | }); |
346 | 348 | } |
347 | 349 | return getPageData(userPage, UserDTO.class); |
... | ... | @@ -423,43 +425,37 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
423 | 425 | |
424 | 426 | @Override |
425 | 427 | @Transactional |
426 | - public void resetPassword(String userId, boolean isPtSysadmin, String tenantId) { | |
427 | - if (isPtSysadmin) { | |
428 | - baseMapper.setPassword2NullAndInsertActiveToken( | |
429 | - userId, RandomStringUtils.randomAlphabetic(10)); | |
430 | - } else { | |
431 | - User user = baseMapper.selectById(userId); | |
432 | - if (user == null) { | |
433 | - return; | |
434 | - } | |
435 | - if (tenantId.equals(user.getTenantId())) { | |
436 | - baseMapper.setPassword2NullAndInsertActiveToken( | |
437 | - userId, RandomStringUtils.randomAlphabetic(10)); | |
438 | - } | |
428 | + public void resetPassword(String userId, String tenantId, String password) { | |
429 | + UserDTO userDTO = findUserInfoById(userId); | |
430 | + if (null == userDTO) { | |
431 | + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | |
439 | 432 | } |
433 | + userDTO.setPassword(passwordEncoder.encode(password)); | |
434 | + userDTO.setActivateToken(null); | |
435 | + baseMapper.updateById(userDTO.getEntity(User.class)); | |
440 | 436 | } |
441 | 437 | |
442 | 438 | @Override |
443 | - public void forgetPassword(String phoneNumber,AccountReqDTO forget) { | |
439 | + public void forgetPassword(String phoneNumber, AccountReqDTO forget) { | |
444 | 440 | String key = |
445 | - MsgTemplatePurposeEnum.FOR_FORGET_PASSWORD.name() | |
446 | - + DEFAULT_DELIMITER | |
447 | - + MessageTypeEnum.PHONE_MESSAGE.name() | |
448 | - + DEFAULT_DELIMITER | |
449 | - + phoneNumber; | |
441 | + MsgTemplatePurposeEnum.FOR_FORGET_PASSWORD.name() | |
442 | + + DEFAULT_DELIMITER | |
443 | + + MessageTypeEnum.PHONE_MESSAGE.name() | |
444 | + + DEFAULT_DELIMITER | |
445 | + + phoneNumber; | |
450 | 446 | boolean correct = |
451 | - cacheUtils | |
452 | - .get(MOBILE_LOGIN_SMS_CODE, key) | |
453 | - .map( | |
454 | - o -> { | |
455 | - CodeTTL codeTTL = (CodeTTL) o; | |
456 | - if (System.currentTimeMillis() - codeTTL.getSendTs() < 5 * 60 * 1000) { | |
457 | - return Objects.equals(codeTTL.getCode(), forget.getUserId()); | |
458 | - } else { | |
459 | - return false; | |
460 | - } | |
461 | - }) | |
462 | - .orElse(false); | |
447 | + cacheUtils | |
448 | + .get(MOBILE_LOGIN_SMS_CODE, key) | |
449 | + .map( | |
450 | + o -> { | |
451 | + CodeTTL codeTTL = (CodeTTL) o; | |
452 | + if (System.currentTimeMillis() - codeTTL.getSendTs() < 5 * 60 * 1000) { | |
453 | + return Objects.equals(codeTTL.getCode(), forget.getUserId()); | |
454 | + } else { | |
455 | + return false; | |
456 | + } | |
457 | + }) | |
458 | + .orElse(false); | |
463 | 459 | if (!correct) { |
464 | 460 | throw new YtDataValidationException(ErrorMessage.MSG_CODE_NOT_MATCHED.getMessage()); |
465 | 461 | } |
... | ... | @@ -468,16 +464,18 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
468 | 464 | throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); |
469 | 465 | } |
470 | 466 | |
471 | - User user = baseMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getPhoneNumber, phoneNumber)); | |
467 | + User user = | |
468 | + baseMapper.selectOne( | |
469 | + new QueryWrapper<User>().lambda().eq(User::getPhoneNumber, phoneNumber)); | |
472 | 470 | |
473 | 471 | UserId userId = new UserId(UUID.fromString(user.getTbUser())); |
474 | 472 | UserCredentials userCredentials = |
475 | - tbUserService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, userId); | |
476 | - | |
473 | + tbUserService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, userId); | |
477 | 474 | |
478 | 475 | userCredentials.setPassword(passwordEncoder.encode(pwd)); |
479 | - tbUserService.replaceUserCredentials(new TenantId(UUID.fromString(user.getTenantId())), userCredentials); | |
480 | -// eventPublisher.publishEvent(new UserAuthDataChangedEvent(userId)); | |
476 | + tbUserService.replaceUserCredentials( | |
477 | + new TenantId(UUID.fromString(user.getTenantId())), userCredentials); | |
478 | + // eventPublisher.publishEvent(new UserAuthDataChangedEvent(userId)); | |
481 | 479 | |
482 | 480 | user.setPassword(pwd); |
483 | 481 | changePassword(user); |
... | ... | @@ -614,6 +612,14 @@ public class YtUserServiceImpl extends AbstractBaseService<UserMapper, User> |
614 | 612 | } |
615 | 613 | |
616 | 614 | @Override |
615 | + public UserDTO checkAccount(String userId, Integer level) { | |
616 | + User user = | |
617 | + baseMapper.selectOne( | |
618 | + new LambdaQueryWrapper<User>().eq(User::getId, userId).eq(User::getLevel, level)); | |
619 | + return null != user ? user.getDTO(UserDTO.class) : null; | |
620 | + } | |
621 | + | |
622 | + @Override | |
617 | 623 | public UserDTO accountExist(String userName) { |
618 | 624 | if (StringUtils.isEmpty(userName)) { |
619 | 625 | throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); | ... | ... |
... | ... | @@ -28,9 +28,6 @@ public interface UserMapper extends BaseMapper<User> { |
28 | 28 | |
29 | 29 | Set<String> getAllIdsByTenantId(@Param("tenantIds") Collection<String> tenantIds); |
30 | 30 | |
31 | - void setPassword2NullAndInsertActiveToken( | |
32 | - @Param("userId") String userId, @Param("activeToken") String activeToken); | |
33 | - | |
34 | 31 | UserDTO findUserInfo(UserDTO userDTO); |
35 | 32 | |
36 | 33 | List<UserDTO> findUserInfoByPhoneNumber(UserDTO userDTO); | ... | ... |
... | ... | @@ -40,7 +40,7 @@ public interface YtUserService { |
40 | 40 | |
41 | 41 | UserDTO saveTenantAdmin(UserDTO userDTO, boolean isPtSysadmin, String tenantId); |
42 | 42 | |
43 | - void resetPassword(String userId, boolean isPtSysadmin, String tenantId); | |
43 | + void resetPassword(String userId, String tenantId,String password); | |
44 | 44 | |
45 | 45 | void forgetPassword(String phoneNumber,AccountReqDTO forget); |
46 | 46 | |
... | ... | @@ -125,4 +125,12 @@ public interface YtUserService { |
125 | 125 | */ |
126 | 126 | CompletableFuture<TsValue> findUsersAsyncByTs(LocalDateTime startTs, LocalDateTime endTs, long ts); |
127 | 127 | |
128 | + /** | |
129 | + * 检查账号是否存在 | |
130 | + * @param userId 用户ID | |
131 | + * @param level 级别:0:超级管理员;1:平台管理员;2:租户账号;3:租户下的账号 | |
132 | + * @return true 存在 false 不存在 | |
133 | + */ | |
134 | + UserDTO checkAccount(String userId,Integer level); | |
135 | + | |
128 | 136 | } | ... | ... |
... | ... | @@ -38,6 +38,7 @@ |
38 | 38 | <result property="tbUser" column="tb_user"/> |
39 | 39 | <result property="customerId" column="customer_id"/> |
40 | 40 | <result property="remark" column="remark"/> |
41 | + <result property="activateToken" column="activate_token"/> | |
41 | 42 | </resultMap> |
42 | 43 | |
43 | 44 | <sql id="columns"> |
... | ... | @@ -56,7 +57,8 @@ |
56 | 57 | su.dept_id AS dept_id, |
57 | 58 | su.level AS level, |
58 | 59 | su.tb_user AS tb_user, |
59 | - su.remark AS remark | |
60 | + su.remark AS remark, | |
61 | + su.activate_token AS activate_token | |
60 | 62 | </sql> |
61 | 63 | |
62 | 64 | <select id="findUserDetailsByUserName" resultMap="userDetailsMap"> |
... | ... | @@ -131,13 +133,6 @@ |
131 | 133 | </foreach> |
132 | 134 | </select> |
133 | 135 | |
134 | - <update id="setPassword2NullAndInsertActiveToken"> | |
135 | - UPDATE sys_user | |
136 | - SET password=null, | |
137 | - activate_token=#{activeToken} | |
138 | - WHERE id = #{userId} | |
139 | - </update> | |
140 | - | |
141 | 136 | <select id="findUserDetailsByPhoneNumber" resultMap="userDetailsMap"> |
142 | 137 | SELECT su.id as id, |
143 | 138 | su.username as username, | ... | ... |