From 8b00da12c4ae5434d0b6c0033caf3b6ffb53e6b8 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 12:16:25 +0200 Subject: [PATCH 1/8] tools cassandra-all bumped to v5 --- pom.xml | 7 +------ .../thingsboard/client/tools/migrator/WriterBuilder.java | 6 +++--- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index f95e9df9b1..e5d6c0e165 100755 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 0.10 4.17.0 4.2.25 - 3.11.17 + 5.0.4 33.1.0-jre 3.1.8 3.14.0 @@ -1827,11 +1827,6 @@ cassandra-all ${cassandra-all.version} - - org.apache.cassandra - cassandra-thrift - ${cassandra-all.version} - org.junit.vintage junit-vintage-engine diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/WriterBuilder.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/WriterBuilder.java index b7f8524031..80fdad3c1c 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/WriterBuilder.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/WriterBuilder.java @@ -59,7 +59,7 @@ public class WriterBuilder { public static CQLSSTableWriter getTsWriter(File dir) { return CQLSSTableWriter.builder() - .inDirectory(dir) + .inDirectory(dir.getAbsolutePath()) .forTable(tsSchema) .using("INSERT INTO thingsboard.ts_kv_cf (entity_type, entity_id, key, partition, ts, bool_v, str_v, long_v, dbl_v, json_v) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") @@ -68,7 +68,7 @@ public class WriterBuilder { public static CQLSSTableWriter getLatestWriter(File dir) { return CQLSSTableWriter.builder() - .inDirectory(dir) + .inDirectory(dir.getAbsolutePath()) .forTable(latestSchema) .using("INSERT INTO thingsboard.ts_kv_latest_cf (entity_type, entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)") @@ -77,7 +77,7 @@ public class WriterBuilder { public static CQLSSTableWriter getPartitionWriter(File dir) { return CQLSSTableWriter.builder() - .inDirectory(dir) + .inDirectory(dir.getAbsolutePath()) .forTable(partitionSchema) .using("INSERT INTO thingsboard.ts_kv_partitions_cf (entity_type, entity_id, key, partition) " + "VALUES (?, ?, ?, ?)") From 5111a07a1154e92263e11138bab8078acd54a8c9 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 12:23:05 +0200 Subject: [PATCH 2/8] addressing vulnerabilities on high and critical --- pom.xml | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e5d6c0e165..cd2078e70a 100755 --- a/pom.xml +++ b/pom.xml @@ -42,13 +42,14 @@ 4.0.2 2.4.0-b180830.0359 4.0.5 - 10.1.39 + 10.1.40 + 2.5.2 3.2.12 3.2.12 3.2.12 6.1.15 6.2.11 - 6.2.8 + 6.3.8 5.1.5 0.12.5 2.0.13 @@ -102,7 +103,7 @@ 1.19.0 1.78.1 2.0.1 - 42.7.3 + 42.7.5 org/thingsboard/server/gen/**/*, org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/* @@ -112,7 +113,7 @@ - 3.7.1 + 3.7.2 8.10.1 3.5.3 2.2 @@ -1163,6 +1164,13 @@ tomcat-embed-websocket ${tomcat.version} + + + net.minidev + json-smart + ${net.minidev.json-smart} + + org.springframework.boot spring-boot-starter @@ -1183,6 +1191,18 @@ spring-security-oauth2-jose ${spring-security.version} + + + org.springframework.security + spring-security-config + ${spring-security.version} + + + org.springframework.security + spring-security-web + ${spring-security.version} + + org.springframework spring-core From 9d72f5f4346d621ab4d8752b331e0990cb14eee2 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 12:24:24 +0200 Subject: [PATCH 3/8] bump californium version from 2.6.1 to 2.7.4 to fix vulnerability and not break the monitoring module --- monitoring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitoring/pom.xml b/monitoring/pom.xml index 4f59cbc975..4ef6c775bf 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -42,7 +42,7 @@ ThingsBoard Monitoring Service org.thingsboard.monitoring.ThingsboardMonitoringApplication - 2.6.1 + 2.7.4 2.0.0-M4 From dec61b8ac28be647563f33ad2565bde0feef5039 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 12:25:53 +0200 Subject: [PATCH 4/8] cassandra thrift removed after cassandra-all bump for module tools --- tools/pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/pom.xml b/tools/pom.xml index 0286c135e4..7e2c44ddd6 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -55,10 +55,6 @@ org.apache.cassandra cassandra-all - - org.apache.cassandra - cassandra-thrift - commons-io commons-io From a3c7084d7fc98492386be0217a5d7ff4c3204493 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 14:24:04 +0200 Subject: [PATCH 5/8] refactored obsolete com.github.java-json-tools:json-schema-validator with actively updated com.networknt:json-schema-validator --- common/cluster-api/pom.xml | 4 - common/dao-api/pom.xml | 4 - dao/pom.xml | 4 + .../BaseComponentDescriptorService.java | 20 ++-- .../BaseComponentDescriptorServiceTest.java | 98 +++++++++++++++++++ pom.xml | 10 +- 6 files changed, 116 insertions(+), 24 deletions(-) create mode 100644 dao/src/test/java/org/thingsboard/server/dao/component/BaseComponentDescriptorServiceTest.java diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index ee9c1eae75..75048197d3 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -60,10 +60,6 @@ jakarta.annotation jakarta.annotation-api - - com.github.java-json-tools - json-schema-validator - org.slf4j slf4j-api diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index d7142e723d..d3027356c3 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -56,10 +56,6 @@ jakarta.annotation jakarta.annotation-api - - com.github.java-json-tools - json-schema-validator - org.slf4j slf4j-api diff --git a/dao/pom.xml b/dao/pom.xml index f203343c89..9618c38386 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -59,6 +59,10 @@ org.thingsboard.common util + + com.networknt + json-schema-validator + org.slf4j slf4j-api diff --git a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java index 5acf1b0f97..2c5d6fb3c5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/component/BaseComponentDescriptorService.java @@ -16,10 +16,10 @@ package org.thingsboard.server.dao.component; import com.fasterxml.jackson.databind.JsonNode; -import com.github.fge.jsonschema.core.exceptions.ProcessingException; -import com.github.fge.jsonschema.core.report.ProcessingReport; -import com.github.fge.jsonschema.main.JsonSchemaFactory; -import com.github.fge.jsonschema.main.JsonValidator; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -36,6 +36,7 @@ import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.Validator; import java.util.Optional; +import java.util.Set; /** * @author Andrew Shvayka @@ -89,15 +90,18 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic @Override public boolean validate(TenantId tenantId, ComponentDescriptor component, JsonNode configuration) { - JsonValidator validator = JsonSchemaFactory.byDefault().getValidator(); try { if (!component.getConfigurationDescriptor().has("schema")) { throw new DataValidationException("Configuration descriptor doesn't contain schema property!"); } JsonNode configurationSchema = component.getConfigurationDescriptor().get("schema"); - ProcessingReport report = validator.validate(configurationSchema, configuration); - return report.isSuccess(); - } catch (ProcessingException e) { + + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); + JsonSchema schema = factory.getSchema(configurationSchema); + + Set validationMessages = schema.validate(configuration); + return validationMessages.isEmpty(); + } catch (Exception e) { throw new IncorrectParameterException(e.getMessage(), e); } } diff --git a/dao/src/test/java/org/thingsboard/server/dao/component/BaseComponentDescriptorServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/component/BaseComponentDescriptorServiceTest.java new file mode 100644 index 0000000000..d76c11f708 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/component/BaseComponentDescriptorServiceTest.java @@ -0,0 +1,98 @@ +/** + * Copyright © 2016-2025 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.dao.component; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; +import org.thingsboard.server.common.data.plugin.ComponentDescriptor; +import org.thingsboard.server.common.data.plugin.ComponentScope; +import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.dao.exception.IncorrectParameterException; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class BaseComponentDescriptorServiceTest { + + private BaseComponentDescriptorService service; + private ComponentDescriptor componentDescriptor; + private TenantId tenantId; + + @BeforeEach + void setUp() { + service = Mockito.spy(BaseComponentDescriptorService.class); + tenantId = TenantId.SYS_TENANT_ID; + + // Create a simple component descriptor + componentDescriptor = new ComponentDescriptor(); + componentDescriptor.setType(ComponentType.ACTION); + componentDescriptor.setScope(ComponentScope.TENANT); + componentDescriptor.setClusteringMode(ComponentClusteringMode.ENABLED); + componentDescriptor.setName("Test Component"); + componentDescriptor.setClazz("org.thingsboard.test.TestComponent"); + + // Create configuration descriptor with schema from JSON string + String configDescriptorJson = """ + { + "schema": { + "type": "object", + "properties": { + "testField": { + "type": "string" + } + }, + "required": ["testField"] + } + }"""; + + componentDescriptor.setConfigurationDescriptor(JacksonUtil.toJsonNode(configDescriptorJson)); + } + + @Test + void testValidate() { + // Create valid configuration from JSON string + String validConfigJson = "{\"testField\": \"test value\"}"; + JsonNode validConfig = JacksonUtil.toJsonNode(validConfigJson); + + // Create invalid configuration (missing required field) from JSON string + String invalidConfigJson = "{}"; + JsonNode invalidConfig = JacksonUtil.toJsonNode(invalidConfigJson); + + // Test valid configuration + boolean validResult = service.validate(tenantId, componentDescriptor, validConfig); + assertTrue(validResult, "Valid configuration should pass validation"); + + // Test invalid configuration + boolean invalidResult = service.validate(tenantId, componentDescriptor, invalidConfig); + assertFalse(invalidResult, "Invalid configuration should fail validation"); + + // Test with component descriptor without schema + ComponentDescriptor noSchemaDescriptor = new ComponentDescriptor(componentDescriptor); + noSchemaDescriptor.setConfigurationDescriptor(JacksonUtil.toJsonNode("{}")); + + // Should throw exception when schema is missing + assertThrows(IncorrectParameterException.class, () -> { + service.validate(tenantId, noSchemaDescriptor, validConfig); + }, "Should throw exception when schema is missing"); + } + +} diff --git a/pom.xml b/pom.xml index cd2078e70a..0260dc09be 100755 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ 2.17.2 1.7.0 4.4.0 - 2.2.14 + 1.5.6 0.6.12 3.12.1 2.0.0-M15 @@ -1620,15 +1620,9 @@ ${auth0-jwt.version} - com.github.java-json-tools + com.networknt json-schema-validator ${json-schema-validator.version} - - - com.sun.mail - mailapi - - org.eclipse.leshan From d608b87f945337908b4c731a10116eab35b080b0 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Sat, 10 May 2025 15:25:59 +0200 Subject: [PATCH 6/8] test scope mockserver with no dependency to not affect transitive dependencies --- pom.xml | 4 ++-- rule-engine/rule-engine-components/pom.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0260dc09be..608a46584a 100755 --- a/pom.xml +++ b/pom.xml @@ -2233,7 +2233,7 @@ org.mock-server - mockserver-netty + mockserver-netty-no-dependencies ${mock-server.version} test @@ -2245,7 +2245,7 @@ org.mock-server - mockserver-client-java + mockserver-client-java-no-dependencies ${mock-server.version} test diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 008c422dbf..b975f7c624 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -141,12 +141,12 @@ org.mock-server - mockserver-netty + mockserver-netty-no-dependencies test org.mock-server - mockserver-client-java + mockserver-client-java-no-dependencies test From afdfe451d5d6a48497e5a04e04a3399c98be4339 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Mon, 12 May 2025 12:50:47 +0200 Subject: [PATCH 7/8] test fix for givenSslIsTrueAndCredentials_whenGetSslContext_thenVerifySslContext --- .../java/org/thingsboard/rule/engine/mqtt/TbMqttNodeTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mqtt/TbMqttNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mqtt/TbMqttNodeTest.java index bf650af8bb..2438e59106 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mqtt/TbMqttNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/mqtt/TbMqttNodeTest.java @@ -181,7 +181,8 @@ public class TbMqttNodeTest extends AbstractRuleNodeUpgradeTest { SslContext actualSslContext = mqttClientConfig.getValue().getSslContext(); assertThat(actualSslContext) .usingRecursiveComparison() - .ignoringFields("ctx", "ctxLock", "sessionContext.context.ctx", "sessionContext.context.ctxLock") + .ignoringFields("ctx", "ctxLock", "sessionContext.context.ctx", "sessionContext.context.ctxLock", + "sslContext") .isEqualTo(SslContextBuilder.forClient().build()); } From be8149a4bc46c2b60ed949aaa5dba176ebe8b171 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Mon, 12 May 2025 14:25:24 +0300 Subject: [PATCH 8/8] UI: Fixed help icon color in rule node --- .../rule-node/action/gps-geo-action-config.component.html | 3 ++- .../action/save-to-custom-table-config.component.html | 1 + .../rule-node/action/timeseries-config.component.html | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/rule-node/action/gps-geo-action-config.component.html b/ui-ngx/src/app/modules/home/components/rule-node/action/gps-geo-action-config.component.html index 2d3f230643..8849d60c77 100644 --- a/ui-ngx/src/app/modules/home/components/rule-node/action/gps-geo-action-config.component.html +++ b/ui-ngx/src/app/modules/home/components/rule-node/action/gps-geo-action-config.component.html @@ -116,11 +116,12 @@ rule-node-config.polygon-definition - help + {{ 'rule-node-config.polygon-definition-required' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/rule-node/action/save-to-custom-table-config.component.html b/ui-ngx/src/app/modules/home/components/rule-node/action/save-to-custom-table-config.component.html index c9685f2c3f..aee7b9cd83 100644 --- a/ui-ngx/src/app/modules/home/components/rule-node/action/save-to-custom-table-config.component.html +++ b/ui-ngx/src/app/modules/home/components/rule-node/action/save-to-custom-table-config.component.html @@ -22,6 +22,7 @@ help diff --git a/ui-ngx/src/app/modules/home/components/rule-node/action/timeseries-config.component.html b/ui-ngx/src/app/modules/home/components/rule-node/action/timeseries-config.component.html index 9a6d06255d..f41613c6fb 100644 --- a/ui-ngx/src/app/modules/home/components/rule-node/action/timeseries-config.component.html +++ b/ui-ngx/src/app/modules/home/components/rule-node/action/timeseries-config.component.html @@ -76,9 +76,10 @@ requiredText="{{ 'rule-node-config.default-ttl-required' | translate }}" minErrorText="{{ 'rule-node-config.min-default-ttl-message' | translate }}" formControlName="defaultTTL"> - help