thingsboard-developers

Changes

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;