merge improvements
This commit is contained in:
parent
e768afc948
commit
a61e9d94c5
@ -31,10 +31,9 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
|||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
|
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||||
@ -136,8 +135,8 @@ public class ThingsboardSecurityConfiguration {
|
|||||||
ShallowEtagHeaderFilter etagFilter = new ShallowEtagHeaderFilter();
|
ShallowEtagHeaderFilter etagFilter = new ShallowEtagHeaderFilter();
|
||||||
etagFilter.setWriteWeakETag(true);
|
etagFilter.setWriteWeakETag(true);
|
||||||
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean
|
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean
|
||||||
= new FilterRegistrationBean<>( etagFilter);
|
= new FilterRegistrationBean<>(etagFilter);
|
||||||
filterRegistrationBean.addUrlPatterns("*.js","*.css","*.ico","/assets/*","/static/*");
|
filterRegistrationBean.addUrlPatterns("*.js", "*.css", "*.ico", "/assets/*", "/static/*");
|
||||||
filterRegistrationBean.setName("etagFilter");
|
filterRegistrationBean.setName("etagFilter");
|
||||||
return filterRegistrationBean;
|
return filterRegistrationBean;
|
||||||
}
|
}
|
||||||
@ -200,8 +199,19 @@ public class ThingsboardSecurityConfiguration {
|
|||||||
private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver;
|
private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
@Order(0)
|
||||||
return (web) -> web.ignoring().requestMatchers("/*.js", "/*.css", "/*.ico", "/assets/**", "/static/**");
|
SecurityFilterChain resources(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.securityMatchers(matchers -> matchers
|
||||||
|
.requestMatchers("/*.js", "/*.css", "/*.ico", "/assets/**", "/static/**"))
|
||||||
|
.headers(header -> header
|
||||||
|
.defaultsDisabled()
|
||||||
|
.addHeaderWriter(new StaticHeadersWriter(HttpHeaders.CACHE_CONTROL, "max-age=0, public")))
|
||||||
|
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll())
|
||||||
|
.requestCache(RequestCacheConfigurer::disable)
|
||||||
|
.securityContext(AbstractHttpConfigurer::disable)
|
||||||
|
.sessionManagement(AbstractHttpConfigurer::disable);
|
||||||
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@ -17,6 +17,10 @@ package org.thingsboard.server.controller;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
@ -36,10 +40,8 @@ import org.thingsboard.server.common.data.id.DeviceId;
|
|||||||
import org.thingsboard.server.config.annotations.ApiOperation;
|
import org.thingsboard.server.config.annotations.ApiOperation;
|
||||||
import org.thingsboard.server.dao.device.DeviceConnectivityService;
|
import org.thingsboard.server.dao.device.DeviceConnectivityService;
|
||||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||||
import org.thingsboard.server.service.security.permission.Operation;
|
|
||||||
import org.thingsboard.server.service.security.system.SystemSecurityService;
|
import org.thingsboard.server.service.security.system.SystemSecurityService;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
@ -64,16 +66,30 @@ public class DeviceConnectivityController extends BaseController {
|
|||||||
notes = "Fetch the list of commands to publish device telemetry based on device profile " +
|
notes = "Fetch the list of commands to publish device telemetry based on device profile " +
|
||||||
"If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
|
"If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " +
|
||||||
"If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " +
|
"If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " +
|
||||||
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
|
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
|
||||||
// @ApiResponses(value = {
|
responses = {
|
||||||
// @ApiResponse(code = 200, message = "OK",
|
@ApiResponse(
|
||||||
// examples = @io.swagger.annotations.Example(
|
responseCode = "200",
|
||||||
// value = {
|
description = "OK",
|
||||||
// @io.swagger.annotations.ExampleProperty(
|
content = @Content(
|
||||||
// mediaType = "application/json",
|
mediaType = MediaType.APPLICATION_JSON_VALUE,
|
||||||
// value = "{\"http\":\"curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}\"," +
|
examples = {
|
||||||
// "\"mqtt\":\"mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}\"," +
|
@ExampleObject(
|
||||||
// "\"coap\":\"coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}\"}")}))})
|
name = "http",
|
||||||
|
value = "curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}"
|
||||||
|
),
|
||||||
|
@ExampleObject(
|
||||||
|
name = "mqtt",
|
||||||
|
value = "mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}"
|
||||||
|
),
|
||||||
|
@ExampleObject(
|
||||||
|
name = "coap",
|
||||||
|
value = "coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
@RequestMapping(value = "/device-connectivity/{deviceId}", method = RequestMethod.GET)
|
@RequestMapping(value = "/device-connectivity/{deviceId}", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ -81,7 +97,7 @@ public class DeviceConnectivityController extends BaseController {
|
|||||||
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
|
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
|
||||||
checkParameter(DEVICE_ID, strDeviceId);
|
checkParameter(DEVICE_ID, strDeviceId);
|
||||||
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
|
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
|
||||||
Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS);
|
Device device = checkDeviceId(deviceId, org.thingsboard.server.service.security.permission.Operation.READ_CREDENTIALS);
|
||||||
|
|
||||||
String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request);
|
String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request);
|
||||||
return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device);
|
return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device);
|
||||||
@ -89,17 +105,26 @@ public class DeviceConnectivityController extends BaseController {
|
|||||||
|
|
||||||
@ApiOperation(value = "Get commands to launch gateway (getGatewayLaunchCommands)",
|
@ApiOperation(value = "Get commands to launch gateway (getGatewayLaunchCommands)",
|
||||||
notes = "Fetch the list of commands for different operation systems to launch a gateway using docker." +
|
notes = "Fetch the list of commands for different operation systems to launch a gateway using docker." +
|
||||||
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
|
TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH,
|
||||||
// @ApiResponses(value = {
|
responses = {
|
||||||
// @ApiResponse(code = 200, message = "OK",
|
@ApiResponse(
|
||||||
// examples = @io.swagger.annotations.Example(
|
responseCode = "200",
|
||||||
// value = {
|
description = "OK",
|
||||||
// @io.swagger.annotations.ExampleProperty(
|
content = @Content(
|
||||||
// mediaType = "application/json",
|
mediaType = MediaType.APPLICATION_JSON_VALUE,
|
||||||
// value = "{\"mqtt\": {\n" +
|
examples = {
|
||||||
// " \"linux\": \"docker run --rm -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v ~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\",\n" +
|
@ExampleObject(
|
||||||
// " \"windows\": \"docker run --rm -it -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs -v %HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\"}\n" +
|
name = "mqtt-linux",
|
||||||
// "}")}))})
|
value = "docker run --rm -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v ~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway"
|
||||||
|
),
|
||||||
|
@ExampleObject(
|
||||||
|
name = "mqtt-windows",
|
||||||
|
value = "docker run --rm -it -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs -v %HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
@RequestMapping(value = "/device-connectivity/gateway-launch/{deviceId}", method = RequestMethod.GET)
|
@RequestMapping(value = "/device-connectivity/gateway-launch/{deviceId}", method = RequestMethod.GET)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ -107,7 +132,7 @@ public class DeviceConnectivityController extends BaseController {
|
|||||||
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
|
@PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException {
|
||||||
checkParameter(DEVICE_ID, strDeviceId);
|
checkParameter(DEVICE_ID, strDeviceId);
|
||||||
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
|
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
|
||||||
Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS);
|
Device device = checkDeviceId(deviceId, org.thingsboard.server.service.security.permission.Operation.READ_CREDENTIALS);
|
||||||
|
|
||||||
if (!checkIsGateway(device)) {
|
if (!checkIsGateway(device)) {
|
||||||
throw new ThingsboardException("The device must be a gateway!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
|
throw new ThingsboardException("The device must be a gateway!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
|
||||||
|
|||||||
@ -35,7 +35,7 @@ public class WidgetTypeDetails extends WidgetType implements HasName, HasTenantI
|
|||||||
@Schema(description = "Base64 encoded thumbnail")
|
@Schema(description = "Base64 encoded thumbnail")
|
||||||
private String image;
|
private String image;
|
||||||
@NoXss
|
@NoXss
|
||||||
@Length(fieldName = "description")
|
@Length(fieldName = "description", max = 1024)
|
||||||
@Schema(description = "Description of the widget")
|
@Schema(description = "Description of the widget")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
|
|||||||
|
|
||||||
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :systemTenantId " +
|
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :systemTenantId " +
|
||||||
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
"OR ((:fullSearch) = TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
||||||
Page<WidgetTypeInfoEntity> findSystemWidgetTypes(@Param("systemTenantId") UUID systemTenantId,
|
Page<WidgetTypeInfoEntity> findSystemWidgetTypes(@Param("systemTenantId") UUID systemTenantId,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
@Param("fullSearch") boolean fullSearch,
|
@Param("fullSearch") boolean fullSearch,
|
||||||
@ -47,7 +47,7 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
|
|||||||
|
|
||||||
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId IN (:tenantId, :nullTenantId) " +
|
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId IN (:tenantId, :nullTenantId) " +
|
||||||
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
"OR ((:fullSearch) = TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
||||||
Page<WidgetTypeInfoEntity> findAllTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
|
Page<WidgetTypeInfoEntity> findAllTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
|
||||||
@Param("nullTenantId") UUID nullTenantId,
|
@Param("nullTenantId") UUID nullTenantId,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
@ -56,7 +56,7 @@ public interface WidgetTypeRepository extends JpaRepository<WidgetTypeDetailsEnt
|
|||||||
|
|
||||||
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :tenantId " +
|
@Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd WHERE wtd.tenantId = :tenantId " +
|
||||||
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
"AND (LOWER(wtd.name) LIKE LOWER(CONCAT('%', :searchText, '%')) " +
|
||||||
"OR ((:fullSearch) IS TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
"OR ((:fullSearch) = TRUE AND LOWER(wtd.description) LIKE LOWER(CONCAT('%', :searchText, '%'))))")
|
||||||
Page<WidgetTypeInfoEntity> findTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
|
Page<WidgetTypeInfoEntity> findTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
@Param("fullSearch") boolean fullSearch,
|
@Param("fullSearch") boolean fullSearch,
|
||||||
|
|||||||
@ -203,7 +203,6 @@ public class TbRestApiCallNodeTest {
|
|||||||
ArgumentCaptor<TbMsg> msgCaptor = ArgumentCaptor.forClass(TbMsg.class);
|
ArgumentCaptor<TbMsg> msgCaptor = ArgumentCaptor.forClass(TbMsg.class);
|
||||||
ArgumentCaptor<TbMsgMetaData> metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class);
|
ArgumentCaptor<TbMsgMetaData> metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class);
|
||||||
ArgumentCaptor<String> dataCaptor = ArgumentCaptor.forClass(String.class);
|
ArgumentCaptor<String> dataCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
//verify(ctx).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture());
|
|
||||||
verify(ctx).transformMsg(msgCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture());
|
verify(ctx).transformMsg(msgCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture());
|
||||||
|
|
||||||
assertNotSame(metaData, metadataCaptor.getValue());
|
assertNotSame(metaData, metadataCaptor.getValue());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user