diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 329bad55a5..677303cc15 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -285,7 +285,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected void loginDifferentTenant() throws Exception { if (savedDifferentTenant != null) { - login(savedDifferentTenant.getEmail(), TENANT_ADMIN_PASSWORD); + login(DIFFERENT_TENANT_ADMIN_EMAIL, DIFFERENT_TENANT_ADMIN_PASSWORD); } else { loginSysAdmin(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java index 4c4f44aea6..8ea89960d7 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java @@ -30,7 +30,10 @@ import org.mockito.Mockito; import org.thingsboard.common.util.ThingsBoardExecutors; 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.EntitySubtype; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; @@ -57,6 +60,8 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; public abstract class BaseDeviceControllerTest extends AbstractControllerTest { @@ -204,7 +209,7 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { String savedDeviceIdStr = savedDevice.getId().getId().toString(); doPost("/api/device", savedDevice) - .andExpect( status().isNotFound()) + .andExpect(status().isNotFound()) .andExpect(statusReason(containsString(msgErrorNoFound("Device", savedDeviceIdStr)))); testNotifyEntityNever(savedDevice.getId(), savedDevice); @@ -222,6 +227,66 @@ public abstract class BaseDeviceControllerTest extends AbstractControllerTest { deleteDifferentTenant(); } + @Test + public void testSaveDeviceWithProfileFromDifferentTenant() throws Exception { + loginDifferentTenant(); + DeviceProfile differentProfile = createDeviceProfile("Different profile"); + differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class); + + loginTenantAdmin(); + Device device = new Device(); + device.setName("My device"); + device.setDeviceProfileId(differentProfile.getId()); + doPost("/api/device", device).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Device can`t be referencing to device profile from different tenant!"))); + } + + @Test + public void testSaveDeviceWithFirmwareFromDifferentTenant() throws Exception { + loginDifferentTenant(); + DeviceProfile differentProfile = createDeviceProfile("Different profile"); + differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class); + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); + firmwareInfo.setDeviceProfileId(differentProfile.getId()); + firmwareInfo.setType(FIRMWARE); + firmwareInfo.setTitle("title"); + firmwareInfo.setVersion("1.0"); + firmwareInfo.setUrl("test.url"); + firmwareInfo.setUsesUrl(true); + OtaPackageInfo savedFw = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); + + loginTenantAdmin(); + Device device = new Device(); + device.setName("My device"); + device.setType("default"); + device.setFirmwareId(savedFw.getId()); + doPost("/api/device", device).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign firmware from different tenant!"))); + } + + @Test + public void testSaveDeviceWithSoftwareFromDifferentTenant() throws Exception { + loginDifferentTenant(); + DeviceProfile differentProfile = createDeviceProfile("Different profile"); + differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class); + SaveOtaPackageInfoRequest softwareInfo = new SaveOtaPackageInfoRequest(); + softwareInfo.setDeviceProfileId(differentProfile.getId()); + softwareInfo.setType(SOFTWARE); + softwareInfo.setTitle("title"); + softwareInfo.setVersion("1.0"); + softwareInfo.setUrl("test.url"); + softwareInfo.setUsesUrl(true); + OtaPackageInfo savedSw = doPost("/api/otaPackage", softwareInfo, OtaPackageInfo.class); + + loginTenantAdmin(); + Device device = new Device(); + device.setName("My device"); + device.setType("default"); + device.setSoftwareId(savedSw.getId()); + doPost("/api/device", device).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign software from different tenant!"))); + } + @Test public void testFindDeviceById() throws Exception { Device device = new Device(); 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 1fb5316a17..d0c4a1d7ce 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java @@ -29,13 +29,17 @@ 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.Dashboard; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileInfo; import org.thingsboard.server.common.data.DeviceProfileProvisionType; import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.OtaPackageInfo; +import org.thingsboard.server.common.data.SaveOtaPackageInfoRequest; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; @@ -45,7 +49,15 @@ import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadCo import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.queue.ProcessingStrategy; +import org.thingsboard.server.common.data.queue.ProcessingStrategyType; +import org.thingsboard.server.common.data.queue.Queue; +import org.thingsboard.server.common.data.queue.SubmitStrategy; +import org.thingsboard.server.common.data.queue.SubmitStrategyType; +import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; +import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.exception.DataValidationException; import java.util.ArrayList; @@ -59,6 +71,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; +import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; public abstract class BaseDeviceProfileControllerTest extends AbstractControllerTest { @@ -345,6 +359,129 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController testNotifyEntityNever(savedDeviceProfile.getId(), savedDeviceProfile); } + @Test + public void testSaveDeviceProfileWithRuleChainFromDifferentTenant() throws Exception { + loginDifferentTenant(); + RuleChain ruleChain = new RuleChain(); + ruleChain.setName("Different rule chain"); + RuleChain savedRuleChain = doPost("/api/ruleChain", ruleChain, RuleChain.class); + + loginTenantAdmin(); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setDefaultRuleChainId(savedRuleChain.getId()); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign rule chain from different tenant!"))); + } + + @Test + public void testSaveDeviceProfileWithDashboardFromDifferentTenant() throws Exception { + loginDifferentTenant(); + Dashboard dashboard = new Dashboard(); + dashboard.setTitle("Different dashboard"); + Dashboard savedDashboard = doPost("/api/dashboard", dashboard, Dashboard.class); + + loginTenantAdmin(); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setDefaultDashboardId(savedDashboard.getId()); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign dashboard from different tenant!"))); + } + + @Test + public void testSaveDeviceProfileWithQueueFromDifferentTenant() throws Exception { + loginDifferentTenant(); + loginSysAdmin(); + TenantProfile tenantProfile = new TenantProfile(); + tenantProfile.setDefault(false); + tenantProfile.setName("Isolated TB Rule Engine"); + tenantProfile.setDescription("Isolated TB Rule Engine tenant profile"); + tenantProfile.setIsolatedTbCore(false); + tenantProfile.setIsolatedTbRuleEngine(true); + + TenantProfileQueueConfiguration mainQueueConfiguration = new TenantProfileQueueConfiguration(); + mainQueueConfiguration.setName("Main"); + mainQueueConfiguration.setTopic("tb_rule_engine.main"); + mainQueueConfiguration.setPollInterval(25); + mainQueueConfiguration.setPartitions(10); + mainQueueConfiguration.setConsumerPerPartition(true); + mainQueueConfiguration.setPackProcessingTimeout(2000); + SubmitStrategy mainQueueSubmitStrategy = new SubmitStrategy(); + mainQueueSubmitStrategy.setType(SubmitStrategyType.BURST); + mainQueueSubmitStrategy.setBatchSize(1000); + mainQueueConfiguration.setSubmitStrategy(mainQueueSubmitStrategy); + ProcessingStrategy mainQueueProcessingStrategy = new ProcessingStrategy(); + mainQueueProcessingStrategy.setType(ProcessingStrategyType.SKIP_ALL_FAILURES); + mainQueueProcessingStrategy.setRetries(3); + mainQueueProcessingStrategy.setFailurePercentage(0); + mainQueueProcessingStrategy.setPauseBetweenRetries(3); + mainQueueProcessingStrategy.setMaxPauseBetweenRetries(3); + mainQueueConfiguration.setProcessingStrategy(mainQueueProcessingStrategy); + TenantProfileData profileData = tenantProfile.getProfileData(); + profileData.setQueueConfiguration(Collections.singletonList(mainQueueConfiguration)); + tenantProfile.setProfileData(profileData); + TenantProfile savedTenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); + savedDifferentTenant.setTenantProfileId(savedTenantProfile.getId()); + savedDifferentTenant = doPost("/api/tenant", savedDifferentTenant, Tenant.class); + loginDifferentTenant(); + PageLink pageLink = new PageLink(1); + PageData pageData = doGetTypedWithPageLink("/api/queues?serviceType=TB_RULE_ENGINE&", + new TypeReference<>() {}, pageLink); + Queue differentQueue = pageData.getData().get(0); + + loginTenantAdmin(); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setDefaultQueueId(differentQueue.getId()); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign queue from different tenant!"))); + } + + @Test + public void testSaveDeviceProfileWithFirmwareFromDifferentTenant() throws Exception { + loginDifferentTenant(); + DeviceProfile differentProfile = createDeviceProfile("Different profile"); + differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class); + SaveOtaPackageInfoRequest firmwareInfo = new SaveOtaPackageInfoRequest(); + firmwareInfo.setDeviceProfileId(differentProfile.getId()); + firmwareInfo.setType(FIRMWARE); + firmwareInfo.setTitle("title"); + firmwareInfo.setVersion("1.0"); + firmwareInfo.setUrl("test.url"); + firmwareInfo.setUsesUrl(true); + OtaPackageInfo savedFw = doPost("/api/otaPackage", firmwareInfo, OtaPackageInfo.class); + + loginTenantAdmin(); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setFirmwareId(savedFw.getId()); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign firmware from different tenant!"))); + } + + @Test + public void testSaveDeviceProfileWithSoftwareFromDifferentTenant() throws Exception { + loginDifferentTenant(); + DeviceProfile differentProfile = createDeviceProfile("Different profile"); + differentProfile = doPost("/api/deviceProfile", differentProfile, DeviceProfile.class); + SaveOtaPackageInfoRequest softwareInfo = new SaveOtaPackageInfoRequest(); + softwareInfo.setDeviceProfileId(differentProfile.getId()); + softwareInfo.setType(SOFTWARE); + softwareInfo.setTitle("title"); + softwareInfo.setVersion("1.0"); + softwareInfo.setUrl("test.url"); + softwareInfo.setUsesUrl(true); + OtaPackageInfo savedSw = doPost("/api/otaPackage", softwareInfo, OtaPackageInfo.class); + + loginTenantAdmin(); + + DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); + deviceProfile.setSoftwareId(savedSw.getId()); + doPost("/api/deviceProfile", deviceProfile).andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Can't assign software from different tenant!"))); + } + @Test public void testDeleteDeviceProfile() throws Exception { DeviceProfile deviceProfile = this.createDeviceProfile("Device Profile"); @@ -1009,7 +1146,7 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController .andExpect(status().isBadRequest()) .andExpect(statusReason(containsString(errorMsg))); - testNotifyEntityEqualsOneTimeServiceNeverError(deviceProfile,savedTenant.getId(), + testNotifyEntityEqualsOneTimeServiceNeverError(deviceProfile, savedTenant.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(errorMsg)); } @@ -1024,7 +1161,7 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController .andExpect(status().isBadRequest()) .andExpect(statusReason(containsString(errorMsg))); - testNotifyEntityEqualsOneTimeServiceNeverError(deviceProfile,savedTenant.getId(), + testNotifyEntityEqualsOneTimeServiceNeverError(deviceProfile, savedTenant.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(errorMsg)); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 9f32939ad2..a1ab278ae3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -226,6 +226,9 @@ public class DeviceServiceImpl extends AbstractCachedEntityService> extends DataValidator { + + @Autowired + private OtaPackageService otaPackageService; + + protected void validateOtaPackage(TenantId tenantId, T entity, DeviceProfileId deviceProfileId) { + if (entity.getFirmwareId() != null) { + OtaPackage firmware = otaPackageService.findOtaPackageById(tenantId, entity.getFirmwareId()); + validateOtaPackage(tenantId, OtaPackageType.FIRMWARE, deviceProfileId, firmware); + } + if (entity.getSoftwareId() != null) { + OtaPackage software = otaPackageService.findOtaPackageById(tenantId, entity.getSoftwareId()); + validateOtaPackage(tenantId, OtaPackageType.SOFTWARE, deviceProfileId, software); + } + } + + private void validateOtaPackage(TenantId tenantId, OtaPackageType type, DeviceProfileId deviceProfileId, OtaPackage otaPackage) { + if (otaPackage == null) { + throw new DataValidationException(prepareMsg("Can't assign non-existent %s!", type)); + } + if (!otaPackage.getTenantId().equals(tenantId)) { + throw new DataValidationException(prepareMsg("Can't assign %s from different tenant!", type)); + } + if (!otaPackage.getType().equals(type)) { + throw new DataValidationException(prepareMsg("Can't assign %s with type: " + otaPackage.getType(), type)); + } + if (otaPackage.getData() == null && !otaPackage.hasUrl()) { + throw new DataValidationException(prepareMsg("Can't assign %s with empty data!", type)); + } + if (!otaPackage.getDeviceProfileId().equals(deviceProfileId)) { + throw new DataValidationException(prepareMsg("Can't assign %s with different deviceProfile!", type)); + } + } + + private String prepareMsg(String msg, OtaPackageType type) { + return String.format(msg, type.name().toLowerCase()); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java index 23e520f070..d30180a892 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceDataValidator.java @@ -22,17 +22,13 @@ import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; -import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.device.data.DeviceTransportConfiguration; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.dao.customer.CustomerDao; import org.thingsboard.server.dao.device.DeviceDao; import org.thingsboard.server.dao.exception.DataValidationException; -import org.thingsboard.server.dao.ota.OtaPackageService; -import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TenantService; @@ -41,7 +37,7 @@ import java.util.Optional; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @Component -public class DeviceDataValidator extends DataValidator { +public class DeviceDataValidator extends AbstractHasOtaPackageValidator { @Autowired private DeviceDao deviceDao; @@ -56,9 +52,6 @@ public class DeviceDataValidator extends DataValidator { @Lazy private TbTenantProfileCache tenantProfileCache; - @Autowired - private OtaPackageService otaPackageService; - @Override protected void validateCreate(TenantId tenantId, Device device) { DefaultTenantProfileConfiguration profileConfiguration = @@ -103,36 +96,6 @@ public class DeviceDataValidator extends DataValidator { .flatMap(deviceData -> Optional.ofNullable(deviceData.getTransportConfiguration())) .ifPresent(DeviceTransportConfiguration::validate); - if (device.getFirmwareId() != null) { - OtaPackage firmware = otaPackageService.findOtaPackageById(tenantId, device.getFirmwareId()); - if (firmware == null) { - throw new DataValidationException("Can't assign non-existent firmware!"); - } - if (!firmware.getType().equals(OtaPackageType.FIRMWARE)) { - throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); - } - if (firmware.getData() == null && !firmware.hasUrl()) { - throw new DataValidationException("Can't assign firmware with empty data!"); - } - if (!firmware.getDeviceProfileId().equals(device.getDeviceProfileId())) { - throw new DataValidationException("Can't assign firmware with different deviceProfile!"); - } - } - - if (device.getSoftwareId() != null) { - OtaPackage software = otaPackageService.findOtaPackageById(tenantId, device.getSoftwareId()); - if (software == null) { - throw new DataValidationException("Can't assign non-existent software!"); - } - if (!software.getType().equals(OtaPackageType.SOFTWARE)) { - throw new DataValidationException("Can't assign software with type: " + software.getType()); - } - if (software.getData() == null && !software.hasUrl()) { - throw new DataValidationException("Can't assign software with empty data!"); - } - if (!software.getDeviceProfileId().equals(device.getDeviceProfileId())) { - throw new DataValidationException("Can't assign firmware with different deviceProfile!"); - } - } + validateOtaPackage(tenantId, device, device.getDeviceProfileId()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java index b1fb9b150b..eec7bc8bc8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/validator/DeviceProfileDataValidator.java @@ -35,8 +35,8 @@ import org.springframework.util.CollectionUtils; import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileProvisionType; -import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.CoapDeviceTypeConfiguration; @@ -52,7 +52,6 @@ import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBo import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.RPKLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.X509LwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.msg.EncryptionUtil; @@ -62,10 +61,9 @@ import org.thingsboard.server.dao.device.DeviceProfileDao; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; -import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.queue.QueueService; import org.thingsboard.server.dao.rule.RuleChainService; -import org.thingsboard.server.dao.service.DataValidator; +import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.dao.tenant.TenantService; import java.util.HashSet; @@ -74,7 +72,7 @@ import java.util.Set; import java.util.stream.Collectors; @Component -public class DeviceProfileDataValidator extends DataValidator { +public class DeviceProfileDataValidator extends AbstractHasOtaPackageValidator { private static final Location LOCATION = new Location("", "", -1, -1); private static final String ATTRIBUTES_PROTO_SCHEMA = "attributes proto schema"; @@ -94,11 +92,11 @@ public class DeviceProfileDataValidator extends DataValidator { @Autowired private QueueService queueService; @Autowired - private OtaPackageService otaPackageService; - @Autowired private RuleChainService ruleChainService; @Autowired private DashboardService dashboardService; + @Autowired + private TbTenantProfileCache tenantProfileCache; private static String invalidSchemaProvidedMessage(String schemaName) { return "[Transport Configuration] invalid " + schemaName + " provided!"; @@ -133,6 +131,11 @@ public class DeviceProfileDataValidator extends DataValidator { if (queue == null) { throw new DataValidationException("Device profile is referencing to non-existent queue!"); } + TenantProfile tenantProfile = tenantProfileCache.get(deviceProfile.getTenantId()); + if ((tenantProfile.isIsolatedTbRuleEngine() && !queue.getTenantId().equals(deviceProfile.getTenantId())) + || (!tenantProfile.isIsolatedTbRuleEngine() && !queue.getTenantId().isNullUid())) { + throw new DataValidationException("Can't assign queue from different tenant!"); + } } if (deviceProfile.getProvisionType() == null) { deviceProfile.setProvisionType(DeviceProfileProvisionType.DISABLED); @@ -192,6 +195,9 @@ public class DeviceProfileDataValidator extends DataValidator { if (ruleChain == null) { throw new DataValidationException("Can't assign non-existent rule chain!"); } + if (!ruleChain.getTenantId().equals(deviceProfile.getTenantId())) { + throw new DataValidationException("Can't assign rule chain from different tenant!"); + } } if (deviceProfile.getDefaultDashboardId() != null) { @@ -199,39 +205,12 @@ public class DeviceProfileDataValidator extends DataValidator { if (dashboard == null) { throw new DataValidationException("Can't assign non-existent dashboard!"); } - } - - if (deviceProfile.getFirmwareId() != null) { - OtaPackage firmware = otaPackageService.findOtaPackageById(tenantId, deviceProfile.getFirmwareId()); - if (firmware == null) { - throw new DataValidationException("Can't assign non-existent firmware!"); - } - if (!firmware.getType().equals(OtaPackageType.FIRMWARE)) { - throw new DataValidationException("Can't assign firmware with type: " + firmware.getType()); - } - if (firmware.getData() == null && !firmware.hasUrl()) { - throw new DataValidationException("Can't assign firmware with empty data!"); - } - if (!firmware.getDeviceProfileId().equals(deviceProfile.getId())) { - throw new DataValidationException("Can't assign firmware with different deviceProfile!"); + if (!dashboard.getTenantId().equals(deviceProfile.getTenantId())) { + throw new DataValidationException("Can't assign dashboard from different tenant!"); } } - if (deviceProfile.getSoftwareId() != null) { - OtaPackage software = otaPackageService.findOtaPackageById(tenantId, deviceProfile.getSoftwareId()); - if (software == null) { - throw new DataValidationException("Can't assign non-existent software!"); - } - if (!software.getType().equals(OtaPackageType.SOFTWARE)) { - throw new DataValidationException("Can't assign software with type: " + software.getType()); - } - if (software.getData() == null && !software.hasUrl()) { - throw new DataValidationException("Can't assign software with empty data!"); - } - if (!software.getDeviceProfileId().equals(deviceProfile.getId())) { - throw new DataValidationException("Can't assign firmware with different deviceProfile!"); - } - } + validateOtaPackage(tenantId, deviceProfile, deviceProfile.getId()); } @Override