Update springfox swagger version.
This commit is contained in:
		
							parent
							
								
									944b2f7572
								
							
						
					
					
						commit
						d110f5a005
					
				@ -250,8 +250,8 @@
 | 
			
		||||
            <artifactId>grpc-stub</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>io.springfox</groupId>
 | 
			
		||||
            <artifactId>springfox-swagger2</artifactId>
 | 
			
		||||
            <groupId>org.thingsboard</groupId>
 | 
			
		||||
            <artifactId>springfox-boot-starter</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.sun.winsw</groupId>
 | 
			
		||||
@ -319,10 +319,6 @@
 | 
			
		||||
            <groupId>org.javadelight</groupId>
 | 
			
		||||
            <artifactId>delight-nashorn-sandbox</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>io.springfox.ui</groupId>
 | 
			
		||||
            <artifactId>springfox-swagger-ui-rfc6570</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.passay</groupId>
 | 
			
		||||
            <artifactId>passay</artifactId>
 | 
			
		||||
 | 
			
		||||
@ -20,13 +20,11 @@ import org.springframework.boot.SpringBootConfiguration;
 | 
			
		||||
import org.springframework.context.annotation.ComponentScan;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableAsync;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableScheduling;
 | 
			
		||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
@SpringBootConfiguration
 | 
			
		||||
@EnableAsync
 | 
			
		||||
@EnableSwagger2
 | 
			
		||||
@EnableScheduling
 | 
			
		||||
@ComponentScan({"org.thingsboard.server"})
 | 
			
		||||
public class ThingsboardServerApplication {
 | 
			
		||||
 | 
			
		||||
@ -18,27 +18,60 @@ package org.thingsboard.server.config;
 | 
			
		||||
import com.fasterxml.classmate.ResolvedType;
 | 
			
		||||
import com.fasterxml.classmate.TypeResolver;
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.google.common.base.Predicate;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Value;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.core.annotation.Order;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.MediaType;
 | 
			
		||||
import org.thingsboard.server.common.data.security.Authority;
 | 
			
		||||
import org.thingsboard.server.exception.ThingsboardErrorResponse;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.LoginRequest;
 | 
			
		||||
import org.thingsboard.server.service.security.auth.rest.LoginResponse;
 | 
			
		||||
import springfox.documentation.builders.ApiInfoBuilder;
 | 
			
		||||
import springfox.documentation.schema.AlternateTypeRule;
 | 
			
		||||
import springfox.documentation.builders.OperationBuilder;
 | 
			
		||||
import springfox.documentation.builders.RepresentationBuilder;
 | 
			
		||||
import springfox.documentation.builders.RequestParameterBuilder;
 | 
			
		||||
import springfox.documentation.builders.ResponseBuilder;
 | 
			
		||||
import springfox.documentation.service.ApiDescription;
 | 
			
		||||
import springfox.documentation.service.ApiInfo;
 | 
			
		||||
import springfox.documentation.service.ApiKey;
 | 
			
		||||
import springfox.documentation.service.ApiListing;
 | 
			
		||||
import springfox.documentation.service.AuthorizationScope;
 | 
			
		||||
import springfox.documentation.service.Contact;
 | 
			
		||||
import springfox.documentation.service.HttpLoginPasswordScheme;
 | 
			
		||||
import springfox.documentation.service.ParameterType;
 | 
			
		||||
import springfox.documentation.service.Response;
 | 
			
		||||
import springfox.documentation.service.SecurityReference;
 | 
			
		||||
import springfox.documentation.service.SecurityScheme;
 | 
			
		||||
import springfox.documentation.service.Tag;
 | 
			
		||||
import springfox.documentation.spi.DocumentationType;
 | 
			
		||||
import springfox.documentation.spi.service.ApiListingBuilderPlugin;
 | 
			
		||||
import springfox.documentation.spi.service.ApiListingScannerPlugin;
 | 
			
		||||
import springfox.documentation.spi.service.contexts.ApiListingContext;
 | 
			
		||||
import springfox.documentation.spi.service.contexts.DocumentationContext;
 | 
			
		||||
import springfox.documentation.spi.service.contexts.OperationContext;
 | 
			
		||||
import springfox.documentation.spi.service.contexts.SecurityContext;
 | 
			
		||||
import springfox.documentation.spring.web.plugins.Docket;
 | 
			
		||||
import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator;
 | 
			
