Commit dede8ed557133964f2fb6e479065b4bdc5c75b23

Authored by xp.Huang
2 parents 717a2b1d e012087d

Merge branch '20220601' into 'master'

feat: 按钮级权限控制

See merge request huang/thingsboard3.3.2!105
... ... @@ -56,10 +56,12 @@ import static org.thingsboard.server.common.data.yunteng.constant.QueryConstant.
56 56 public class YtDeviceController extends BaseController {
57 57 private final YtDeviceService deviceService;
58 58 private final DeviceService tbDeviceService;
  59 + String sePL = new Date().toString();
59 60
60 61 @PostMapping
61 62 @ApiOperation("创建|编辑")
62   - @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  63 +// @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
  64 + @PreAuthorize("@check.checkPermissions({'TENANT_ADMIN'},{})")
63 65 public ResponseEntity<DeviceDTO> saveDevice(
64 66 @Validated(AddGroup.class) @RequestBody DeviceDTO deviceDTO) throws ThingsboardException, ExecutionException, InterruptedException {
65 67 String currentTenantId = getCurrentUser().getCurrentTenantId();
... ...
  1 +package org.thingsboard.server.controller.yunteng.permission;
  2 +
  3 +import com.alibaba.excel.util.StringUtils;
  4 +import lombok.RequiredArgsConstructor;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.springframework.security.core.Authentication;
  7 +import org.springframework.security.core.context.SecurityContextHolder;
  8 +import org.springframework.stereotype.Service;
  9 +import org.thingsboard.server.dao.yunteng.service.RoleService;
  10 +import org.thingsboard.server.service.security.model.SecurityUser;
  11 +
  12 +import java.util.List;
  13 +import java.util.Set;
  14 +
  15 +@Service("check")
  16 +@Slf4j
  17 +@RequiredArgsConstructor
  18 +public class PermissionTools {
  19 +
  20 + private final RoleService roleService;
  21 +
  22 + /**
  23 + * 接口权限校验
  24 + *
  25 + * @param needRoles 接口访问所需角色
  26 + * @param needPermission 接口访问所需权限
  27 + * @return
  28 + */
  29 + public Boolean checkPermissions(List<String> needRoles, Set<String> needPermission) {
  30 + SecurityUser securityUser = null;
  31 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  32 + if (authentication != null && authentication.getPrincipal() instanceof SecurityUser) {
  33 + securityUser = (SecurityUser) authentication.getPrincipal();
  34 + }
  35 + if (securityUser == null) {
  36 + return false;
  37 + }
  38 + Set<String> userRoles = securityUser.getRoles();
  39 + if (needRoles != null && !needRoles.isEmpty()) {
  40 + if (userRoles == null) {
  41 + return false;
  42 + }
  43 + boolean roleMatched = userRoles.stream().anyMatch(f -> needRoles.contains(f));
  44 + if (!roleMatched) {
  45 + return false;
  46 + }
  47 + }
  48 +
  49 + if (needPermission != null && !needPermission.isEmpty()) {
  50 + Set<String> userPermissions = roleService.getPermissions(securityUser.isPtSysadmin(), securityUser.isPtTenantAdmin(), securityUser.getCurrentTenantId(), securityUser.getCurrentUserId());
  51 + if (userPermissions == null || userPermissions.isEmpty()) {
  52 + return false;
  53 + }
  54 + boolean permissionMatched = userPermissions.stream().anyMatch(f -> needPermission.contains(f));
  55 + if (!permissionMatched) {
  56 + return false;
  57 + }
  58 + }
  59 +
  60 + return true;
  61 + }
  62 +}
... ...
1 1 package org.thingsboard.server.dao.yunteng.impl;
2 2
3 3 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4 5 import lombok.RequiredArgsConstructor;
5 6 import lombok.extern.slf4j.Slf4j;
6 7 import org.springframework.stereotype.Service;
... ... @@ -9,8 +10,14 @@ import org.thingsboard.server.common.data.yunteng.constant.FastIotConstants;
9 10 import org.thingsboard.server.common.data.yunteng.core.exception.YtDataValidationException;
10 11 import org.thingsboard.server.common.data.yunteng.core.message.ErrorMessage;
11 12 import org.thingsboard.server.common.data.yunteng.dto.*;
  13 +import org.thingsboard.server.dao.yunteng.entities.ConfigurationAct;
12 14 import org.thingsboard.server.dao.yunteng.entities.ConfigurationContent;
  15 +import org.thingsboard.server.dao.yunteng.entities.ConfigurationDatasource;
  16 +import org.thingsboard.server.dao.yunteng.entities.ConfigurationEvent;
  17 +import org.thingsboard.server.dao.yunteng.mapper.ConfigurationActMapper;
13 18 import org.thingsboard.server.dao.yunteng.mapper.ConfigurationContentMapper;
  19 +import org.thingsboard.server.dao.yunteng.mapper.ConfigurationDatasourceMapper;
  20 +import org.thingsboard.server.dao.yunteng.mapper.ConfigurationEventMapper;
14 21 import org.thingsboard.server.dao.yunteng.service.AbstractBaseService;
15 22 import org.thingsboard.server.dao.yunteng.service.YtConfigurationContentService;
16 23 import java.util.List;
... ... @@ -22,6 +29,9 @@ import java.util.Set;
22 29 public class YtConfigurationContentServiceImpl
23 30 extends AbstractBaseService<ConfigurationContentMapper, ConfigurationContent>
24 31 implements YtConfigurationContentService {
  32 + private final ConfigurationDatasourceMapper datasourceMapper;
  33 + private final ConfigurationEventMapper eventMapper;
  34 + private final ConfigurationActMapper actMapper;
25 35
26 36 @Override
27 37 @Transactional
... ... @@ -62,6 +72,18 @@ public class YtConfigurationContentServiceImpl
62 72 @Override
63 73 @Transactional
64 74 public boolean deleteConfigurationContentByCenterId(Set<String> configurationCenterIds) {
  75 + LambdaQueryWrapper<ConfigurationDatasource> dataFilter = new QueryWrapper<ConfigurationDatasource>().lambda()
  76 + .in(ConfigurationDatasource::getConfigurationId,configurationCenterIds);
  77 + datasourceMapper.delete(dataFilter);
  78 +
  79 + LambdaQueryWrapper<ConfigurationEvent> eventFilter = new QueryWrapper<ConfigurationEvent>().lambda()
  80 + .in(ConfigurationEvent::getConfigurationId,configurationCenterIds);
  81 + eventMapper.delete(eventFilter);
  82 +
  83 + LambdaQueryWrapper<ConfigurationAct> actFilter = new QueryWrapper<ConfigurationAct>().lambda()
  84 + .in(ConfigurationAct::getConfigurationId,configurationCenterIds);
  85 + actMapper.delete(actFilter);
  86 +
65 87 return baseMapper.delete(
66 88 new LambdaQueryWrapper<ConfigurationContent>()
67 89 .in(ConfigurationContent::getConfigurationId, configurationCenterIds))
... ...
... ... @@ -111,9 +111,9 @@ public class YtSmsServiceImpl implements YtSmsService {
111 111 @Transactional
112 112 public boolean sendSmsCode(String phoneNumber,MsgTemplatePurposeEnum purpose) {
113 113 // 检查手机号码是否存在系统,以免乱发消息
114   - if (userMapper
115   - .selectList(new QueryWrapper<User>().lambda().eq(User::getPhoneNumber, phoneNumber))
116   - .isEmpty()) {
  114 + List<User> users = userMapper
  115 + .selectList(new QueryWrapper<User>().lambda().eq(User::getPhoneNumber, phoneNumber));
  116 + if (users.isEmpty()) {
117 117 throw new YtDataValidationException("电话号码未在系统注册,请联系你的管理员");
118 118 }
119 119 // 获取是否有验证码存在,防止发送数量过多
... ... @@ -140,8 +140,10 @@ public class YtSmsServiceImpl implements YtSmsService {
140 140 messageTemplateMapper.selectList(
141 141 new QueryWrapper<MessageTemplate>()
142 142 .lambda()
143   - .eq(MessageTemplate::getTemplatePurpose, purpose.name())
144   - .eq(MessageTemplate::getMessageType, MessageTypeEnum.PHONE_MESSAGE.name()));
  143 + .eq(MessageTemplate::getTenantId, users.get(0).getTenantId())
  144 + .eq(MessageTemplate::getStatus, 1)
  145 + .eq(MessageTemplate::getTemplatePurpose, purpose.name())
  146 + .eq(MessageTemplate::getMessageType, MessageTypeEnum.PHONE_MESSAGE.name()));
145 147 if (messageTemplates.isEmpty()) {
146 148 throw new YtDataValidationException("no sms provider config");
147 149 }
... ...
... ... @@ -7,7 +7,9 @@
7 7 SELECT sus.*
8 8 FROM iotfs_third_user base
9 9 LEFT JOIN sys_user sus ON base.app_user_id = sus.id
  10 + LEFT JOIN sys_tenant ste ON ste.tenant_id = sus.tenant_id
10 11 <where>
  12 + sus.account_expire_time > CURRENT_TIMESTAMP and ste.tenant_expire_time > CURRENT_TIMESTAMP
11 13 <if test="thirdId !=null and thirdId !=''">
12 14 AND base.third_user_id = #{thirdId}
13 15 </if>
... ...