From 1d1fd7711f9189f3f2aa06e3625f351ec63bd798 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 5 Dec 2018 15:35:46 +0200 Subject: [PATCH] Implemented permissions check using Access Control Service. --- .../server/controller/AlarmController.java | 4 +- .../server/controller/AssetController.java | 3 +- .../server/controller/BaseController.java | 156 ++++-------------- .../controller/DashboardController.java | 2 +- .../server/controller/DeviceController.java | 3 +- .../controller/EntityRelationController.java | 31 ++-- .../controller/EntityViewController.java | 3 +- .../server/controller/EventController.java | 4 +- .../server/controller/RpcController.java | 3 +- .../controller/RuleChainController.java | 19 ++- .../controller/TelemetryController.java | 23 +-- .../server/controller/TenantController.java | 11 +- .../server/controller/UserController.java | 49 +++--- .../controller/WidgetTypeController.java | 19 ++- .../controller/WidgetsBundleController.java | 14 +- .../permission/CustomerUserPremissions.java | 66 ++++++-- .../security/permission/Operation.java | 3 +- .../permission/PermissionChecker.java | 15 ++ .../service/security/permission/Resource.java | 5 +- .../permission/SysAdminPermissions.java | 34 ++++ .../permission/TenantAdminPermissions.java | 51 ++++++ .../DefaultTelemetryWebSocketService.java | 17 +- .../server/common/data/EntityType.java | 2 +- .../common/data/id/EntityIdFactory.java | 4 + .../server/common/data/id/WidgetTypeId.java | 9 +- .../common/data/id/WidgetsBundleId.java | 9 +- .../server/common/data/widget/WidgetType.java | 3 +- .../common/data/widget/WidgetsBundle.java | 3 +- msa/js-executor/package-lock.json | 2 +- msa/web-ui/package-lock.json | 2 +- ui/package-lock.json | 2 +- 31 files changed, 345 insertions(+), 226 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 16ba5a5c3f..b43ccf4bf9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -150,7 +150,7 @@ public class AlarmController extends BaseController { throw new ThingsboardException("Invalid alarms search query: Both parameters 'searchStatus' " + "and 'status' can't be specified at the same time!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); } - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); try { TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get()); @@ -177,7 +177,7 @@ public class AlarmController extends BaseController { throw new ThingsboardException("Invalid alarms search query: Both parameters 'searchStatus' " + "and 'status' can't be specified at the same time!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); } - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); try { return alarmService.findHighestAlarmSeverity(getCurrentUser().getTenantId(), entityId, alarmSearchStatus, alarmStatus); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 55e087b0b2..bd0ca65458 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -300,12 +300,11 @@ public class AssetController extends BaseController { checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getAssetTypes()); - checkEntityId(query.getParameters().getEntityId()); + checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { List assets = checkNotNull(assetService.findAssetsByQuery(getTenantId(), query).get()); assets = assets.stream().filter(asset -> { try { - //checkAsset(asset); accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset); return true; } catch (ThingsboardException e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 1888cfffe4..702fdd9cb2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -258,14 +259,9 @@ public abstract class BaseController { } } - void checkTenantId(TenantId tenantId) throws ThingsboardException { + void checkTenantId(TenantId tenantId, Operation operation) throws ThingsboardException { validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() != Authority.SYS_ADMIN && - (authUser.getTenantId() == null || !authUser.getTenantId().equals(tenantId))) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } + accessControlService.checkPermission(getCurrentUser(), tenantId, Resource.TENANT, operation, tenantId); } protected TenantId getTenantId() throws ThingsboardException { @@ -274,19 +270,11 @@ public abstract class BaseController { Customer checkCustomerId(CustomerId customerId, Operation operation) throws ThingsboardException { try { - /*SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() == Authority.SYS_ADMIN || - (authUser.getAuthority() != Authority.TENANT_ADMIN && - (authUser.getCustomerId() == null || !authUser.getCustomerId().equals(customerId)))) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - }*/ accessControlService.checkPermission(getCurrentUser(), getCurrentUser().getTenantId(), Resource.CUSTOMER, operation, customerId); if (customerId != null && !customerId.isNullUid()) { Customer customer = customerService.findCustomerById(getTenantId(), customerId); checkNotNull(customer); - //checkCustomer(customer); accessControlService.checkPermission(getCurrentUser(), Resource.CUSTOMER, operation, customerId, customer); return customer; } else { @@ -297,59 +285,49 @@ public abstract class BaseController { } } - /*private void checkCustomer(Customer customer) throws ThingsboardException { - checkNotNull(customer); - checkTenantId(customer.getTenantId()); - }*/ - - User checkUserId(UserId userId) throws ThingsboardException { + User checkUserId(UserId userId, Operation operation) throws ThingsboardException { try { validateId(userId, "Incorrect userId " + userId); User user = userService.findUserById(getCurrentUser().getTenantId(), userId); - checkUser(user); + checkNotNull(user); + accessControlService.checkPermission(getCurrentUser(), Resource.USER, operation, userId, user); return user; } catch (Exception e) { throw handleException(e, false); } } - private void checkUser(User user) throws ThingsboardException { - checkNotNull(user); - checkTenantId(user.getTenantId()); - if (user.getAuthority() == Authority.CUSTOMER_USER) { - checkCustomerId(user.getCustomerId()); - } - } - - protected void checkEntityId(EntityId entityId) throws ThingsboardException { + protected void checkEntityId(EntityId entityId, Operation operation) throws ThingsboardException { try { checkNotNull(entityId); validateId(entityId.getId(), "Incorrect entityId " + entityId); - SecurityUser authUser = getCurrentUser(); switch (entityId.getEntityType()) { case DEVICE: - checkDevice(deviceService.findDeviceById(authUser.getTenantId(), new DeviceId(entityId.getId()))); + checkDeviceId(new DeviceId(entityId.getId()), operation); return; case CUSTOMER: - checkCustomerId(new CustomerId(entityId.getId())); + checkCustomerId(new CustomerId(entityId.getId()), operation); return; case TENANT: - checkTenantId(new TenantId(entityId.getId())); + checkTenantId(new TenantId(entityId.getId()), operation); return; case RULE_CHAIN: - checkRuleChain(new RuleChainId(entityId.getId())); + checkRuleChain(new RuleChainId(entityId.getId()), operation); + return; + case RULE_NODE: + checkRuleNode(new RuleNodeId(entityId.getId()), operation); return; case ASSET: - checkAsset(assetService.findAssetById(authUser.getTenantId(), new AssetId(entityId.getId()))); + checkAssetId(new AssetId(entityId.getId()), operation); return; case DASHBOARD: - checkDashboardId(new DashboardId(entityId.getId())); + checkDashboardId(new DashboardId(entityId.getId()), operation); return; case USER: - checkUserId(new UserId(entityId.getId())); + checkUserId(new UserId(entityId.getId()), operation); return; case ENTITY_VIEW: - checkEntityViewId(new EntityViewId(entityId.getId())); + checkEntityViewId(new EntityViewId(entityId.getId()), operation); return; default: throw new IllegalArgumentException("Unsupported entity type: " + entityId.getEntityType()); @@ -364,7 +342,6 @@ public abstract class BaseController { validateId(deviceId, "Incorrect deviceId " + deviceId); Device device = deviceService.findDeviceById(getCurrentUser().getTenantId(), deviceId); checkNotNull(device); -// checkDevice(device); accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, operation, deviceId, device); return device; } catch (Exception e) { @@ -372,18 +349,11 @@ public abstract class BaseController { } } - /*protected void checkDevice(Device device) throws ThingsboardException { - checkNotNull(device); - checkTenantId(device.getTenantId()); - checkCustomerId(device.getCustomerId()); - }*/ - protected EntityView checkEntityViewId(EntityViewId entityViewId, Operation operation) throws ThingsboardException { try { validateId(entityViewId, "Incorrect entityViewId " + entityViewId); EntityView entityView = entityViewService.findEntityViewById(getCurrentUser().getTenantId(), entityViewId); checkNotNull(entityView); - //checkEntityView(entityView); accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, operation, entityViewId, entityView); return entityView; } catch (Exception e) { @@ -391,38 +361,24 @@ public abstract class BaseController { } } -/* protected void checkEntityView(EntityView entityView) throws ThingsboardException { - checkNotNull(entityView); - checkTenantId(entityView.getTenantId()); - checkCustomerId(entityView.getCustomerId()); - }*/ - Asset checkAssetId(AssetId assetId, Operation operation) throws ThingsboardException { try { validateId(assetId, "Incorrect assetId " + assetId); Asset asset = assetService.findAssetById(getCurrentUser().getTenantId(), assetId); checkNotNull(asset); accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, operation, assetId, asset); - //checkAsset(asset); return asset; } catch (Exception e) { throw handleException(e, false); } } - /*protected void checkAsset(Asset asset) throws ThingsboardException { - checkNotNull(asset); - checkTenantId(asset.getTenantId()); - checkCustomerId(asset.getCustomerId()); - }*/ - Alarm checkAlarmId(AlarmId alarmId, Operation operation) throws ThingsboardException { try { validateId(alarmId, "Incorrect alarmId " + alarmId); Alarm alarm = alarmService.findAlarmByIdAsync(getCurrentUser().getTenantId(), alarmId).get(); checkNotNull(alarm); accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarmId, alarm); - //checkAlarm(alarm); return alarm; } catch (Exception e) { throw handleException(e, false); @@ -435,67 +391,42 @@ public abstract class BaseController { AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(getCurrentUser().getTenantId(), alarmId).get(); checkNotNull(alarmInfo); accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarmId, alarmInfo); - //checkAlarm(alarmInfo); return alarmInfo; } catch (Exception e) { throw handleException(e, false); } } - /* protected void checkAlarm(Alarm alarm) throws ThingsboardException { - checkNotNull(alarm); - checkTenantId(alarm.getTenantId()); - }*/ - - WidgetsBundle checkWidgetsBundleId(WidgetsBundleId widgetsBundleId, boolean modify) throws ThingsboardException { + WidgetsBundle checkWidgetsBundleId(WidgetsBundleId widgetsBundleId, Operation operation) throws ThingsboardException { try { validateId(widgetsBundleId, "Incorrect widgetsBundleId " + widgetsBundleId); WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(getCurrentUser().getTenantId(), widgetsBundleId); - checkWidgetsBundle(widgetsBundle, modify); + checkNotNull(widgetsBundle); + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGETS_BUNDLE, operation, widgetsBundleId, widgetsBundle); return widgetsBundle; } catch (Exception e) { throw handleException(e, false); } } - private void checkWidgetsBundle(WidgetsBundle widgetsBundle, boolean modify) throws ThingsboardException { - checkNotNull(widgetsBundle); - if (widgetsBundle.getTenantId() != null && !widgetsBundle.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { - checkTenantId(widgetsBundle.getTenantId()); - } else if (modify && getCurrentUser().getAuthority() != Authority.SYS_ADMIN) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - } - - WidgetType checkWidgetTypeId(WidgetTypeId widgetTypeId, boolean modify) throws ThingsboardException { + WidgetType checkWidgetTypeId(WidgetTypeId widgetTypeId, Operation operation) throws ThingsboardException { try { validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId); WidgetType widgetType = widgetTypeService.findWidgetTypeById(getCurrentUser().getTenantId(), widgetTypeId); - checkWidgetType(widgetType, modify); + checkNotNull(widgetType); + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, operation, widgetTypeId, widgetType); return widgetType; } catch (Exception e) { throw handleException(e, false); } } - void checkWidgetType(WidgetType widgetType, boolean modify) throws ThingsboardException { - checkNotNull(widgetType); - if (widgetType.getTenantId() != null && !widgetType.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { - checkTenantId(widgetType.getTenantId()); - } else if (modify && getCurrentUser().getAuthority() != Authority.SYS_ADMIN) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - } - Dashboard checkDashboardId(DashboardId dashboardId, Operation operation) throws ThingsboardException { try { validateId(dashboardId, "Incorrect dashboardId " + dashboardId); Dashboard dashboard = dashboardService.findDashboardById(getCurrentUser().getTenantId(), dashboardId); checkNotNull(dashboard); accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation, dashboardId, dashboard); - //checkDashboard(dashboard); return dashboard; } catch (Exception e) { throw handleException(e, false); @@ -508,25 +439,12 @@ public abstract class BaseController { DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(getCurrentUser().getTenantId(), dashboardId); checkNotNull(dashboardInfo); accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation, dashboardId, dashboardInfo); - //checkDashboard(dashboardInfo); return dashboardInfo; } catch (Exception e) { throw handleException(e, false); } } - /*private void checkDashboard(DashboardInfo dashboard) throws ThingsboardException { - checkNotNull(dashboard); - checkTenantId(dashboard.getTenantId()); - SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() == Authority.CUSTOMER_USER) { - if (!dashboard.isAssignedToCustomer(authUser.getCustomerId())) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - } - }*/ - ComponentDescriptor checkComponentDescriptorByClazz(String clazz) throws ThingsboardException { try { log.debug("[{}] Lookup component descriptor", clazz); @@ -554,24 +472,22 @@ public abstract class BaseController { } } - protected RuleChain checkRuleChain(RuleChainId ruleChainId) throws ThingsboardException { - checkNotNull(ruleChainId); - return checkRuleChain(ruleChainService.findRuleChainById(getCurrentUser().getTenantId(), ruleChainId)); - } - - protected RuleChain checkRuleChain(RuleChain ruleChain) throws ThingsboardException { + protected RuleChain checkRuleChain(RuleChainId ruleChainId, Operation operation) throws ThingsboardException { + validateId(ruleChainId, "Incorrect ruleChainId " + ruleChainId); + RuleChain ruleChain = ruleChainService.findRuleChainById(getCurrentUser().getTenantId(), ruleChainId); checkNotNull(ruleChain); - SecurityUser authUser = getCurrentUser(); - TenantId tenantId = ruleChain.getTenantId(); - validateId(tenantId, INCORRECT_TENANT_ID + tenantId); - if (authUser.getAuthority() != Authority.TENANT_ADMIN || - !authUser.getTenantId().equals(tenantId)) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } + accessControlService.checkPermission(getCurrentUser(), Resource.RULE_CHAIN, operation, ruleChainId, ruleChain); return ruleChain; } + protected RuleNode checkRuleNode(RuleNodeId ruleNodeId, Operation operation) throws ThingsboardException { + validateId(ruleNodeId, "Incorrect ruleNodeId " + ruleNodeId); + RuleNode ruleNode = ruleChainService.findRuleNodeById(getTenantId(), ruleNodeId); + checkNotNull(ruleNode); + checkRuleChain(ruleNode.getRuleChainId(), operation); + return ruleNode; + } + protected String constructBaseUrl(HttpServletRequest request) { String scheme = request.getScheme(); diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 033c2a2534..800fe23c13 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -427,7 +427,7 @@ public class DashboardController extends BaseController { @RequestParam(required = false) String textOffset) throws ThingsboardException { try { TenantId tenantId = new TenantId(toUUID(strTenantId)); - checkTenantId(tenantId); + checkTenantId(tenantId, Operation.READ); TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); return checkNotNull(dashboardService.findDashboardsByTenantId(tenantId, pageLink)); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 14c66afcff..b9a8551470 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -349,12 +349,11 @@ public class DeviceController extends BaseController { checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getDeviceTypes()); - checkEntityId(query.getParameters().getEntityId()); + checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { List devices = checkNotNull(deviceService.findDevicesByQuery(getCurrentUser().getTenantId(), query).get()); devices = devices.stream().filter(device -> { try { - //checkDevice(device); accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, Operation.READ, device.getId(), device); return true; } catch (ThingsboardException e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 04d35c522e..68c6281e20 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationInfo; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import org.thingsboard.server.service.security.permission.Operation; import java.util.List; @@ -55,8 +56,8 @@ public class EntityRelationController extends BaseController { public void saveRelation(@RequestBody EntityRelation relation) throws ThingsboardException { try { checkNotNull(relation); - checkEntityId(relation.getFrom()); - checkEntityId(relation.getTo()); + checkEntityId(relation.getFrom(), Operation.WRITE); + checkEntityId(relation.getTo(), Operation.WRITE); if (relation.getTypeGroup() == null) { relation.setTypeGroup(RelationTypeGroup.COMMON); } @@ -89,8 +90,8 @@ public class EntityRelationController extends BaseController { checkParameter(TO_TYPE, strToType); EntityId fromId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); EntityId toId = EntityIdFactory.getByTypeAndId(strToType, strToId); - checkEntityId(fromId); - checkEntityId(toId); + checkEntityId(fromId, Operation.WRITE); + checkEntityId(toId, Operation.WRITE); RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup); try { @@ -119,7 +120,7 @@ public class EntityRelationController extends BaseController { checkParameter("entityId", strId); checkParameter("entityType", strType); EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.WRITE); try { relationService.deleteEntityRelations(getTenantId(), entityId); logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null); @@ -145,8 +146,8 @@ public class EntityRelationController extends BaseController { checkParameter(TO_TYPE, strToType); EntityId fromId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); EntityId toId = EntityIdFactory.getByTypeAndId(strToType, strToId); - checkEntityId(fromId); - checkEntityId(toId); + checkEntityId(fromId, Operation.READ); + checkEntityId(toId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); return checkNotNull(relationService.getRelation(getTenantId(), fromId, toId, strRelationType, typeGroup)); } catch (Exception e) { @@ -163,7 +164,7 @@ public class EntityRelationController extends BaseController { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findByFrom(getTenantId(), entityId, typeGroup)); @@ -181,7 +182,7 @@ public class EntityRelationController extends BaseController { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findInfoByFrom(getTenantId(), entityId, typeGroup).get()); @@ -201,7 +202,7 @@ public class EntityRelationController extends BaseController { checkParameter(FROM_TYPE, strFromType); checkParameter(RELATION_TYPE, strRelationType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findByFromAndType(getTenantId(), entityId, strRelationType, typeGroup)); @@ -219,7 +220,7 @@ public class EntityRelationController extends BaseController { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findByTo(getTenantId(), entityId, typeGroup)); @@ -237,7 +238,7 @@ public class EntityRelationController extends BaseController { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findInfoByTo(getTenantId(), entityId, typeGroup).get()); @@ -257,7 +258,7 @@ public class EntityRelationController extends BaseController { checkParameter(TO_TYPE, strToType); checkParameter(RELATION_TYPE, strRelationType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { return checkNotNull(relationService.findByToAndType(getTenantId(), entityId, strRelationType, typeGroup)); @@ -273,7 +274,7 @@ public class EntityRelationController extends BaseController { checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getFilters()); - checkEntityId(query.getParameters().getEntityId()); + checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { return checkNotNull(relationService.findByQuery(getTenantId(), query).get()); } catch (Exception e) { @@ -288,7 +289,7 @@ public class EntityRelationController extends BaseController { checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getFilters()); - checkEntityId(query.getParameters().getEntityId()); + checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { return checkNotNull(relationService.findInfoByQuery(getTenantId(), query).get()); } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index 0ac0e85f75..831cb9e9d0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -311,12 +311,11 @@ public class EntityViewController extends BaseController { checkNotNull(query); checkNotNull(query.getParameters()); checkNotNull(query.getEntityViewTypes()); - checkEntityId(query.getParameters().getEntityId()); + checkEntityId(query.getParameters().getEntityId(), Operation.READ); try { List entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(getTenantId(), query).get()); entityViews = entityViews.stream().filter(entityView -> { try { - //checkEntityView(entityView); accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, Operation.READ, entityView.getId(), entityView); return true; } catch (ThingsboardException e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index 66b01d31d4..941a2ca369 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -63,7 +63,7 @@ public class EventController extends BaseController { TenantId tenantId = new TenantId(toUUID(strTenantId)); EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); return checkNotNull(eventService.findEvents(tenantId, entityId, eventType, pageLink)); @@ -91,7 +91,7 @@ public class EventController extends BaseController { TenantId tenantId = new TenantId(toUUID(strTenantId)); EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId); - checkEntityId(entityId); + checkEntityId(entityId, Operation.READ); TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); return checkNotNull(eventService.findEvents(tenantId, entityId, pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcController.java b/application/src/main/java/org/thingsboard/server/controller/RpcController.java index a0d388c2ce..aa1330d383 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcController.java @@ -47,6 +47,7 @@ import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; import org.thingsboard.server.service.rpc.LocalRequestMetaData; import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.service.security.model.SecurityUser; +import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity; import javax.annotation.Nullable; @@ -118,7 +119,7 @@ public class RpcController extends BaseController { final DeferredResult response = new DeferredResult<>(); long timeout = System.currentTimeMillis() + (cmd.getTimeout() != null ? cmd.getTimeout() : DEFAULT_TIMEOUT); ToDeviceRpcRequestBody body = new ToDeviceRpcRequestBody(cmd.getMethodName(), cmd.getRequestData()); - accessValidator.validate(currentUser, deviceId, new HttpValidationCallback(response, new FutureCallback>() { + accessValidator.validate(currentUser, Operation.RPC_CALL, deviceId, new HttpValidationCallback(response, new FutureCallback>() { @Override public void onSuccess(@Nullable DeferredResult result) { ToDeviceRpcRequest rpcRequest = new ToDeviceRpcRequest(UUID.randomUUID(), diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 4d88500ffb..f4caa7c1f7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -52,6 +52,8 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.service.script.JsInvokeService; import org.thingsboard.server.service.script.RuleNodeJsScriptEngine; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; import java.util.List; import java.util.Map; @@ -80,7 +82,7 @@ public class RuleChainController extends BaseController { checkParameter(RULE_CHAIN_ID, strRuleChainId); try { RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - return checkRuleChain(ruleChainId); + return checkRuleChain(ruleChainId, Operation.READ); } catch (Exception e) { throw handleException(e); } @@ -93,7 +95,7 @@ public class RuleChainController extends BaseController { checkParameter(RULE_CHAIN_ID, strRuleChainId); try { RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - checkRuleChain(ruleChainId); + checkRuleChain(ruleChainId, Operation.READ); return ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChainId); } catch (Exception e) { throw handleException(e); @@ -108,6 +110,12 @@ public class RuleChainController extends BaseController { try { boolean created = ruleChain.getId() == null; ruleChain.setTenantId(getCurrentUser().getTenantId()); + + Operation operation = created ? Operation.CREATE : Operation.WRITE; + + accessControlService.checkPermission(getCurrentUser(), Resource.RULE_CHAIN, operation, + ruleChain.getId(), ruleChain); + RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); actorService.onEntityStateChange(ruleChain.getTenantId(), savedRuleChain.getId(), @@ -134,7 +142,7 @@ public class RuleChainController extends BaseController { checkParameter(RULE_CHAIN_ID, strRuleChainId); try { RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.WRITE); TenantId tenantId = getCurrentUser().getTenantId(); RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId); if (ruleChainService.setRootRuleChain(getTenantId(), ruleChainId)) { @@ -171,7 +179,7 @@ public class RuleChainController extends BaseController { @ResponseBody public RuleChainMetaData saveRuleChainMetaData(@RequestBody RuleChainMetaData ruleChainMetaData) throws ThingsboardException { try { - RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId()); + RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId(), Operation.WRITE); RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(getTenantId(), ruleChainMetaData)); actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); @@ -214,7 +222,7 @@ public class RuleChainController extends BaseController { checkParameter(RULE_CHAIN_ID, strRuleChainId); try { RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); - RuleChain ruleChain = checkRuleChain(ruleChainId); + RuleChain ruleChain = checkRuleChain(ruleChainId, Operation.DELETE); ruleChainService.deleteRuleChainById(getTenantId(), ruleChainId); @@ -240,6 +248,7 @@ public class RuleChainController extends BaseController { checkParameter(RULE_NODE_ID, strRuleNodeId); try { RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId)); + checkRuleNode(ruleNodeId, Operation.READ); TenantId tenantId = getCurrentUser().getTenantId(); List events = eventService.findLatestEvents(tenantId, ruleNodeId, DataConstants.DEBUG_RULE_NODE, 2); JsonNode result = null; diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index bebd2cc4d3..44553c8631 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -67,6 +67,7 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.service.security.model.SecurityUser; +import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.AttributeData; import org.thingsboard.server.service.telemetry.TsData; import org.thingsboard.server.service.telemetry.exception.InvalidParametersException; @@ -122,7 +123,7 @@ public class TelemetryController extends BaseController { @ResponseBody public DeferredResult getAttributeKeys( @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, this::getAttributeKeysCallback); + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback); } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @@ -131,7 +132,7 @@ public class TelemetryController extends BaseController { public DeferredResult getAttributeKeysByScope( @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr , @PathVariable("scope") String scope) throws ThingsboardException { - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); } @@ -142,7 +143,7 @@ public class TelemetryController extends BaseController { @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr, @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); } @@ -154,7 +155,7 @@ public class TelemetryController extends BaseController { @PathVariable("scope") String scope, @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); } @@ -163,7 +164,7 @@ public class TelemetryController extends BaseController { @ResponseBody public DeferredResult getTimeseriesKeys( @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result))); } @@ -175,7 +176,7 @@ public class TelemetryController extends BaseController { @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr)); } @@ -192,7 +193,7 @@ public class TelemetryController extends BaseController { @RequestParam(name = "limit", defaultValue = "100") Integer limit, @RequestParam(name = "agg", defaultValue = "NONE") String aggStr ) throws ThingsboardException { - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> { // If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr); @@ -283,7 +284,7 @@ public class TelemetryController extends BaseController { deleteToTs = endTs; } - return accessValidator.validateEntityAndCallback(user, entityIdStr, (result, tenantId, entityId) -> { + return accessValidator.validateEntityAndCallback(user, Operation.WRITE_TELEMETRY, entityIdStr, (result, tenantId, entityId) -> { List deleteTsKvQueries = new ArrayList<>(); for (String key : keys) { deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted)); @@ -336,7 +337,7 @@ public class TelemetryController extends BaseController { if (DataConstants.SERVER_SCOPE.equals(scope) || DataConstants.SHARED_SCOPE.equals(scope) || DataConstants.CLIENT_SCOPE.equals(scope)) { - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdStr, (result, tenantId, entityId) -> { + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdStr, (result, tenantId, entityId) -> { ListenableFuture> future = attributesService.removeAll(user.getTenantId(), entityId, scope, keys); Futures.addCallback(future, new FutureCallback>() { @Override @@ -375,7 +376,7 @@ public class TelemetryController extends BaseController { return getImmediateDeferredResult("No attributes data found in request body!", HttpStatus.BAD_REQUEST); } SecurityUser user = getCurrentUser(); - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, tenantId, entityId) -> { + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdSrc, (result, tenantId, entityId) -> { tsSubService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { @@ -424,7 +425,7 @@ public class TelemetryController extends BaseController { return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST); } SecurityUser user = getCurrentUser(); - return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, tenantId, entityId) -> { + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_TELEMETRY, entityIdSrc, (result, tenantId, entityId) -> { tsSubService.saveAndNotify(tenantId, entityId, entries, ttl, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index 155f0a1095..a48bc65d6d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -35,6 +35,8 @@ import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.service.install.InstallScripts; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; @RestController @RequestMapping("/api") @@ -54,7 +56,7 @@ public class TenantController extends BaseController { checkParameter("tenantId", strTenantId); try { TenantId tenantId = new TenantId(toUUID(strTenantId)); - checkTenantId(tenantId); + checkTenantId(tenantId, Operation.READ); return checkNotNull(tenantService.findTenantById(tenantId)); } catch (Exception e) { throw handleException(e); @@ -67,6 +69,12 @@ public class TenantController extends BaseController { public Tenant saveTenant(@RequestBody Tenant tenant) throws ThingsboardException { try { boolean newTenant = tenant.getId() == null; + + Operation operation = newTenant ? Operation.CREATE : Operation.WRITE; + + accessControlService.checkPermission(getCurrentUser(), tenant.getId(), Resource.TENANT, operation, + tenant.getId()); + tenant = checkNotNull(tenantService.saveTenant(tenant)); if (newTenant) { installScripts.createDefaultRuleChains(tenant.getId()); @@ -84,6 +92,7 @@ public class TenantController extends BaseController { checkParameter("tenantId", strTenantId); try { TenantId tenantId = new TenantId(toUUID(strTenantId)); + checkTenantId(tenantId, Operation.DELETE); tenantService.deleteTenant(tenantId); actorService.onEntityStateChange(tenantId, tenantId, ComponentLifecycleEvent.DELETED); diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index bea704ec9d..ebf92bb3fe 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -49,6 +49,8 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtToken; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; import javax.servlet.http.HttpServletRequest; @@ -81,12 +83,7 @@ public class UserController extends BaseController { checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); - SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(userId)) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - return checkUserId(userId); + return checkUserId(userId, Operation.READ); } catch (Exception e) { throw handleException(e); } @@ -105,14 +102,13 @@ public class UserController extends BaseController { public JsonNode getUserToken(@PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); try { - UserId userId = new UserId(toUUID(strUserId)); - SecurityUser authUser = getCurrentUser(); - User user = userService.findUserById(authUser.getTenantId(), userId); - if (!userTokenAccessEnabled || (authUser.getAuthority() == Authority.SYS_ADMIN && user.getAuthority() != Authority.TENANT_ADMIN) - || (authUser.getAuthority() == Authority.TENANT_ADMIN && !authUser.getTenantId().equals(user.getTenantId()))) { + if (!userTokenAccessEnabled) { throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } + UserId userId = new UserId(toUUID(strUserId)); + SecurityUser authUser = getCurrentUser(); + User user = checkUserId(userId, Operation.READ); UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); UserCredentials credentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), userId); SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal); @@ -135,17 +131,20 @@ public class UserController extends BaseController { @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { try { - SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(user.getId())) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - boolean sendEmail = user.getId() == null && sendActivationMail; + if (getCurrentUser().getAuthority() == Authority.TENANT_ADMIN) { user.setTenantId(getCurrentUser().getTenantId()); } + + Operation operation = user.getId() == null ? Operation.CREATE : Operation.WRITE; + + accessControlService.checkPermission(getCurrentUser(), Resource.USER, operation, + user.getId(), user); + + boolean sendEmail = user.getId() == null && sendActivationMail; User savedUser = checkNotNull(userService.saveUser(user)); if (sendEmail) { + SecurityUser authUser = getCurrentUser(); UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), savedUser.getId()); String baseUrl = constructBaseUrl(request); String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, @@ -181,6 +180,10 @@ public class UserController extends BaseController { HttpServletRequest request) throws ThingsboardException { try { User user = checkNotNull(userService.findUserByEmail(getCurrentUser().getTenantId(), email)); + + accessControlService.checkPermission(getCurrentUser(), Resource.USER, Operation.READ, + user.getId(), user); + UserCredentials userCredentials = userService.findUserCredentialsByUserId(getCurrentUser().getTenantId(), user.getId()); if (!userCredentials.isEnabled()) { String baseUrl = constructBaseUrl(request); @@ -204,13 +207,9 @@ public class UserController extends BaseController { checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); + User user = checkUserId(userId, Operation.READ); SecurityUser authUser = getCurrentUser(); - if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(userId)) { - throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, - ThingsboardErrorCode.PERMISSION_DENIED); - } - User user = checkUserId(userId); - UserCredentials userCredentials = userService.findUserCredentialsByUserId(getCurrentUser().getTenantId(), user.getId()); + UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), user.getId()); if (!userCredentials.isEnabled()) { String baseUrl = constructBaseUrl(request); String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, @@ -231,7 +230,7 @@ public class UserController extends BaseController { checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); - User user = checkUserId(userId); + User user = checkUserId(userId, Operation.DELETE); userService.deleteUser(getCurrentUser().getTenantId(), userId); logEntityAction(userId, user, @@ -278,7 +277,7 @@ public class UserController extends BaseController { checkParameter("customerId", strCustomerId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); - checkCustomerId(customerId); + checkCustomerId(customerId, Operation.READ); TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(userService.findCustomerUsers(tenantId, customerId, pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index 9647450b7c..a3651fa74b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -31,6 +31,8 @@ import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; import java.util.List; @@ -45,7 +47,7 @@ public class WidgetTypeController extends BaseController { checkParameter("widgetTypeId", strWidgetTypeId); try { WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); - return checkWidgetTypeId(widgetTypeId, false); + return checkWidgetTypeId(widgetTypeId, Operation.READ); } catch (Exception e) { throw handleException(e); } @@ -57,10 +59,16 @@ public class WidgetTypeController extends BaseController { public WidgetType saveWidgetType(@RequestBody WidgetType widgetType) throws ThingsboardException { try { if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) { - widgetType.setTenantId(new TenantId(ModelConstants.NULL_UUID)); + widgetType.setTenantId(TenantId.SYS_TENANT_ID); } else { widgetType.setTenantId(getCurrentUser().getTenantId()); } + + Operation operation = widgetType.getId() == null ? Operation.CREATE : Operation.WRITE; + + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, operation, + widgetType.getId(), widgetType); + return checkNotNull(widgetTypeService.saveWidgetType(widgetType)); } catch (Exception e) { throw handleException(e); @@ -74,7 +82,7 @@ public class WidgetTypeController extends BaseController { checkParameter("widgetTypeId", strWidgetTypeId); try { WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); - checkWidgetTypeId(widgetTypeId, true); + checkWidgetTypeId(widgetTypeId, Operation.DELETE); widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId); } catch (Exception e) { throw handleException(e); @@ -90,7 +98,7 @@ public class WidgetTypeController extends BaseController { try { TenantId tenantId; if (isSystem) { - tenantId = new TenantId(ModelConstants.NULL_UUID); + tenantId = TenantId.SYS_TENANT_ID; } else { tenantId = getCurrentUser().getTenantId(); } @@ -115,7 +123,8 @@ public class WidgetTypeController extends BaseController { tenantId = getCurrentUser().getTenantId(); } WidgetType widgetType = widgetTypeService.findWidgetTypeByTenantIdBundleAliasAndAlias(tenantId, bundleAlias, alias); - checkWidgetType(widgetType, false); + checkNotNull(widgetType); + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, Operation.READ, widgetType.getId(), widgetType); return widgetType; } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 31f444d079..689c37f4a6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -33,6 +33,8 @@ import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.service.security.permission.Operation; +import org.thingsboard.server.service.security.permission.Resource; import java.util.List; @@ -47,7 +49,7 @@ public class WidgetsBundleController extends BaseController { checkParameter("widgetsBundleId", strWidgetsBundleId); try { WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); - return checkWidgetsBundleId(widgetsBundleId, false); + return checkWidgetsBundleId(widgetsBundleId, Operation.READ); } catch (Exception e) { throw handleException(e); } @@ -59,10 +61,16 @@ public class WidgetsBundleController extends BaseController { public WidgetsBundle saveWidgetsBundle(@RequestBody WidgetsBundle widgetsBundle) throws ThingsboardException { try { if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) { - widgetsBundle.setTenantId(new TenantId(ModelConstants.NULL_UUID)); + widgetsBundle.setTenantId(TenantId.SYS_TENANT_ID); } else { widgetsBundle.setTenantId(getCurrentUser().getTenantId()); } + + Operation operation = widgetsBundle.getId() == null ? Operation.CREATE : Operation.WRITE; + + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGETS_BUNDLE, operation, + widgetsBundle.getId(), widgetsBundle); + return checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); } catch (Exception e) { throw handleException(e); @@ -76,7 +84,7 @@ public class WidgetsBundleController extends BaseController { checkParameter("widgetsBundleId", strWidgetsBundleId); try { WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); - checkWidgetsBundleId(widgetsBundleId, true); + checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java index 4c67aa3df0..87fe80d44b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java @@ -1,18 +1,29 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.security.permission; -import org.thingsboard.server.common.data.Dashboard; -import org.thingsboard.server.common.data.DashboardInfo; -import org.thingsboard.server.common.data.HasCustomerId; -import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.*; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.service.security.model.SecurityUser; -import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; public class CustomerUserPremissions extends HashMap { @@ -24,10 +35,13 @@ public class CustomerUserPremissions extends HashMap(Operation.READ) { + new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) { @Override public boolean hasPermission(SecurityUser user, Operation operation, DashboardId dashboardId, DashboardInfo dashboard) { @@ -83,4 +97,34 @@ public class CustomerUserPremissions extends HashMap() { + + @Override + public boolean hasPermission(SecurityUser user, Operation operation, UserId userId, User userEntity) { + if (userEntity.getAuthority() != Authority.CUSTOMER_USER) { + return false; + } + if (!user.getId().equals(userId)) { + return false; + } + return true; + } + + }; + + private static final PermissionChecker widgetsPermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ) { + + @Override + public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { + if (!super.hasPermission(user, operation, entityId, entity)) { + return false; + } + if (entity.getTenantId() == null || entity.getTenantId().isNullUid() || user.getTenantId().equals(entity.getTenantId())) { + return true; + } + return true; + } + + }; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Operation.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Operation.java index d5254e737e..e8ad7f0a00 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/Operation.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Operation.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.security.permission; public enum Operation { - ALL, CREATE, READ, WRITE, DELETE, ASSIGN_TO_CUSTOMER, UNASSIGN_FROM_CUSTOMER + ALL, CREATE, READ, WRITE, DELETE, ASSIGN_TO_CUSTOMER, UNASSIGN_FROM_CUSTOMER, RPC_CALL, + READ_ATTRIBUTES, WRITE_ATTRIBUTES, READ_TELEMETRY, WRITE_TELEMETRY } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java b/application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java index 921b7d96c4..3b14890732 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.security.permission; import org.thingsboard.server.common.data.HasCustomerId; diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java index 8cf4dc2613..7038b535d2 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java @@ -28,7 +28,10 @@ public enum Resource { DASHBOARD(EntityType.DASHBOARD), ENTITY_VIEW(EntityType.ENTITY_VIEW), TENANT(EntityType.TENANT), - RULE_CHAIN(EntityType.RULE_CHAIN); + RULE_CHAIN(EntityType.RULE_CHAIN), + USER(EntityType.USER), + WIDGETS_BUNDLE(EntityType.WIDGETS_BUNDLE), + WIDGET_TYPE(EntityType.WIDGET_TYPE); private final EntityType entityType; diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java index 251cb9b2f0..285ebee5aa 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java @@ -1,8 +1,26 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.security.permission; import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.service.security.model.SecurityUser; import java.util.HashMap; @@ -15,6 +33,9 @@ public class SysAdminPermissions extends HashMap { put(Resource.DASHBOARD, new PermissionChecker.GenericPermissionChecker(Operation.READ)); put(Resource.TENANT, PermissionChecker.allowAllPermissionChecker); put(Resource.RULE_CHAIN, systemEntityPermissionChecker); + put(Resource.USER, userPermissionChecker); + put(Resource.WIDGETS_BUNDLE, systemEntityPermissionChecker); + put(Resource.WIDGET_TYPE, systemEntityPermissionChecker); } private static final PermissionChecker systemEntityPermissionChecker = new PermissionChecker() { @@ -36,4 +57,17 @@ public class SysAdminPermissions extends HashMap { return true; } }; + + private static final PermissionChecker userPermissionChecker = new PermissionChecker() { + + @Override + public boolean hasPermission(SecurityUser user, Operation operation, UserId userId, User userEntity) { + if (userEntity.getAuthority() == Authority.CUSTOMER_USER) { + return false; + } + return true; + } + + }; + } diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java index c8e208f354..c5d9f372af 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java @@ -1,8 +1,26 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.thingsboard.server.service.security.permission; import org.thingsboard.server.common.data.HasTenantId; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.service.security.model.SecurityUser; import java.util.HashMap; @@ -19,6 +37,9 @@ public class TenantAdminPermissions extends HashMap put(Resource.ENTITY_VIEW, tenantEntityPermissionChecker); put(Resource.TENANT, tenantPermissionChecker); put(Resource.RULE_CHAIN, tenantEntityPermissionChecker); + put(Resource.USER, userPermissionChecker); + put(Resource.WIDGETS_BUNDLE, widgetsPermissionChecker); + put(Resource.WIDGET_TYPE, widgetsPermissionChecker); } public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() { @@ -56,4 +77,34 @@ public class TenantAdminPermissions extends HashMap } }; + + private static final PermissionChecker userPermissionChecker = new PermissionChecker() { + + @Override + public boolean hasPermission(SecurityUser user, Operation operation, UserId userId, User userEntity) { + if (userEntity.getAuthority() == Authority.SYS_ADMIN) { + return false; + } + if (!user.getTenantId().equals(userEntity.getTenantId())) { + return false; + } + return true; + } + + }; + + private static final PermissionChecker widgetsPermissionChecker = new PermissionChecker() { + + @Override + public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { + if (entity.getTenantId() == null || entity.getTenantId().isNullUid()) { + return operation == Operation.READ; + } + if (!user.getTenantId().equals(entity.getTenantId())) { + return false; + } + return true; + } + + }; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java index 6bda32dbff..83e7cff1c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java @@ -48,6 +48,7 @@ import org.thingsboard.server.service.security.ValidationCallback; import org.thingsboard.server.service.security.ValidationResult; import org.thingsboard.server.service.security.ValidationResultCode; import org.thingsboard.server.service.security.model.UserPrincipal; +import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.cmd.AttributesSubscriptionCmd; import org.thingsboard.server.service.telemetry.cmd.GetHistoryCmd; import org.thingsboard.server.service.telemetry.cmd.SubscriptionCmd; @@ -354,9 +355,9 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi }; if (StringUtils.isEmpty(cmd.getScope())) { - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, keys, callback)); + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_ATTRIBUTES, entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, keys, callback)); } else { - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), keys, callback)); + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_ATTRIBUTES, entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), keys, callback)); } } @@ -406,7 +407,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi sendWsMsg(sessionRef, update); } }; - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_TELEMETRY, entityId, on(r -> Futures.addCallback(tsService.findAll(sessionRef.getSecurityCtx().getTenantId(), entityId, queries), callback, executor), callback::onFailure)); } @@ -436,9 +437,9 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi if (StringUtils.isEmpty(cmd.getScope())) { - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, callback)); + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_ATTRIBUTES, entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, callback)); } else { - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), callback)); + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_ATTRIBUTES, entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), callback)); } } @@ -474,14 +475,14 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi getLimit(cmd.getLimit()), getAggregation(cmd.getAgg()))).collect(Collectors.toList()); final FutureCallback> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys); - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_TELEMETRY, entityId, on(r -> Futures.addCallback(tsService.findAll(sessionRef.getSecurityCtx().getTenantId(), entityId, queries), callback, executor), callback::onFailure)); } else { List keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); startTs = System.currentTimeMillis(); log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), entityId); final FutureCallback> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys); - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_TELEMETRY, entityId, on(r -> Futures.addCallback(tsService.findLatest(sessionRef.getSecurityCtx().getTenantId(), entityId, keys), callback, executor), callback::onFailure)); } } @@ -511,7 +512,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi sendWsMsg(sessionRef, update); } }; - accessValidator.validate(sessionRef.getSecurityCtx(), entityId, + accessValidator.validate(sessionRef.getSecurityCtx(), Operation.READ_TELEMETRY, entityId, on(r -> Futures.addCallback(tsService.findAllLatest(sessionRef.getSecurityCtx().getTenantId(), entityId), callback, executor), callback::onFailure)); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index ef4994adda..2cf8374a1b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -19,5 +19,5 @@ package org.thingsboard.server.common.data; * @author Andrew Shvayka */ public enum EntityType { - TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW + TENANT, CUSTOMER, USER, DASHBOARD, ASSET, DEVICE, ALARM, RULE_CHAIN, RULE_NODE, ENTITY_VIEW, WIDGETS_BUNDLE, WIDGET_TYPE } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java index 4e35c0b2df..1ba1af605d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java @@ -59,6 +59,10 @@ public class EntityIdFactory { return new RuleNodeId(uuid); case ENTITY_VIEW: return new EntityViewId(uuid); + case WIDGETS_BUNDLE: + return new WidgetsBundleId(uuid); + case WIDGET_TYPE: + return new WidgetTypeId(uuid); } throw new IllegalArgumentException("EntityType " + type + " is not supported!"); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java index df04222551..23cf1bafdd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java @@ -18,9 +18,11 @@ package org.thingsboard.server.common.data.id; import java.util.UUID; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import org.thingsboard.server.common.data.EntityType; -public final class WidgetTypeId extends UUIDBased { +public final class WidgetTypeId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -29,4 +31,9 @@ public final class WidgetTypeId extends UUIDBased { super(id); } + @JsonIgnore + @Override + public EntityType getEntityType() { + return EntityType.WIDGET_TYPE; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java index 7d8e853a08..c0a5380c6d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java @@ -18,9 +18,11 @@ package org.thingsboard.server.common.data.id; import java.util.UUID; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import org.thingsboard.server.common.data.EntityType; -public final class WidgetsBundleId extends UUIDBased { +public final class WidgetsBundleId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -29,4 +31,9 @@ public final class WidgetsBundleId extends UUIDBased { super(id); } + @JsonIgnore + @Override + public EntityType getEntityType() { + return EntityType.WIDGETS_BUNDLE; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java index fc21bdc648..e488a5a994 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java @@ -18,11 +18,12 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.databind.JsonNode; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; +import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; @EqualsAndHashCode(callSuper = true) -public class WidgetType extends BaseData { +public class WidgetType extends BaseData implements HasTenantId { private static final long serialVersionUID = 8388684344603660756L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java index 01112b3fe0..50486179e3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java @@ -15,13 +15,14 @@ */ package org.thingsboard.server.common.data.widget; +import org.thingsboard.server.common.data.HasTenantId; import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import java.util.Arrays; -public class WidgetsBundle extends SearchTextBased { +public class WidgetsBundle extends SearchTextBased implements HasTenantId { private static final long serialVersionUID = -7627368878362410489L; diff --git a/msa/js-executor/package-lock.json b/msa/js-executor/package-lock.json index f232cca82b..1af16309a7 100644 --- a/msa/js-executor/package-lock.json +++ b/msa/js-executor/package-lock.json @@ -1,6 +1,6 @@ { "name": "thingsboard-js-executor", - "version": "2.2.1", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/msa/web-ui/package-lock.json b/msa/web-ui/package-lock.json index 11cf32b3bd..c50ee7d073 100644 --- a/msa/web-ui/package-lock.json +++ b/msa/web-ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "thingsboard-web-ui", - "version": "2.2.1", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/ui/package-lock.json b/ui/package-lock.json index 93adbd1dac..7c0604dac5 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "thingsboard", - "version": "2.2.1", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": {