		||||
import springfox.documentation.swagger.common.SwaggerPluginSupport;
 | 
			
		||||
import springfox.documentation.swagger.web.DocExpansion;
 | 
			
		||||
import springfox.documentation.swagger.web.ModelRendering;
 | 
			
		||||
import springfox.documentation.swagger.web.OperationsSorter;
 | 
			
		||||
import springfox.documentation.swagger.web.UiConfiguration;
 | 
			
		||||
import springfox.documentation.swagger.web.UiConfigurationBuilder;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
import static com.google.common.base.Predicates.and;
 | 
			
		||||
import static com.google.common.base.Predicates.not;
 | 
			
		||||
import static com.google.common.collect.Lists.newArrayList;
 | 
			
		||||
import static java.util.function.Predicate.not;
 | 
			
		||||
import static springfox.documentation.builders.PathSelectors.any;
 | 
			
		||||
import static springfox.documentation.builders.PathSelectors.regex;
 | 
			
		||||
 | 
			
		||||
@Configuration
 | 
			
		||||
@ -67,6 +100,9 @@ public class SwaggerConfiguration {
 | 
			
		||||
    @Value("${swagger.version}")
 | 
			
		||||
    private String version;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private CachingOperationNameGenerator operationNames;
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    public Docket thingsboardApi() {
 | 
			
		||||
        TypeResolver typeResolver = new TypeResolver();
 | 
			
		||||
@ -77,29 +113,110 @@ public class SwaggerConfiguration {
 | 
			
		||||
                typeResolver.resolve(
 | 
			
		||||
                        String.class);
 | 
			
		||||
 | 
			
		||||
        return new Docket(DocumentationType.SWAGGER_2)
 | 
			
		||||
        return new Docket(DocumentationType.OAS_30)
 | 
			
		||||
                .groupName("thingsboard")
 | 
			
		||||
                .apiInfo(apiInfo())
 | 
			
		||||
                .alternateTypeRules(
 | 
			
		||||
                .additionalModels(
 | 
			
		||||
                        typeResolver.resolve(ThingsboardErrorResponse.class),
 | 
			
		||||
                        typeResolver.resolve(LoginRequest.class),
 | 
			
		||||
                        typeResolver.resolve(LoginResponse.class)
 | 
			
		||||
                )
 | 
			
		||||
               /* .alternateTypeRules(
 | 
			
		||||
                        new AlternateTypeRule(
 | 
			
		||||
                                jsonNodeType,
 | 
			
		||||
                                stringType))
 | 
			
		||||
                                stringType))*/
 | 
			
		||||
                .select()
 | 
			
		||||
                .paths(apiPaths())
 | 
			
		||||
                .paths(any())
 | 
			
		||||
                .build()
 | 
			
		||||
                .securitySchemes(newArrayList(jwtTokenKey()))
 | 
			
		||||
                .globalResponses(HttpMethod.GET,
 | 
			
		||||
                        List.of(
 | 
			
		||||
                            new ResponseBuilder()
 | 
			
		||||
                                    .code("401")
 | 
			
		||||
                                    .description("Unauthorized")
 | 
			
		||||
                                    .representation(MediaType.APPLICATION_JSON)
 | 
			
		||||
                                    .apply(classRepresentation(ThingsboardErrorResponse.class, true))
 | 
			
		||||
                                    .build()
 | 
			
		||||
                        )
 | 
			
		||||
                )
 | 
			
		||||
                .securitySchemes(newArrayList(httpLogin()))
 | 
			
		||||
                .securityContexts(newArrayList(securityContext()))
 | 
			
		||||
                .enableUrlTemplating(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ApiKey jwtTokenKey() {
 | 
			
		||||
        return new ApiKey("X-Authorization", "JWT token", "header");
 | 
			
		||||
    @Bean
 | 
			
		||||
    @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
 | 
			
		||||
    ApiListingScannerPlugin loginEndpointListingScanner() {
 | 
			
		||||
        return new ApiListingScannerPlugin() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public List<ApiDescription> apply(DocumentationContext context) {
 | 
			
		||||
                return List.of(loginEndpointApiDescription());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean supports(DocumentationType delimiter) {
 | 
			
		||||
                return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER)
 | 
			
		||||
    ApiListingBuilderPlugin loginEndpointListingBuilder() {
 | 
			
		||||
        return new ApiListingBuilderPlugin() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void apply(ApiListingContext apiListingContext) {
 | 
			
		||||
                if (apiListingContext.getResourceGroup().getGroupName().equals("default")) {
 | 
			
		||||
                    ApiListing apiListing = apiListingContext.apiListingBuilder().build();
 | 
			
		||||
                    if (apiListing.getResourcePath().equals("/api/auth/login")) {
 | 
			
		||||
                        apiListingContext.apiListingBuilder().tags(Set.of(new Tag("login-endpoint", "Login Endpoint")));
 | 
			
		||||
                        apiListingContext.apiListingBuilder().description("Login Endpoint");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean supports(DocumentationType delimiter) {
 | 
			
		||||
                return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    UiConfiguration uiConfig() {
 | 
			
		||||
        return UiConfigurationBuilder.builder()
 | 
			
		||||
                .deepLinking(true)
 | 
			
		||||
                .displayOperationId(false)
 | 
			
		||||
                .defaultModelsExpandDepth(1)
 | 
			
		||||
                .defaultModelExpandDepth(1)
 | 
			
		||||
                .defaultModelRendering(ModelRendering.EXAMPLE)
 | 
			
		||||
                .displayRequestDuration(false)
 | 
			
		||||
                .docExpansion(DocExpansion.NONE)
 | 
			
		||||
                .filter(false)
 | 
			
		||||
                .maxDisplayedTags(null)
 | 
			
		||||
                .operationsSorter(OperationsSorter.ALPHA)
 | 
			
		||||
                .showExtensions(false)
 | 
			
		||||
                .showCommonExtensions(false)
 | 
			
		||||
                .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
 | 
			
		||||
                .validatorUrl(null)
 | 
			
		||||
                .syntaxHighlightActivate(true)
 | 
			
		||||
                .syntaxHighlightTheme("agate")
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SecurityScheme httpLogin() {
 | 
			
		||||
        return HttpLoginPasswordScheme
 | 
			
		||||
                .X_AUTHORIZATION_BUILDER
 | 
			
		||||
                .loginEndpoint("/api/auth/login")
 | 
			
		||||
                .name("HTTP login form")
 | 
			
		||||
                .description("Enter Username / Password")
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private SecurityContext securityContext() {
 | 
			
		||||
        return SecurityContext.builder()
 | 
			
		||||
                .securityReferences(defaultAuth())
 | 
			
		||||
                .forPaths(securityPaths())
 | 
			
		||||
                .operationSelector(securityPathOperationSelector())
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -107,11 +224,8 @@ public class SwaggerConfiguration {
 | 
			
		||||
        return regex(apiPathRegex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Predicate<String> securityPaths() {
 | 
			
		||||
        return and(
 | 
			
		||||
                regex(securityPathRegex),
 | 
			
		||||
                not(regex(nonSecurityPathRegex))
 | 
			
		||||
        );
 | 
			
		||||
    private Predicate<OperationContext> securityPathOperationSelector() {
 | 
			
		||||
        return new SecurityPathOperationSelector(securityPathRegex, nonSecurityPathRegex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    List<SecurityReference> defaultAuth() {
 | 
			
		||||
@ -120,7 +234,7 @@ public class SwaggerConfiguration {
 | 
			
		||||
        authorizationScopes[1] = new AuthorizationScope(Authority.TENANT_ADMIN.name(), "Tenant administrator");
 | 
			
		||||
        authorizationScopes[2] = new AuthorizationScope(Authority.CUSTOMER_USER.name(), "Customer");
 | 
			
		||||
        return newArrayList(
 | 
			
		||||
                new SecurityReference("X-Authorization", authorizationScopes));
 | 
			
		||||
                new SecurityReference("HTTP login form", authorizationScopes));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ApiInfo apiInfo() {
 | 
			
		||||
@ -134,4 +248,75 @@ public class SwaggerConfiguration {
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ApiDescription loginEndpointApiDescription() {
 | 
			
		||||
        return new ApiDescription(null, "/api/auth/login", "Login method to get user JWT token data", "Login endpoint", Collections.singletonList(
 | 
			
		||||
                new OperationBuilder(operationNames)
 | 
			
		||||
                        .summary("Login method to get user JWT token data")
 | 
			
		||||
                        .tags(Set.of("login-endpoint"))
 | 
			
		||||
                        .authorizations(new ArrayList<>())
 | 
			
		||||
                        .position(0)
 | 
			
		||||
                        .codegenMethodNameStem("loginPost")
 | 
			
		||||
                        .method(HttpMethod.POST)
 | 
			
		||||
                        .notes("Login method to get user JWT token data.\n\nValue of the response **token** field can be used as JWT token value for authorization.")
 | 
			
		||||
                        .requestParameters(
 | 
			
		||||
                                List.of(
 | 
			
		||||
                                        new RequestParameterBuilder()
 | 
			
		||||
                                                .in(ParameterType.BODY)
 | 
			
		||||
                                                .required(true)
 | 
			
		||||
                                                .description("Login request")
 | 
			
		||||
                                                .content(c ->
 | 
			
		||||
                                                         c.requestBody(true)
 | 
			
		||||
                                                          .representation(MediaType.APPLICATION_JSON)
 | 
			
		||||
                                                          .apply(classRepresentation(LoginRequest.class, false))
 | 
			
		||||
                                                )
 | 
			
		||||
                                                .build()
 | 
			
		||||
                                )
 | 
			
		||||
                        )
 | 
			
		||||
                        .responses(loginResponses())
 | 
			
		||||
                        .build()
 | 
			
		||||
        ), false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Collection<Response> loginResponses() {
 | 
			
		||||
        return List.of(
 | 
			
		||||
                new ResponseBuilder()
 | 
			
		||||
                        .code("200")
 | 
			
		||||
                        .description("OK")
 | 
			
		||||
                        .representation(MediaType.APPLICATION_JSON)
 | 
			
		||||
                        .apply(classRepresentation(LoginResponse.class, true)).
 | 
			
		||||
                        build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Helper methods **/
 | 
			
		||||
 | 
			
		||||
    private Consumer<RepresentationBuilder> classRepresentation(Class clazz, boolean isResponse) {
 | 
			
		||||
        return r -> r.model(
 | 
			
		||||
                m ->
 | 
			
		||||
                        m.referenceModel(ref ->
 | 
			
		||||
                                ref.key(k ->
 | 
			
		||||
                                        k.qualifiedModelName(q ->
 | 
			
		||||
                                                q.namespace(clazz.getPackageName())
 | 
			
		||||
                                                        .name(clazz.getSimpleName())).isResponse(isResponse)))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class SecurityPathOperationSelector implements Predicate<OperationContext> {
 | 
			
		||||
 | 
			
		||||
        private final Predicate<String> securityPathSelector;
 | 
			
		||||
 | 
			
		||||
        SecurityPathOperationSelector(String securityPathRegex, String nonSecurityPathRegex) {
 | 
			
		||||
            this.securityPathSelector = regex(securityPathRegex).and(
 | 
			
		||||
                not(
 | 
			
		||||
                    regex(nonSecurityPathRegex)
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean test(OperationContext operationContext) {
 | 
			
		||||
            return this.securityPathSelector.test(operationContext.requestMappingPattern());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -64,6 +64,7 @@ import java.util.List;
 | 
			
		||||
public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapter {
 | 
			
		||||
 | 
			
		||||
    public static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
 | 
			
		||||
    public static final String JWT_TOKEN_HEADER_PARAM_V2 = "Authorization";
 | 
			
		||||
    public static final String JWT_TOKEN_QUERY_PARAM = "token";
 | 
			
		||||
 | 
			
		||||
    public static final String WEBJARS_ENTRY_POINT = "/webjars/**";
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,20 @@ package org.thingsboard.server.config;
 | 
			
		||||
import org.springframework.stereotype.Controller;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
@Controller
 | 
			
		||||
public class WebConfig {
 | 
			
		||||
 | 
			
		||||
    @RequestMapping(value = {"/assets", "/assets/", "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)[^\\.]*}/**"})
 | 
			
		||||
    @RequestMapping(value = {"/assets", "/assets/", "/{path:^(?!api$)(?!assets$)(?!static$)(?!webjars$)(?!swagger-ui$)[^\\.]*}/**"})
 | 
			
		||||
    public String redirect() {
 | 
			
		||||
        return "forward:/index.html";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @RequestMapping("/swagger-ui.html")
 | 
			
		||||
    public void redirectSwagger(HttpServletResponse response) throws IOException {
 | 
			
		||||
        response.sendRedirect("/swagger-ui/");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,7 @@ public class ControllerConstants {
 | 
			
		||||
    protected static final String OTA_PACKAGE_ID_PARAM_DESCRIPTION = "A string value representing the ota package id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
    protected static final String ENTITY_TYPE_PARAM_DESCRIPTION = "A string value representing the entity type. For example, 'DEVICE'";
 | 
			
		||||
    protected static final String RULE_CHAIN_ID_PARAM_DESCRIPTION = "A string value representing the rule chain id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
    protected static final String RULE_NODE_ID_PARAM_DESCRIPTION = "A string value representing the rule node id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
    protected static final String WIDGET_BUNDLE_ID_PARAM_DESCRIPTION = "A string value representing the widget bundle id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
    protected static final String WIDGET_TYPE_ID_PARAM_DESCRIPTION = "A string value representing the widget type id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
    protected static final String RESOURCE_ID_PARAM_DESCRIPTION = "A string value representing the resource id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'";
 | 
			
		||||
 | 
			
		||||
@ -95,6 +95,7 @@ import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_S
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TEXT_SEARCH_DESCRIPTION;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPES_ALLOWABLE_VALUES;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPE_DESCRIPTION;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.RULE_NODE_ID_PARAM_DESCRIPTION;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION;
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION;
 | 
			
		||||
@ -434,7 +435,7 @@ public class RuleChainController extends BaseController {
 | 
			
		||||
    @RequestMapping(value = "/ruleNode/{ruleNodeId}/debugIn", method = RequestMethod.GET)
 | 
			
		||||
    @ResponseBody
 | 
			
		||||
    public JsonNode getLatestRuleNodeDebugInput(
 | 
			
		||||
            @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION)
 | 
			
		||||
            @ApiParam(value = RULE_NODE_ID_PARAM_DESCRIPTION)
 | 
			
		||||
            @PathVariable(RULE_NODE_ID) String strRuleNodeId) throws ThingsboardException {
 | 
			
		||||
        checkParameter(RULE_NODE_ID, strRuleNodeId);
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ public class WidgetsBundleController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    @ApiOperation(value = "Create Or Update Widget Bundle (saveWidgetsBundle)",
 | 
			
		||||
            notes = "Create or update the Widget Bundle. " + WIDGET_BUNDLE_DESCRIPTION + " " +
 | 
			
		||||
                    "When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address). " +
 | 
			
		||||
                    "When creating the bundle, platform generates Widget Bundle Id as [time-based UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_(date-time_and_MAC_address)). " +
 | 
			
		||||
                    "The newly created Widget Bundle Id will be present in the response. " +
 | 
			
		||||
                    "Specify existing Widget Bundle id to update the Widget Bundle. " +
 | 
			
		||||
                    "Referencing non-existing Widget Bundle Id will cause 'Not Found' error." +
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,10 @@ public class JwtHeaderTokenExtractor implements TokenExtractor {
 | 
			
		||||
    public String extract(HttpServletRequest request) {
 | 
			
		||||
        String header = request.getHeader(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM);
 | 
			
		||||
        if (StringUtils.isBlank(header)) {
 | 
			
		||||
            throw new AuthenticationServiceException("Authorization header cannot be blank!");
 | 
			
		||||
            header = request.getHeader(ThingsboardSecurityConfiguration.JWT_TOKEN_HEADER_PARAM_V2);
 | 
			
		||||
            if (StringUtils.isBlank(header)) {
 | 
			
		||||
                throw new AuthenticationServiceException("Authorization header cannot be blank!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (header.length() < HEADER_PREFIX.length()) {
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,14 @@ package org.thingsboard.server.service.security.auth.rest;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonCreator;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
import io.swagger.annotations.ApiModel;
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
 | 
			
		||||
@ApiModel
 | 
			
		||||
public class LoginRequest {
 | 
			
		||||
 | 
			
		||||
    private String username;
 | 
			
		||||
 | 
			
		||||
    private String password;
 | 
			
		||||
 | 
			
		||||
    @JsonCreator
 | 
			
		||||
@ -28,10 +33,12 @@ public class LoginRequest {
 | 
			
		||||
        this.password = password;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 1, required = true, value = "User email", example = "tenant@thingsboard.org")
 | 
			
		||||
    public String getUsername() {
 | 
			
		||||
        return username;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 2, required = true, value = "User password", example = "tenant")
 | 
			
		||||
    public String getPassword() {
 | 
			
		||||
        return password;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright © 2016-2021 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.service.security.auth.rest;
 | 
			
		||||
 | 
			
		||||
import io.swagger.annotations.ApiModel;
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
@ApiModel
 | 
			
		||||
@Data
 | 
			
		||||
public class LoginResponse {
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 1, required = true, value = "JWT token",
 | 
			
		||||
            example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...")
 | 
			
		||||
    private String token;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(position = 2, required = true, value = "Refresh token",
 | 
			
		||||
            example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...")
 | 
			
		||||
    private String refreshToken;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -845,9 +845,9 @@ edges:
 | 
			
		||||
    persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}"
 | 
			
		||||
 | 
			
		||||
swagger:
 | 
			
		||||
  api_path_regex: "${SWAGGER_API_PATH_REGEX:/api.*}"
 | 
			
		||||
  security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api.*}"
 | 
			
		||||
  non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/noauth.*}"
 | 
			
		||||
  api_path_regex: "${SWAGGER_API_PATH_REGEX:/api/.*}"
 | 
			
		||||
  security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api/.*}"
 | 
			
		||||
  non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/(?:noauth|v1)/.*}"
 | 
			
		||||
  title: "${SWAGGER_TITLE:ThingsBoard REST API}"
 | 
			
		||||
  description: "${SWAGGER_DESCRIPTION:For instructions how to authorize requests please visit <a href='http://thingsboard.io/docs/reference/rest-api/'>REST API documentation page</a>.}"
 | 
			
		||||
  contact:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								pom.xml
									
									
									
									
									
								
							@ -46,8 +46,8 @@
 | 
			
		||||
        <spring-data-redis.version>2.4.3</spring-data-redis.version>
 | 
			
		||||
        <jedis.version>3.3.0</jedis.version>
 | 
			
		||||
        <jjwt.version>0.7.0</jjwt.version>
 | 
			
		||||
        <slf4j.version>1.7.7</slf4j.version>
 | 
			
		||||
        <logback.version>1.2.3</logback.version>
 | 
			
		||||
        <slf4j.version>1.7.32</slf4j.version>
 | 
			
		||||
        <logback.version>1.2.6</logback.version>
 | 
			
		||||
        <rat.version>0.10</rat.version>
 | 
			
		||||
        <cassandra.version>4.10.0</cassandra.version>
 | 
			
		||||
        <metrics.version>4.0.5</metrics.version>
 | 
			
		||||
@ -83,9 +83,8 @@
 | 
			
		||||
        <rabbitmq.version>4.8.0</rabbitmq.version>
 | 
			
		||||
        <surfire.version>2.19.1</surfire.version>
 | 
			
		||||
        <jar-plugin.version>3.0.2</jar-plugin.version>
 | 
			
		||||
        <springfox-swagger.version>2.6.1</springfox-swagger.version>
 | 
			
		||||
        <springfox-swagger-ui-rfc6570.version>1.0.0</springfox-swagger-ui-rfc6570.version>
 | 
			
		||||
        <swagger-annotations.version>1.5.10</swagger-annotations.version>
 | 
			
		||||
        <springfox-swagger.version>3.0.1</springfox-swagger.version>
 | 
			
		||||
        <swagger-annotations.version>1.6.3</swagger-annotations.version>
 | 
			
		||||
        <spatial4j.version>0.7</spatial4j.version>
 | 
			
		||||
        <jts.version>1.15.0</jts.version>
 | 
			
		||||
        <bouncycastle.version>1.67</bouncycastle.version>
 | 
			
		||||
@ -1620,8 +1619,8 @@
 | 
			
		||||
                <version>${curator.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>io.springfox</groupId>
 | 
			
		||||
                <artifactId>springfox-swagger2</artifactId>
 | 
			
		||||
                <groupId>org.thingsboard</groupId>
 | 
			
		||||
                <artifactId>springfox-boot-starter</artifactId>
 | 
			
		||||
                <version>${springfox-swagger.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
@ -1699,11 +1698,6 @@
 | 
			
		||||
                <artifactId>fst</artifactId>
 | 
			
		||||
                <version>${fst.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>io.springfox.ui</groupId>
 | 
			
		||||
                <artifactId>springfox-swagger-ui-rfc6570</artifactId>
 | 
			
		||||
                <version>${springfox-swagger-ui-rfc6570.version}</version>
 | 
			
		||||
            </dependency>
 | 
			
		||||
            <dependency>
 | 
			
		||||
                <groupId>org.locationtech.spatial4j</groupId>
 | 
			
		||||
                <artifactId>spatial4j</artifactId>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user