diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java index 23ba6fd19e..ff57aec801 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java @@ -42,6 +42,7 @@ public class CustomerUserPermissions extends AbstractPermissions { put(Resource.WIDGET_TYPE, widgetsPermissionChecker); put(Resource.EDGE, customerEntityPermissionChecker); put(Resource.RPC, rpcPermissionChecker); + put(Resource.DEVICE_PROFILE, deviceProfilePermissionChecker); } private static final PermissionChecker customerAlarmPermissionChecker = new PermissionChecker() { @@ -152,4 +153,19 @@ public class CustomerUserPermissions extends AbstractPermissions { return user.getTenantId().equals(entity.getTenantId()); } }; + + private static final PermissionChecker deviceProfilePermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ) { + + @Override + @SuppressWarnings("unchecked") + public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) { + if (!super.hasPermission(user, operation, entityId, entity)) { + return false; + } + if (entity.getTenantId() == null || entity.getTenantId().isNullUid()) { + return true; + } + return user.getTenantId().equals(entity.getTenantId()); + } + }; } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java index 80266563ef..75f40bae8e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java @@ -28,6 +28,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; @@ -170,6 +171,25 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId()); Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName()); Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType()); + + Customer customer = new Customer(); + customer.setTitle("Customer"); + customer.setTenantId(savedTenant.getId()); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + + User customerUser = new User(); + customerUser.setAuthority(Authority.CUSTOMER_USER); + customerUser.setTenantId(savedTenant.getId()); + customerUser.setCustomerId(savedCustomer.getId()); + customerUser.setEmail("customer2@thingsboard.org"); + + createUserAndLogin(customerUser, "customer"); + + foundDeviceProfileInfo = doGet("/api/deviceProfileInfo/" + savedDeviceProfile.getId().getId().toString(), DeviceProfileInfo.class); + Assert.assertNotNull(foundDeviceProfileInfo); + Assert.assertEquals(savedDeviceProfile.getId(), foundDeviceProfileInfo.getId()); + Assert.assertEquals(savedDeviceProfile.getName(), foundDeviceProfileInfo.getName()); + Assert.assertEquals(savedDeviceProfile.getType(), foundDeviceProfileInfo.getType()); } @Test diff --git a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts index a76a65ab96..59b1959269 100644 --- a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts @@ -36,6 +36,7 @@ import { UserService } from '@core/http/user.service'; import { AttributeService } from '@core/http/attribute.service'; import { EntityRelationService } from '@core/http/entity-relation.service'; import { EntityService } from '@core/http/entity.service'; +import { AuthService } from '@core/auth/auth.service'; import { DialogService } from '@core/services/dialog.service'; import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; import { ResourceService } from '@core/http/resource.service'; @@ -75,6 +76,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid this.ctx.attributeService = $injector.get(AttributeService); this.ctx.entityRelationService = $injector.get(EntityRelationService); this.ctx.entityService = $injector.get(EntityService); + this.ctx.authService = $injector.get(AuthService); this.ctx.dialogs = $injector.get(DialogService); this.ctx.customDialog = $injector.get(CustomDialogService); this.ctx.resourceService = $injector.get(ResourceService); diff --git a/ui-ngx/src/app/modules/home/models/services.map.ts b/ui-ngx/src/app/modules/home/models/services.map.ts index f3bd6710f6..93ec69da61 100644 --- a/ui-ngx/src/app/modules/home/models/services.map.ts +++ b/ui-ngx/src/app/modules/home/models/services.map.ts @@ -36,6 +36,7 @@ import { BroadcastService } from '@core/services/broadcast.service'; import { ImportExportService } from '@home/components/import-export/import-export.service'; import { DeviceProfileService } from '@core/http/device-profile.service'; import { OtaPackageService } from '@core/http/ota-package.service'; +import { AuthService } from '@core/auth/auth.service'; import { ResourceService } from '@core/http/resource.service'; import { TwoFactorAuthenticationService } from '@core/http/two-factor-authentication.service'; @@ -62,6 +63,7 @@ export const ServicesMap = new Map>( ['importExport', ImportExportService], ['deviceProfileService', DeviceProfileService], ['otaPackageService', OtaPackageService], + ['authService', AuthService], ['resourceService', ResourceService], ['twoFactorAuthenticationService', TwoFactorAuthenticationService] ] diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 4e250b71ea..4686fe88e6 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -71,6 +71,7 @@ import { EntityRelationService } from '@core/http/entity-relation.service'; import { EntityService } from '@core/http/entity.service'; import { DialogService } from '@core/services/dialog.service'; import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; +import { AuthService } from '@core/auth/auth.service'; import { ResourceService } from '@core/http/resource.service'; import { DatePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; @@ -158,6 +159,7 @@ export class WidgetContext { } } + authService: AuthService; deviceService: DeviceService; assetService: AssetService; entityViewService: EntityViewService;