thingsboard-developers
Changes
application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java 2(+1 -1)
application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java 86(+86 -0)
application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java 95(+95 -0)
application/src/main/java/org/thingsboard/server/service/security/permission/Operation.java 2(+1 -1)
application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java 72(+72 -0)
application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java 10(+9 -1)
application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java 39(+39 -0)
Details
diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java
index 8c59c86..b7b6f0c 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java
@@ -28,6 +28,8 @@ import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.settings.AdminSettingsService;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.update.UpdateService;
import org.thingsboard.server.service.update.model.UpdateMessage;
@@ -49,6 +51,7 @@ public class AdminController extends BaseController {
@ResponseBody
public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException {
try {
+ accessControlService.checkPermission(getCurrentUser(), TenantId.SYS_TENANT_ID, Resource.ADMIN_SETTINGS, Operation.READ);
return checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key));
} catch (Exception e) {
throw handleException(e);
@@ -60,6 +63,7 @@ public class AdminController extends BaseController {
@ResponseBody
public AdminSettings saveAdminSettings(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
try {
+ accessControlService.checkPermission(getCurrentUser(), TenantId.SYS_TENANT_ID, Resource.ADMIN_SETTINGS, Operation.WRITE);
adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
if (adminSettings.getKey().equals("mail")) {
mailService.updateMailConfiguration();
@@ -74,6 +78,7 @@ public class AdminController extends BaseController {
@RequestMapping(value = "/settings/testMail", method = RequestMethod.POST)
public void sendTestMail(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
try {
+ accessControlService.checkPermission(getCurrentUser(), TenantId.SYS_TENANT_ID, Resource.ADMIN_SETTINGS, Operation.READ);
adminSettings = checkNotNull(adminSettings);
if (adminSettings.getKey().equals("mail")) {
String email = getCurrentUser().getEmail();
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 6261e74..16ba5a5 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java
@@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
@RestController
@RequestMapping("/api")
@@ -55,7 +57,7 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- return checkAlarmId(alarmId);
+ return checkAlarmId(alarmId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -68,7 +70,7 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- return checkAlarmInfoId(alarmId);
+ return checkAlarmInfoId(alarmId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -80,6 +82,8 @@ public class AlarmController extends BaseController {
public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException {
try {
alarm.setTenantId(getCurrentUser().getTenantId());
+ Operation operation = alarm.getId() == null ? Operation.CREATE : Operation.WRITE;
+ accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarm.getId(), alarm);
Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm));
logEntityAction(savedAlarm.getId(), savedAlarm,
getCurrentUser().getCustomerId(),
@@ -99,7 +103,7 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- Alarm alarm = checkAlarmId(alarmId);
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
} catch (Exception e) {
@@ -114,7 +118,7 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
- Alarm alarm = checkAlarmId(alarmId);
+ Alarm alarm = checkAlarmId(alarmId, Operation.WRITE);
alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
} 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 0df7e6b..55e087b 100644
--- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java
@@ -43,6 +43,8 @@ import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.service.security.model.SecurityUser;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
import java.util.ArrayList;
import java.util.List;
@@ -61,7 +63,7 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
try {
AssetId assetId = new AssetId(toUUID(strAssetId));
- return checkAssetId(assetId);
+ return checkAssetId(assetId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -73,15 +75,12 @@ public class AssetController extends BaseController {
public Asset saveAsset(@RequestBody Asset asset) throws ThingsboardException {
try {
asset.setTenantId(getCurrentUser().getTenantId());
- if (getCurrentUser().getAuthority() == Authority.CUSTOMER_USER) {
- if (asset.getId() == null || asset.getId().isNullUid() ||
- asset.getCustomerId() == null || asset.getCustomerId().isNullUid()) {
- throw new ThingsboardException("You don't have permission to perform this operation!",
- ThingsboardErrorCode.PERMISSION_DENIED);
- } else {
- checkCustomerId(asset.getCustomerId());
- }
- }
+
+ Operation operation = asset.getId() == null ? Operation.CREATE : Operation.WRITE;
+
+ accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, operation,
+ asset.getId(), asset);
+
Asset savedAsset = checkNotNull(assetService.saveAsset(asset));
logEntityAction(savedAsset.getId(), savedAsset,
@@ -103,7 +102,7 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
try {
AssetId assetId = new AssetId(toUUID(strAssetId));
- Asset asset = checkAssetId(assetId);
+ Asset asset = checkAssetId(assetId, Operation.DELETE);
assetService.deleteAsset(getTenantId(), assetId);
logEntityAction(assetId, asset,
@@ -128,10 +127,10 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
AssetId assetId = new AssetId(toUUID(strAssetId));
- checkAssetId(assetId);
+ checkAssetId(assetId, Operation.ASSIGN_TO_CUSTOMER);
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(getTenantId(), assetId, customerId));
@@ -157,12 +156,12 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
try {
AssetId assetId = new AssetId(toUUID(strAssetId));
- Asset asset = checkAssetId(assetId);
+ Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_CUSTOMER);
if (asset.getCustomerId() == null || asset.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Asset isn't assigned to any customer!");
}
- Customer customer = checkCustomerId(asset.getCustomerId());
+ Customer customer = checkCustomerId(asset.getCustomerId(), Operation.READ);
Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(getTenantId(), assetId));
@@ -188,7 +187,7 @@ public class AssetController extends BaseController {
checkParameter(ASSET_ID, strAssetId);
try {
AssetId assetId = new AssetId(toUUID(strAssetId));
- Asset asset = checkAssetId(assetId);
+ Asset asset = checkAssetId(assetId, Operation.ASSIGN_TO_CUSTOMER);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(asset.getTenantId());
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(getTenantId(), assetId, publicCustomer.getId()));
@@ -256,7 +255,7 @@ public class AssetController extends BaseController {
try {
TenantId tenantId = getCurrentUser().getTenantId();
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId);
+ checkCustomerId(customerId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length()>0) {
return checkNotNull(assetService.findAssetsByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
@@ -306,7 +305,8 @@ public class AssetController extends BaseController {
List<Asset> assets = checkNotNull(assetService.findAssetsByQuery(getTenantId(), query).get());
assets = assets.stream().filter(asset -> {
try {
- checkAsset(asset);
+ //checkAsset(asset);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ASSET, Operation.READ, asset.getId(), asset);
return true;
} catch (ThingsboardException e) {
return false;
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 f947e6d..1888cff 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -272,18 +272,22 @@ public abstract class BaseController {
return getCurrentUser().getTenantId();
}
- Customer checkCustomerId(CustomerId customerId) throws ThingsboardException {
+ Customer checkCustomerId(CustomerId customerId, Operation operation) throws ThingsboardException {
try {
- SecurityUser authUser = getCurrentUser();
+ /*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(authUser.getTenantId(), customerId);
- checkCustomer(customer);
+ Customer customer = customerService.findCustomerById(getTenantId(), customerId);
+ checkNotNull(customer);
+ //checkCustomer(customer);
+ accessControlService.checkPermission(getCurrentUser(), Resource.CUSTOMER, operation, customerId, customer);
return customer;
} else {
return null;
@@ -293,10 +297,10 @@ public abstract class BaseController {
}
}
- private void checkCustomer(Customer customer) throws ThingsboardException {
+ /*private void checkCustomer(Customer customer) throws ThingsboardException {
checkNotNull(customer);
checkTenantId(customer.getTenantId());
- }
+ }*/
User checkUserId(UserId userId) throws ThingsboardException {
try {
@@ -355,84 +359,93 @@ public abstract class BaseController {
}
}
- Device checkDeviceId(DeviceId deviceId) throws ThingsboardException {
+ Device checkDeviceId(DeviceId deviceId, Operation operation) throws ThingsboardException {
try {
validateId(deviceId, "Incorrect deviceId " + deviceId);
Device device = deviceService.findDeviceById(getCurrentUser().getTenantId(), deviceId);
+ checkNotNull(device);
// checkDevice(device);
- accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, Operation.READ, deviceId, device);
+ accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, operation, deviceId, device);
return device;
} catch (Exception e) {
throw handleException(e, false);
}
}
- protected void checkDevice(Device device) throws ThingsboardException {
+ /*protected void checkDevice(Device device) throws ThingsboardException {
checkNotNull(device);
checkTenantId(device.getTenantId());
checkCustomerId(device.getCustomerId());
- }
+ }*/
- protected EntityView checkEntityViewId(EntityViewId entityViewId) throws ThingsboardException {
+ protected EntityView checkEntityViewId(EntityViewId entityViewId, Operation operation) throws ThingsboardException {
try {
validateId(entityViewId, "Incorrect entityViewId " + entityViewId);
EntityView entityView = entityViewService.findEntityViewById(getCurrentUser().getTenantId(), entityViewId);
- checkEntityView(entityView);
+ checkNotNull(entityView);
+ //checkEntityView(entityView);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, operation, entityViewId, entityView);
return entityView;
} catch (Exception e) {
throw handleException(e, false);
}
}
- protected void checkEntityView(EntityView entityView) throws ThingsboardException {
+/* protected void checkEntityView(EntityView entityView) throws ThingsboardException {
checkNotNull(entityView);
checkTenantId(entityView.getTenantId());
checkCustomerId(entityView.getCustomerId());
- }
+ }*/
- Asset checkAssetId(AssetId assetId) throws ThingsboardException {
+ Asset checkAssetId(AssetId assetId, Operation operation) throws ThingsboardException {
try {
validateId(assetId, "Incorrect assetId " + assetId);
Asset asset = assetService.findAssetById(getCurrentUser().getTenantId(), assetId);
- checkAsset(asset);
+ 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 {
+ /*protected void checkAsset(Asset asset) throws ThingsboardException {
checkNotNull(asset);
checkTenantId(asset.getTenantId());
checkCustomerId(asset.getCustomerId());
- }
+ }*/
- Alarm checkAlarmId(AlarmId alarmId) throws ThingsboardException {
+ Alarm checkAlarmId(AlarmId alarmId, Operation operation) throws ThingsboardException {
try {
validateId(alarmId, "Incorrect alarmId " + alarmId);
Alarm alarm = alarmService.findAlarmByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
- checkAlarm(alarm);
+ checkNotNull(alarm);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ALARM, operation, alarmId, alarm);
+ //checkAlarm(alarm);
return alarm;
} catch (Exception e) {
throw handleException(e, false);
}
}
- AlarmInfo checkAlarmInfoId(AlarmId alarmId) throws ThingsboardException {
+ AlarmInfo checkAlarmInfoId(AlarmId alarmId, Operation operation) throws ThingsboardException {
try {
validateId(alarmId, "Incorrect alarmId " + alarmId);
AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
- checkAlarm(alarmInfo);
+ 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 {
+ /* protected void checkAlarm(Alarm alarm) throws ThingsboardException {
checkNotNull(alarm);
checkTenantId(alarm.getTenantId());
- }
+ }*/
WidgetsBundle checkWidgetsBundleId(WidgetsBundleId widgetsBundleId, boolean modify) throws ThingsboardException {
try {
@@ -476,29 +489,33 @@ public abstract class BaseController {
}
}
- Dashboard checkDashboardId(DashboardId dashboardId) throws ThingsboardException {
+ Dashboard checkDashboardId(DashboardId dashboardId, Operation operation) throws ThingsboardException {
try {
validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
Dashboard dashboard = dashboardService.findDashboardById(getCurrentUser().getTenantId(), dashboardId);
- checkDashboard(dashboard);
+ checkNotNull(dashboard);
+ accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation, dashboardId, dashboard);
+ //checkDashboard(dashboard);
return dashboard;
} catch (Exception e) {
throw handleException(e, false);
}
}
- DashboardInfo checkDashboardInfoId(DashboardId dashboardId) throws ThingsboardException {
+ DashboardInfo checkDashboardInfoId(DashboardId dashboardId, Operation operation) throws ThingsboardException {
try {
validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(getCurrentUser().getTenantId(), dashboardId);
- checkDashboard(dashboardInfo);
+ 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 {
+ /*private void checkDashboard(DashboardInfo dashboard) throws ThingsboardException {
checkNotNull(dashboard);
checkTenantId(dashboard.getTenantId());
SecurityUser authUser = getCurrentUser();
@@ -508,7 +525,7 @@ public abstract class BaseController {
ThingsboardErrorCode.PERMISSION_DENIED);
}
}
- }
+ }*/
ComponentDescriptor checkComponentDescriptorByClazz(String clazz) throws ThingsboardException {
try {
diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java
index d42801d..dfb5d74 100644
--- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java
@@ -36,6 +36,8 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
@RestController
@RequestMapping("/api")
@@ -51,7 +53,7 @@ public class CustomerController extends BaseController {
checkParameter(CUSTOMER_ID, strCustomerId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- return checkCustomerId(customerId);
+ return checkCustomerId(customerId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -64,7 +66,7 @@ public class CustomerController extends BaseController {
checkParameter(CUSTOMER_ID, strCustomerId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode infoObject = objectMapper.createObjectNode();
infoObject.put("title", customer.getTitle());
@@ -82,7 +84,7 @@ public class CustomerController extends BaseController {
checkParameter(CUSTOMER_ID, strCustomerId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
return customer.getTitle();
} catch (Exception e) {
throw handleException(e);
@@ -95,6 +97,10 @@ public class CustomerController extends BaseController {
public Customer saveCustomer(@RequestBody Customer customer) throws ThingsboardException {
try {
customer.setTenantId(getCurrentUser().getTenantId());
+
+ Operation operation = customer.getId() == null ? Operation.CREATE : Operation.WRITE;
+ accessControlService.checkPermission(getCurrentUser(), Resource.CUSTOMER, operation, customer.getId(), customer);
+
Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer));
logEntityAction(savedCustomer.getId(), savedCustomer,
@@ -118,7 +124,7 @@ public class CustomerController extends BaseController {
checkParameter(CUSTOMER_ID, strCustomerId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.DELETE);
customerService.deleteCustomer(getTenantId(), customerId);
logEntityAction(customerId, customer,
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 9f32a8b..033c2a2 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java
@@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
import java.util.HashSet;
import java.util.Set;
@@ -76,7 +78,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- return checkDashboardInfoId(dashboardId);
+ return checkDashboardInfoId(dashboardId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -89,7 +91,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- return checkDashboardId(dashboardId);
+ return checkDashboardId(dashboardId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -101,6 +103,12 @@ public class DashboardController extends BaseController {
public Dashboard saveDashboard(@RequestBody Dashboard dashboard) throws ThingsboardException {
try {
dashboard.setTenantId(getCurrentUser().getTenantId());
+
+ Operation operation = dashboard.getId() == null ? Operation.CREATE : Operation.WRITE;
+
+ accessControlService.checkPermission(getCurrentUser(), Resource.DASHBOARD, operation,
+ dashboard.getId(), dashboard);
+
Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard));
logEntityAction(savedDashboard.getId(), savedDashboard,
@@ -123,7 +131,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.DELETE);
dashboardService.deleteDashboard(getCurrentUser().getTenantId(), dashboardId);
logEntityAction(dashboardId, dashboard,
@@ -150,10 +158,10 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- checkDashboardId(dashboardId);
+ checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER);
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
@@ -182,9 +190,9 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER);
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
@@ -211,7 +219,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER);
Set<CustomerId> customerIds = new HashSet<>();
if (strCustomerIds != null) {
@@ -276,7 +284,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER);
Set<CustomerId> customerIds = new HashSet<>();
if (strCustomerIds != null) {
@@ -319,7 +327,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER);
Set<CustomerId> customerIds = new HashSet<>();
if (strCustomerIds != null) {
@@ -362,7 +370,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.ASSIGN_TO_CUSTOMER);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId());
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId()));
@@ -388,7 +396,7 @@ public class DashboardController extends BaseController {
checkParameter(DASHBOARD_ID, strDashboardId);
try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
- Dashboard dashboard = checkDashboardId(dashboardId);
+ Dashboard dashboard = checkDashboardId(dashboardId, Operation.UNASSIGN_FROM_CUSTOMER);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId());
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId()));
@@ -458,7 +466,7 @@ public class DashboardController extends BaseController {
try {
TenantId tenantId = getCurrentUser().getTenantId();
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId);
+ checkCustomerId(customerId, Operation.READ);
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink).get());
} 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 66fc180..14c66af 100644
--- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java
@@ -64,7 +64,7 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- return checkDeviceId(deviceId);
+ return checkDeviceId(deviceId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -76,15 +76,12 @@ public class DeviceController extends BaseController {
public Device saveDevice(@RequestBody Device device) throws ThingsboardException {
try {
device.setTenantId(getCurrentUser().getTenantId());
- if (getCurrentUser().getAuthority() == Authority.CUSTOMER_USER) {
- if (device.getId() == null || device.getId().isNullUid() ||
- device.getCustomerId() == null || device.getCustomerId().isNullUid()) {
- throw new ThingsboardException("You don't have permission to perform this operation!",
- ThingsboardErrorCode.PERMISSION_DENIED);
- } else {
- checkCustomerId(device.getCustomerId());
- }
- }
+
+ Operation operation = device.getId() == null ? Operation.CREATE : Operation.WRITE;
+
+ accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, operation,
+ device.getId(), device);
+
Device savedDevice = checkNotNull(deviceService.saveDevice(device));
actorService
@@ -118,7 +115,7 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- Device device = checkDeviceId(deviceId);
+ Device device = checkDeviceId(deviceId, Operation.DELETE);
deviceService.deleteDevice(getCurrentUser().getTenantId(), deviceId);
logEntityAction(deviceId, device,
@@ -144,10 +141,10 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- checkDeviceId(deviceId);
+ checkDeviceId(deviceId, Operation.ASSIGN_TO_CUSTOMER);
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(getCurrentUser().getTenantId(), deviceId, customerId));
@@ -171,11 +168,11 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- Device device = checkDeviceId(deviceId);
+ Device device = checkDeviceId(deviceId, Operation.UNASSIGN_FROM_CUSTOMER);
if (device.getCustomerId() == null || device.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Device isn't assigned to any customer!");
}
- Customer customer = checkCustomerId(device.getCustomerId());
+ Customer customer = checkCustomerId(device.getCustomerId(), Operation.READ);
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(getCurrentUser().getTenantId(), deviceId));
@@ -199,7 +196,7 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- Device device = checkDeviceId(deviceId);
+ Device device = checkDeviceId(deviceId, Operation.ASSIGN_TO_CUSTOMER);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(device.getTenantId());
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(getCurrentUser().getTenantId(), deviceId, publicCustomer.getId()));
@@ -223,7 +220,7 @@ public class DeviceController extends BaseController {
checkParameter(DEVICE_ID, strDeviceId);
try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
- Device device = checkDeviceId(deviceId);
+ Device device = checkDeviceId(deviceId, Operation.READ);
DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(getCurrentUser().getTenantId(), deviceId));
logEntityAction(deviceId, device,
device.getCustomerId(),
@@ -243,7 +240,7 @@ public class DeviceController extends BaseController {
public DeviceCredentials saveDeviceCredentials(@RequestBody DeviceCredentials deviceCredentials) throws ThingsboardException {
checkNotNull(deviceCredentials);
try {
- Device device = checkDeviceId(deviceCredentials.getDeviceId());
+ Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE);
DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(getCurrentUser().getTenantId(), deviceCredentials));
actorService.onCredentialsUpdate(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId());
logEntityAction(device.getId(), device,
@@ -307,7 +304,7 @@ public class DeviceController extends BaseController {
try {
TenantId tenantId = getCurrentUser().getTenantId();
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId);
+ checkCustomerId(customerId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length() > 0) {
return checkNotNull(deviceService.findDevicesByTenantIdAndCustomerIdAndType(tenantId, customerId, type, pageLink));
@@ -357,7 +354,8 @@ public class DeviceController extends BaseController {
List<Device> devices = checkNotNull(deviceService.findDevicesByQuery(getCurrentUser().getTenantId(), query).get());
devices = devices.stream().filter(device -> {
try {
- checkDevice(device);
+ //checkDevice(device);
+ accessControlService.checkPermission(getCurrentUser(), Resource.DEVICE, Operation.READ, device.getId(), device);
return true;
} catch (ThingsboardException e) {
return false;
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 eef742e..0ac0e85 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
@@ -48,6 +48,8 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.service.security.model.SecurityUser;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
import javax.annotation.Nullable;
import java.util.ArrayList;
@@ -74,7 +76,7 @@ public class EntityViewController extends BaseController {
public EntityView getEntityViewById(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
- return checkEntityViewId(new EntityViewId(toUUID(strEntityViewId)));
+ return checkEntityViewId(new EntityViewId(toUUID(strEntityViewId)), Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
@@ -86,6 +88,12 @@ public class EntityViewController extends BaseController {
public EntityView saveEntityView(@RequestBody EntityView entityView) throws ThingsboardException {
try {
entityView.setTenantId(getCurrentUser().getTenantId());
+
+ Operation operation = entityView.getId() == null ? Operation.CREATE : Operation.WRITE;
+
+ accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, operation,
+ entityView.getId(), entityView);
+
EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView));
List<ListenableFuture<List<Void>>> futures = new ArrayList<>();
if (savedEntityView.getKeys() != null && savedEntityView.getKeys().getAttributes() != null) {
@@ -168,7 +176,7 @@ public class EntityViewController extends BaseController {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
- EntityView entityView = checkEntityViewId(entityViewId);
+ EntityView entityView = checkEntityViewId(entityViewId, Operation.DELETE);
entityViewService.deleteEntityView(getTenantId(), entityViewId);
logEntityAction(entityViewId, entityView, entityView.getCustomerId(),
ActionType.DELETED, null, strEntityViewId);
@@ -203,10 +211,10 @@ public class EntityViewController extends BaseController {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- Customer customer = checkCustomerId(customerId);
+ Customer customer = checkCustomerId(customerId, Operation.READ);
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
- checkEntityViewId(entityViewId);
+ checkEntityViewId(entityViewId, Operation.ASSIGN_TO_CUSTOMER);
EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(getTenantId(), entityViewId, customerId));
logEntityAction(entityViewId, savedEntityView,
@@ -228,11 +236,11 @@ public class EntityViewController extends BaseController {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
- EntityView entityView = checkEntityViewId(entityViewId);
+ EntityView entityView = checkEntityViewId(entityViewId, Operation.UNASSIGN_FROM_CUSTOMER);
if (entityView.getCustomerId() == null || entityView.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Entity View isn't assigned to any customer!");
}
- Customer customer = checkCustomerId(entityView.getCustomerId());
+ Customer customer = checkCustomerId(entityView.getCustomerId(), Operation.READ);
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(getTenantId(), entityViewId));
logEntityAction(entityViewId, entityView,
entityView.getCustomerId(),
@@ -261,7 +269,7 @@ public class EntityViewController extends BaseController {
try {
TenantId tenantId = getCurrentUser().getTenantId();
CustomerId customerId = new CustomerId(toUUID(strCustomerId));
- checkCustomerId(customerId);
+ checkCustomerId(customerId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length() > 0) {
return checkNotNull(entityViewService.findEntityViewsByTenantIdAndCustomerIdAndType(tenantId, customerId, pageLink, type));
@@ -308,7 +316,8 @@ public class EntityViewController extends BaseController {
List<EntityView> entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(getTenantId(), query).get());
entityViews = entityViews.stream().filter(entityView -> {
try {
- checkEntityView(entityView);
+ //checkEntityView(entityView);
+ accessControlService.checkPermission(getCurrentUser(), Resource.ENTITY_VIEW, Operation.READ, entityView.getId(), entityView);
return true;
} catch (ThingsboardException e) {
return false;
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 7c8b2ae..66b01d3 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EventController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java
@@ -26,12 +26,15 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
+import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.model.ModelConstants;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
@RestController
@RequestMapping("/api")
@@ -58,13 +61,12 @@ public class EventController extends BaseController {
checkParameter("EntityType", strEntityType);
try {
TenantId tenantId = new TenantId(toUUID(strTenantId));
- if (!tenantId.getId().equals(ModelConstants.NULL_UUID) &&
- !tenantId.equals(getCurrentUser().getTenantId())) {
- throw new ThingsboardException("You don't have permission to perform this operation!",
- ThingsboardErrorCode.PERMISSION_DENIED);
- }
+
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId);
+
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
- return checkNotNull(eventService.findEvents(tenantId, EntityIdFactory.getByTypeAndId(strEntityType, strEntityId), eventType, pageLink));
+ return checkNotNull(eventService.findEvents(tenantId, entityId, eventType, pageLink));
} catch (Exception e) {
throw handleException(e);
}
@@ -87,13 +89,12 @@ public class EventController extends BaseController {
checkParameter("EntityType", strEntityType);
try {
TenantId tenantId = new TenantId(toUUID(strTenantId));
- if (!tenantId.getId().equals(ModelConstants.NULL_UUID) &&
- !tenantId.equals(getCurrentUser().getTenantId())) {
- throw new ThingsboardException("You don't have permission to perform this operation!",
- ThingsboardErrorCode.PERMISSION_DENIED);
- }
+
+ EntityId entityId = EntityIdFactory.getByTypeAndId(strEntityType, strEntityId);
+ checkEntityId(entityId);
+
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
- return checkNotNull(eventService.findEvents(tenantId, EntityIdFactory.getByTypeAndId(strEntityType, strEntityId), pageLink));
+ return checkNotNull(eventService.findEvents(tenantId, entityId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
index b482982..11c59df 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
@@ -51,6 +51,9 @@ import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.service.security.model.SecurityUser;
+import org.thingsboard.server.service.security.permission.AccessControlService;
+import org.thingsboard.server.service.security.permission.Operation;
+import org.thingsboard.server.service.security.permission.Resource;
import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity;
import javax.annotation.Nullable;
@@ -95,6 +98,9 @@ public class AccessValidator {
@Autowired
protected EntityViewService entityViewService;
+ @Autowired
+ protected AccessControlService accessControlService;
+
private ExecutorService executor;
@PostConstruct
@@ -109,30 +115,30 @@ public class AccessValidator {
}
}
- public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr,
+ public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, Operation operation, String entityType, String entityIdStr,
ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess) throws ThingsboardException {
- return validateEntityAndCallback(currentUser, entityType, entityIdStr, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
+ return validateEntityAndCallback(currentUser, operation, entityType, entityIdStr, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
}
- public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr,
+ public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, Operation operation, String entityType, String entityIdStr,
ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess,
BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException {
- return validateEntityAndCallback(currentUser, EntityIdFactory.getByTypeAndId(entityType, entityIdStr),
+ return validateEntityAndCallback(currentUser, operation, EntityIdFactory.getByTypeAndId(entityType, entityIdStr),
onSuccess, onFailure);
}
- public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId,
+ public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, Operation operation, EntityId entityId,
ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess) throws ThingsboardException {
- return validateEntityAndCallback(currentUser, entityId, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
+ return validateEntityAndCallback(currentUser, operation, entityId, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
}
- public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId,
+ public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, Operation operation, EntityId entityId,
ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess,
BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException {
final DeferredResult<ResponseEntity> response = new DeferredResult<>();
- validate(currentUser, entityId, new HttpValidationCallback(response,
+ validate(currentUser, operation, entityId, new HttpValidationCallback(response,
new FutureCallback<DeferredResult<ResponseEntity>>() {
@Override
public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) {
@@ -148,25 +154,25 @@ public class AccessValidator {
return response;
}
- public void validate(SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ public void validate(SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
switch (entityId.getEntityType()) {
case DEVICE:
- validateDevice(currentUser, entityId, callback);
+ validateDevice(currentUser, operation, entityId, callback);
return;
case ASSET:
- validateAsset(currentUser, entityId, callback);
+ validateAsset(currentUser, operation, entityId, callback);
return;
case RULE_CHAIN:
- validateRuleChain(currentUser, entityId, callback);
+ validateRuleChain(currentUser, operation, entityId, callback);
return;
case CUSTOMER:
- validateCustomer(currentUser, entityId, callback);
+ validateCustomer(currentUser, operation, entityId, callback);
return;
case TENANT:
- validateTenant(currentUser, entityId, callback);
+ validateTenant(currentUser, operation, entityId, callback);
return;
case ENTITY_VIEW:
- validateEntityView(currentUser, entityId, callback);
+ validateEntityView(currentUser, operation, entityId, callback);
return;
default:
//TODO: add support of other entities
@@ -174,7 +180,7 @@ public class AccessValidator {
}
}
- private void validateDevice(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateDevice(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -183,19 +189,18 @@ public class AccessValidator {
if (device == null) {
return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND);
} else {
- if (!device.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!");
- } else if (currentUser.isCustomerUser() && !device.getCustomerId().equals(currentUser.getCustomerId())) {
- return ValidationResult.accessDenied("Device doesn't belong to the current Customer!");
- } else {
- return ValidationResult.ok(device);
+ try {
+ accessControlService.checkPermission(currentUser, Resource.DEVICE, operation, entityId, device);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(device);
}
}), executor);
}
}
- private void validateAsset(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateAsset(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -204,19 +209,18 @@ public class AccessValidator {
if (asset == null) {
return ValidationResult.entityNotFound("Asset with requested id wasn't found!");
} else {
- if (!asset.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Asset doesn't belong to the current Tenant!");
- } else if (currentUser.isCustomerUser() && !asset.getCustomerId().equals(currentUser.getCustomerId())) {
- return ValidationResult.accessDenied("Asset doesn't belong to the current Customer!");
- } else {
- return ValidationResult.ok(asset);
+ try {
+ accessControlService.checkPermission(currentUser, Resource.ASSET, operation, entityId, asset);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(asset);
}
}), executor);
}
}
- private void validateRuleChain(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateRuleChain(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isCustomerUser()) {
callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -225,19 +229,18 @@ public class AccessValidator {
if (ruleChain == null) {
return ValidationResult.entityNotFound("Rule chain with requested id wasn't found!");
} else {
- if (currentUser.isTenantAdmin() && !ruleChain.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Rule chain doesn't belong to the current Tenant!");
- } else if (currentUser.isSystemAdmin() && !ruleChain.getTenantId().isNullUid()) {
- return ValidationResult.accessDenied("Rule chain is not in system scope!");
- } else {
- return ValidationResult.ok(ruleChain);
+ try {
+ accessControlService.checkPermission(currentUser, Resource.RULE_CHAIN, operation, entityId, ruleChain);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(ruleChain);
}
}), executor);
}
}
- private void validateRule(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateRule(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isCustomerUser()) {
callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -251,19 +254,18 @@ public class AccessValidator {
} else {
//TODO: make async
RuleChain ruleChain = ruleChainService.findRuleChainById(currentUser.getTenantId(), ruleNode.getRuleChainId());
- if (currentUser.isTenantAdmin() && !ruleChain.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Rule chain doesn't belong to the current Tenant!");
- } else if (currentUser.isSystemAdmin() && !ruleChain.getTenantId().isNullUid()) {
- return ValidationResult.accessDenied("Rule chain is not in system scope!");
- } else {
- return ValidationResult.ok(ruleNode);
+ try {
+ accessControlService.checkPermission(currentUser, Resource.RULE_CHAIN, operation, ruleNode.getRuleChainId(), ruleChain);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(ruleNode);
}
}), executor);
}
}
- private void validateCustomer(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateCustomer(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -272,19 +274,18 @@ public class AccessValidator {
if (customer == null) {
return ValidationResult.entityNotFound("Customer with requested id wasn't found!");
} else {
- if (!customer.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Customer doesn't belong to the current Tenant!");
- } else if (currentUser.isCustomerUser() && !customer.getId().equals(currentUser.getCustomerId())) {
- return ValidationResult.accessDenied("Customer doesn't relate to the currently authorized customer user!");
- } else {
- return ValidationResult.ok(customer);
+ try {
+ accessControlService.checkPermission(currentUser, customer.getTenantId(), Resource.CUSTOMER, operation, entityId);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(customer);
}
}), executor);
}
}
- private void validateTenant(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateTenant(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isCustomerUser()) {
callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else if (currentUser.isSystemAdmin()) {
@@ -294,16 +295,19 @@ public class AccessValidator {
Futures.addCallback(tenantFuture, getCallback(callback, tenant -> {
if (tenant == null) {
return ValidationResult.entityNotFound("Tenant with requested id wasn't found!");
- } else if (!tenant.getId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Tenant doesn't relate to the currently authorized user!");
- } else {
- return ValidationResult.ok(tenant);
}
+ try {
+ accessControlService.checkPermission(currentUser, new TenantId(entityId.getId()), Resource.TENANT, operation, entityId);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
+ }
+ return ValidationResult.ok(tenant);
+
}), executor);
}
}
- private void validateEntityView(final SecurityUser currentUser, EntityId entityId, FutureCallback<ValidationResult> callback) {
+ private void validateEntityView(final SecurityUser currentUser, Operation operation, EntityId entityId, FutureCallback<ValidationResult> callback) {
if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
@@ -312,13 +316,12 @@ public class AccessValidator {
if (entityView == null) {
return ValidationResult.entityNotFound(ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND);
} else {
- if (!entityView.getTenantId().equals(currentUser.getTenantId())) {
- return ValidationResult.accessDenied("Entity-view doesn't belong to the current Tenant!");
- } else if (currentUser.isCustomerUser() && !entityView.getCustomerId().equals(currentUser.getCustomerId())) {
- return ValidationResult.accessDenied("Entity-view doesn't belong to the current Customer!");
- } else {
- return ValidationResult.ok(entityView);
+ try {
+ accessControlService.checkPermission(currentUser, Resource.ENTITY_VIEW, operation, entityId, entityView);
+ } catch (ThingsboardException e) {
+ return ValidationResult.accessDenied(e.getMessage());
}
+ return ValidationResult.ok(entityView);
}
}), executor);
}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java b/application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java
index 03d4222..ccb62ec 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/AccessControlService.java
@@ -28,6 +28,6 @@ public interface AccessControlService {
void checkPermission(SecurityUser user, TenantId tenantId, Resource resource, Operation operation, EntityId entityId) throws ThingsboardException;
- <T extends HasTenantId & HasCustomerId, I extends EntityId> void checkPermission(SecurityUser user, Resource resource, Operation operation, I entityId, T entity) throws ThingsboardException;
+ <T extends HasTenantId, I extends EntityId> void checkPermission(SecurityUser user, Resource resource, Operation operation, I entityId, T entity) throws ThingsboardException;
}
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
new file mode 100644
index 0000000..4c67aa3
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPremissions.java
@@ -0,0 +1,86 @@
+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.id.DashboardId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+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<Resource, PermissionChecker> {
+
+ public CustomerUserPremissions() {
+ super();
+ put(Resource.ALARM, TenantAdminPermissions.tenantEntityPermissionChecker);
+ put(Resource.ASSET, customerEntityPermissionChecker);
+ put(Resource.DEVICE, customerEntityPermissionChecker);
+ put(Resource.CUSTOMER, customerPermissionChecker);
+ put(Resource.DASHBOARD, customerDashboardPermissionChecker);
+ put(Resource.ENTITY_VIEW, customerEntityPermissionChecker);
+ put(Resource.TENANT, TenantAdminPermissions.tenantPermissionChecker);
+ }
+
+ public static final PermissionChecker customerEntityPermissionChecker = 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 (!user.getTenantId().equals(entity.getTenantId())) {
+ return false;
+ }
+ if (!(entity instanceof HasCustomerId)) {
+ return false;
+ }
+ if (!user.getCustomerId().equals(((HasCustomerId)entity).getCustomerId())) {
+ return false;
+ }
+ return true;
+ }
+ };
+
+ private static final PermissionChecker customerPermissionChecker =
+ new PermissionChecker.GenericPermissionChecker(Operation.READ) {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ if (!super.hasPermission(user, tenantId, operation, entityId)) {
+ return false;
+ }
+ if (!user.getCustomerId().equals(entityId)) {
+ return false;
+ }
+ return true;
+ }
+
+ };
+
+ private static final PermissionChecker customerDashboardPermissionChecker =
+ new PermissionChecker.GenericPermissionChecker<DashboardInfo, DashboardId>(Operation.READ) {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, Operation operation, DashboardId dashboardId, DashboardInfo dashboard) {
+
+ if (!super.hasPermission(user, operation, dashboardId, dashboard)) {
+ return false;
+ }
+ if (!user.getTenantId().equals(dashboard.getTenantId())) {
+ return false;
+ }
+ if (!dashboard.isAssignedToCustomer(user.getCustomerId())) {
+ return false;
+ }
+ return true;
+ }
+
+ };
+}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java b/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
new file mode 100644
index 0000000..7601891
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
@@ -0,0 +1,95 @@
+/**
+ * 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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.thingsboard.server.common.data.Customer;
+import org.thingsboard.server.common.data.EntityType;
+import org.thingsboard.server.common.data.HasCustomerId;
+import org.thingsboard.server.common.data.HasTenantId;
+import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
+import org.thingsboard.server.common.data.exception.ThingsboardException;
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.common.data.security.Authority;
+import org.thingsboard.server.dao.customer.CustomerService;
+import org.thingsboard.server.service.security.model.SecurityUser;
+
+import java.util.*;
+
+import static org.thingsboard.server.dao.service.Validator.validateId;
+
+@Service
+@Slf4j
+public class DefaultAccessControlService implements AccessControlService {
+
+ private static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
+ private static final String YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION = "You don't have permission to perform this operation!";
+
+ private final Map<Authority, Map<Resource, PermissionChecker>> authorityPermissions = new HashMap<>();
+ {
+ authorityPermissions.put(Authority.SYS_ADMIN, new SysAdminPermissions());
+ authorityPermissions.put(Authority.TENANT_ADMIN, new TenantAdminPermissions());
+ authorityPermissions.put(Authority.CUSTOMER_USER, new CustomerUserPremissions());
+ }
+
+ @Override
+ public void checkPermission(SecurityUser user, TenantId tenantId, Resource resource, Operation operation) throws ThingsboardException {
+ PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource);
+ if (!permissionChecker.hasPermission(user, tenantId, operation)) {
+ permissionDenied();
+ }
+ }
+
+ @Override
+ public void checkPermission(SecurityUser user, TenantId tenantId, Resource resource, Operation operation, EntityId entityId) throws ThingsboardException {
+ PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource);
+ if (!permissionChecker.hasPermission(user, tenantId, operation, entityId)) {
+ permissionDenied();
+ }
+ }
+
+ @Override
+ public <T extends HasTenantId, I extends EntityId> void checkPermission(SecurityUser user, Resource resource,
+ Operation operation, I entityId, T entity) throws ThingsboardException {
+ PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource);
+ if (!permissionChecker.hasPermission(user, operation, entityId, entity)) {
+ permissionDenied();
+ }
+ }
+
+ private PermissionChecker getPermissionChecker(Authority authority, Resource resource) throws ThingsboardException {
+ Map<Resource, PermissionChecker> permissions = authorityPermissions.get(authority);
+ if (permissions == null) {
+ permissionDenied();
+ }
+ PermissionChecker permissionChecker = permissions.get(resource);
+ if (permissionChecker == null) {
+ permissionDenied();
+ }
+ return permissionChecker;
+ }
+
+ private void permissionDenied() throws ThingsboardException {
+ throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION,
+ ThingsboardErrorCode.PERMISSION_DENIED);
+ }
+
+}
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 3c48c66..d5254e7 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,6 @@ package org.thingsboard.server.service.security.permission;
public enum Operation {
- ALL, CREATE, READ, WRITE, DELETE
+ ALL, CREATE, READ, WRITE, DELETE, ASSIGN_TO_CUSTOMER, UNASSIGN_FROM_CUSTOMER
}
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
new file mode 100644
index 0000000..921b7d9
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/PermissionChecker.java
@@ -0,0 +1,72 @@
+package org.thingsboard.server.service.security.permission;
+
+import org.thingsboard.server.common.data.HasCustomerId;
+import org.thingsboard.server.common.data.HasTenantId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.service.security.model.SecurityUser;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public interface PermissionChecker<T extends HasTenantId, I extends EntityId> {
+
+ default boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation) {
+ return false;
+ }
+
+ default boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ return false;
+ }
+
+ default boolean hasPermission(SecurityUser user, Operation operation, I entityId, T entity) {
+ return false;
+ }
+
+ public class GenericPermissionChecker<T extends HasTenantId, I extends EntityId> implements PermissionChecker<T, I> {
+
+ private final Set<Operation> allowedOperations;
+
+ public GenericPermissionChecker(Operation... operations) {
+ allowedOperations = new HashSet<Operation>(Arrays.asList(operations));
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation) {
+ return allowedOperations.contains(Operation.ALL) || allowedOperations.contains(operation);
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ return allowedOperations.contains(Operation.ALL) || allowedOperations.contains(operation);
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, Operation operation, I entityId, T entity) {
+ return allowedOperations.contains(Operation.ALL) || allowedOperations.contains(operation);
+ }
+ }
+
+ public static PermissionChecker denyAllPermissionChecker = new PermissionChecker() {};
+
+ public static PermissionChecker allowAllPermissionChecker = new PermissionChecker<HasTenantId, EntityId>() {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation) {
+ return true;
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ return true;
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
+ return true;
+ }
+ };
+
+
+}
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 391cfd5..8cf4dc2 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
@@ -20,7 +20,15 @@ import org.thingsboard.server.common.data.EntityType;
import java.util.Optional;
public enum Resource {
- DEVICE(EntityType.DEVICE);
+ ADMIN_SETTINGS(),
+ ALARM(EntityType.ALARM),
+ DEVICE(EntityType.DEVICE),
+ ASSET(EntityType.ASSET),
+ CUSTOMER(EntityType.CUSTOMER),
+ DASHBOARD(EntityType.DASHBOARD),
+ ENTITY_VIEW(EntityType.ENTITY_VIEW),
+ TENANT(EntityType.TENANT),
+ RULE_CHAIN(EntityType.RULE_CHAIN);
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
new file mode 100644
index 0000000..251cb9b
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java
@@ -0,0 +1,39 @@
+package org.thingsboard.server.service.security.permission;
+
+import org.thingsboard.server.common.data.HasTenantId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.service.security.model.SecurityUser;
+
+import java.util.HashMap;
+
+public class SysAdminPermissions extends HashMap<Resource, PermissionChecker> {
+
+ public SysAdminPermissions() {
+ super();
+ put(Resource.ADMIN_SETTINGS, PermissionChecker.allowAllPermissionChecker);
+ put(Resource.DASHBOARD, new PermissionChecker.GenericPermissionChecker(Operation.READ));
+ put(Resource.TENANT, PermissionChecker.allowAllPermissionChecker);
+ put(Resource.RULE_CHAIN, systemEntityPermissionChecker);
+ }
+
+ private static final PermissionChecker systemEntityPermissionChecker = new PermissionChecker<HasTenantId, EntityId>() {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ if (tenantId != null && !tenantId.isNullUid()) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
+
+ if (entity.getTenantId() != null && !entity.getTenantId().isNullUid()) {
+ 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
new file mode 100644
index 0000000..c8e208f
--- /dev/null
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
@@ -0,0 +1,59 @@
+package org.thingsboard.server.service.security.permission;
+
+import org.thingsboard.server.common.data.HasTenantId;
+import org.thingsboard.server.common.data.id.EntityId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.service.security.model.SecurityUser;
+
+import java.util.HashMap;
+
+public class TenantAdminPermissions extends HashMap<Resource, PermissionChecker> {
+
+ public TenantAdminPermissions() {
+ super();
+ put(Resource.ALARM, tenantEntityPermissionChecker);
+ put(Resource.ASSET, tenantEntityPermissionChecker);
+ put(Resource.DEVICE, tenantEntityPermissionChecker);
+ put(Resource.CUSTOMER, tenantEntityPermissionChecker);
+ put(Resource.DASHBOARD, tenantEntityPermissionChecker);
+ put(Resource.ENTITY_VIEW, tenantEntityPermissionChecker);
+ put(Resource.TENANT, tenantPermissionChecker);
+ put(Resource.RULE_CHAIN, tenantEntityPermissionChecker);
+ }
+
+ public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker<HasTenantId, EntityId>() {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ if (!user.getTenantId().equals(tenantId)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
+
+ if (!user.getTenantId().equals(entity.getTenantId())) {
+ return false;
+ }
+ return true;
+ }
+ };
+
+ public static final PermissionChecker tenantPermissionChecker =
+ new PermissionChecker.GenericPermissionChecker(Operation.READ) {
+
+ @Override
+ public boolean hasPermission(SecurityUser user, TenantId tenantId, Operation operation, EntityId entityId) {
+ if (!super.hasPermission(user, tenantId, operation, entityId)) {
+ return false;
+ }
+ if (!user.getTenantId().equals(entityId)) {
+ return false;
+ }
+ return true;
+ }
+
+ };
+}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
index 7b74e62..e5688a6 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.id.TenantId;
import java.util.*;
-public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName {
+public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName, HasTenantId {
private TenantId tenantId;
private String title;