Merge branch 'master' into fix/tenant-removal-partition

This commit is contained in:
Viacheslav Klimov 2024-04-29 14:33:12 +03:00 committed by GitHub
commit 62516d9231
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 161 additions and 9 deletions

View File

@ -40,9 +40,9 @@ public class TbRuleEngineSecurityConfiguration {
.frameOptions(config -> {}).disable())
.cors(cors -> {})
.csrf(AbstractHttpConfigurer::disable)
.authorizeRequests()
.requestMatchers("/actuator/prometheus").permitAll()
.anyRequest().authenticated();
.authorizeHttpRequests(config -> config
.requestMatchers("/actuator/prometheus").permitAll()
.anyRequest().authenticated());
return http.build();
}
}

View File

@ -209,7 +209,7 @@ public class ThingsboardSecurityConfiguration {
.csrf(AbstractHttpConfigurer::disable)
.exceptionHandling(config -> {})
.sessionManagement(config -> config.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeRequests(config -> config
.authorizeHttpRequests(config -> config
.requestMatchers(WEBJARS_ENTRY_POINT).permitAll() // Webjars
.requestMatchers(DEVICE_API_ENTRY_POINT).permitAll() // Device HTTP Transport API
.requestMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point
@ -217,10 +217,11 @@ public class ThingsboardSecurityConfiguration {
.requestMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point
.requestMatchers(MAIL_OAUTH2_PROCESSING_ENTRY_POINT).permitAll() // Mail oauth2 code processing url
.requestMatchers(DEVICE_CONNECTIVITY_CERTIFICATE_DOWNLOAD_ENTRY_POINT).permitAll() // Device connectivity certificate (public)
.requestMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll()) // static resources, user activation and password reset end-points
.authorizeRequests(config -> config
.requestMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll() // static resources, user activation and password reset end-points
.requestMatchers(WS_ENTRY_POINT).permitAll() // Protected WebSocket API End-points
.requestMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()) // Protected API End-points
.formLogin(form -> form
.loginPage("/login").permitAll())
.exceptionHandling(config -> config.accessDeniedHandler(restAccessDeniedHandler))
.addFilterBefore(buildRestLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildRestPublicLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class)
@ -243,7 +244,7 @@ public class ThingsboardSecurityConfiguration {
@Bean
@ConditionalOnMissingBean(CorsFilter.class)
public CorsFilter corsFilter(@Autowired MvcCorsProperties mvcCorsProperties) {
if (mvcCorsProperties.getMappings().size() == 0) {
if (mvcCorsProperties.getMappings().isEmpty()) {
return new CorsFilter(new UrlBasedCorsConfigurationSource());
} else {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

View File

@ -18,18 +18,28 @@ package org.thingsboard.server.dao.service;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.AttributeScope;
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.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
@ -46,6 +56,7 @@ import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.ApiUsageStateFilter;
import org.thingsboard.server.common.data.query.AssetSearchQueryFilter;
import org.thingsboard.server.common.data.query.AssetTypeFilter;
import org.thingsboard.server.common.data.query.DeviceSearchQueryFilter;
@ -65,6 +76,7 @@ import org.thingsboard.server.common.data.query.FilterPredicateValue;
import org.thingsboard.server.common.data.query.KeyFilter;
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
import org.thingsboard.server.common.data.query.RelationsQueryFilter;
import org.thingsboard.server.common.data.query.SingleEntityFilter;
import org.thingsboard.server.common.data.query.StringFilterPredicate;
import org.thingsboard.server.common.data.query.StringFilterPredicate.StringOperation;
import org.thingsboard.server.common.data.relation.EntityRelation;
@ -72,15 +84,20 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardDao;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entity.EntityService;
import org.thingsboard.server.dao.entityview.EntityViewDao;
import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.sql.relation.RelationRepository;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService;
import org.thingsboard.server.dao.user.UserService;
import java.util.ArrayList;
@ -91,12 +108,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.thingsboard.server.common.data.query.EntityKeyType.ATTRIBUTE;
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD;
@ -106,6 +124,7 @@ import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIEL
public class EntityServiceTest extends AbstractServiceTest {
static final int ENTITY_COUNT = 5;
public static final String TEST_CUSTOMER_NAME = "Test";
@Autowired
AssetService assetService;
@ -125,6 +144,27 @@ public class EntityServiceTest extends AbstractServiceTest {
RelationService relationService;
@Autowired
TimeseriesService timeseriesService;
@Autowired
ApiUsageStateService apiUsageStateService;
@Autowired
CustomerService customerService;
@Autowired
DashboardDao dashboardDao;
@Autowired
EntityViewDao entityViewDao;
@Autowired
AlarmService alarmService;
private CustomerId customerId;
@Before
public void before() {
Customer customer = new Customer();
customer.setTenantId(tenantId);
customer.setTitle(TEST_CUSTOMER_NAME);
customer = customerService.saveCustomer(customer);
customerId = customer.getId();
}
@Test
public void testCountEntitiesByQuery() throws InterruptedException {
@ -810,7 +850,7 @@ public class EntityServiceTest extends AbstractServiceTest {
}
void createLoopRelations(TenantId tenantId, String type, EntityId... ids) {
assertThat("ids lenght", ids.length, Matchers.greaterThanOrEqualTo(1));
assertThat(ids.length).isGreaterThanOrEqualTo(1);
//chain all from the head to the tail
for (int i = 1; i < ids.length; i++) {
relationService.saveRelation(tenantId, new EntityRelation(ids[i - 1], ids[i], type, RelationTypeGroup.COMMON));
@ -1179,6 +1219,117 @@ public class EntityServiceTest extends AbstractServiceTest {
assertEquals(0, result.getTotalElements());
}
@Test
public void testFindEntitiesBySingleEntityFilter() {
List<Device> devices = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Device device = new Device();
device.setTenantId(tenantId);
device.setName("Device test" + i);
device.setType("default");
devices.add(deviceService.saveDevice(device));
}
SingleEntityFilter singleEntityFilter = new SingleEntityFilter();
singleEntityFilter.setSingleEntity(devices.get(0).getId());
List<EntityKey> entityFields = List.of(
new EntityKey(EntityKeyType.ENTITY_FIELD, "name")
);
EntityDataPageLink pageLink = new EntityDataPageLink(1000, 0, null, null);
EntityDataQuery query = new EntityDataQuery(singleEntityFilter, pageLink, entityFields, null, null);
PageData<EntityData> result = searchEntities(query);
assertEquals(1, result.getTotalElements());
String deviceName = result.getData().get(0).getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue();
assertThat(deviceName).isEqualTo(devices.get(0).getName());
}
@Test
public void testFindEntitiesByApiUsageStateFilter() {
apiUsageStateService.createDefaultApiUsageState(tenantId, customerId);
ApiUsageStateFilter apiUsageStateFilter = new ApiUsageStateFilter();
apiUsageStateFilter.setCustomerId(customerId);
List<EntityKey> entityFields = List.of(
new EntityKey(EntityKeyType.ENTITY_FIELD, "name")
);
EntityDataPageLink pageLink = new EntityDataPageLink(1000, 0, null, null);
EntityDataQuery query = new EntityDataQuery(apiUsageStateFilter, pageLink, entityFields, null, null);
PageData<EntityData> result = searchEntities(query);
assertEquals(1, result.getTotalElements());
String name = result.getData().get(0).getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue();
assertThat(name).isEqualTo(TEST_CUSTOMER_NAME);
}
@Test
public void testFindEntitiesByRelationEntityTypeFilter() {
Customer customer = new Customer();
customer.setTenantId(tenantId);
customer.setTitle("Customer Relation Query");
customer = customerService.saveCustomer(customer);
final int assetCount = 2;
final int relationsCnt = 4;
final int deviceEntitiesCnt = assetCount * relationsCnt;
List<Asset> assets = new ArrayList<>();
for (int i = 0; i < assetCount; i++) {
Asset building = new Asset();
building.setTenantId(tenantId);
building.setCustomerId(customer.getId());
building.setName("Building _" + i);
building.setType("building");
building = assetService.saveAsset(building);
assets.add(building);
}
List<Device> devices = new ArrayList<>();
for (int i = 0; i < deviceEntitiesCnt; i++) {
Device device = new Device();
device.setTenantId(tenantId);
device.setCustomerId(customer.getId());
device.setName("Test device " + i);
device.setType("default");
Device savedDevice = deviceService.saveDevice(device);
devices.add(savedDevice);
}
for (int i = 0; i < assetCount; i++) {
for (int j = 0; j < relationsCnt; j++) {
EntityRelation relationEntity = new EntityRelation();
relationEntity.setFrom(assets.get(i).getId());
relationEntity.setTo(devices.get(j + (i * relationsCnt)).getId());
relationEntity.setTypeGroup(RelationTypeGroup.COMMON);
relationEntity.setType("contains");
relationService.saveRelation(tenantId, relationEntity);
}
}
RelationEntityTypeFilter relationEntityTypeFilter = new RelationEntityTypeFilter("contains", Collections.singletonList(EntityType.DEVICE));
RelationsQueryFilter filter = new RelationsQueryFilter();
filter.setFilters(Collections.singletonList(relationEntityTypeFilter));
filter.setDirection(EntitySearchDirection.FROM);
EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, null);
List<KeyFilter> keyFiltersEqualString = createStringKeyFilters("name", EntityKeyType.ENTITY_FIELD, StringOperation.STARTS_WITH, "Test device ");
for (Asset asset : assets) {
filter.setRootEntity(asset.getId());
EntityDataQuery query = new EntityDataQuery(filter, pageLink, Collections.emptyList(), Collections.emptyList(), keyFiltersEqualString);
PageData<EntityData> relationsResult = entityService.findEntityDataByQuery(tenantId, customer.getId(), query);
long relationsResultCnt = entityService.countEntitiesByQuery(tenantId, customer.getId(), query);
Assert.assertEquals(relationsCnt, relationsResult.getData().size());
Assert.assertEquals(relationsCnt, relationsResultCnt);
}
}
@Test
public void testFindEntityDataByQuery_filter_device_type_name_ends_with() {
List<Device> devices = new ArrayList<>();