diff --git a/build.gradle b/build.gradle index 8e0b1eb..9d4cca7 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,9 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' + + compile 'io.springfox:springfox-swagger2:2.9.2' + compile 'io.springfox:springfox-swagger-ui:2.9.2' } dependencyManagement { diff --git a/src/main/java/hive/caronte/swagger/CaronteLoginSwagger.java b/src/main/java/hive/caronte/swagger/CaronteLoginSwagger.java new file mode 100644 index 0000000..c58f366 --- /dev/null +++ b/src/main/java/hive/caronte/swagger/CaronteLoginSwagger.java @@ -0,0 +1,77 @@ +package hive.caronte.swagger; + +import com.fasterxml.classmate.TypeResolver; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import org.springframework.http.HttpMethod; +import springfox.documentation.builders.OperationBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.ResponseMessageBuilder; +import springfox.documentation.schema.Example; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiDescription; +import springfox.documentation.service.ResponseMessage; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.ApiListingScannerPlugin; +import springfox.documentation.spi.service.contexts.DocumentationContext; +import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator; + +import java.util.*; + +import static java.util.Collections.*; + +public class CaronteLoginSwagger implements ApiListingScannerPlugin { + @Override + public List apply(DocumentationContext context) { + return new ArrayList<>( + Arrays.asList( + new ApiDescription( + "authentication", + "/auth", + "Hive JWT Swagger", + Collections.singletonList( + new OperationBuilder( + new CachingOperationNameGenerator()) + .authorizations(new ArrayList<>()) + .codegenMethodNameStem("LogIn") + .method(HttpMethod.POST) + .notes("Use this method to authenticate in all HIVE's APIs,\n" + + " the result is a Bearer token in the response head." + + "\n\nBody request example:\n\n" + + "{\"username\":\"admin\",\"password\":\"admin\"}") + .parameters( + Collections.singletonList( //<4> + new ParameterBuilder() + .description("name & password") + .type(new TypeResolver().resolve(Object.class)) + .name("Credentials:") + .parameterType("body") + .parameterAccess("access") + .required(true) + .modelRef(new ModelRef("object")) + .build())) + .responseMessages(responseMessages()) + .responseModel(new ModelRef("string")) + .build()), + false) + )); + } + + /** + * @return Set of response messages that overide the default/global response messages + */ + private Set responseMessages() { + return singleton(new ResponseMessageBuilder() + .code(200) + .message("see the bearer token in the response header") + .responseModel(new ModelRef("string")) + .build()); + } + // tag::api-listing-plugin[] + + @Override + public boolean supports(DocumentationType delimiter) { + return DocumentationType.SWAGGER_2.equals(delimiter); + } + +} diff --git a/src/main/java/hive/caronte/swagger/SwaggerConfig.java b/src/main/java/hive/caronte/swagger/SwaggerConfig.java new file mode 100644 index 0000000..2a6841d --- /dev/null +++ b/src/main/java/hive/caronte/swagger/SwaggerConfig.java @@ -0,0 +1,64 @@ +package hive.caronte.swagger; + +import com.fasterxml.classmate.TypeResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.ApiListingScannerPlugin; +import springfox.documentation.spi.service.OperationModelsProviderPlugin; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.HashSet; +import java.util.Set; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig extends WebMvcConfigurationSupport { + + @Bean + public Docket apiDocumentation() { + Set responseContentTypes = new HashSet<>(); + responseContentTypes.add("*/*"); + responseContentTypes.add("application/json"); + responseContentTypes.add("image/jpeg"); + responseContentTypes.add("text/plain"); + return new + Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("hive.caronte.security")) + .build() + .produces(responseContentTypes) + .consumes(responseContentTypes) + .apiInfo(metaData()); + } + + private ApiInfo metaData() { + return new + ApiInfoBuilder() + .title("Caronte endpoints") + .description("\"Hive's Token API (Java JWT)\"" + + "\n Repository: https://github.com/hex-g/caronte" + + "\n Created by: https://github.com/hex-g/") + .version("v1.0") + .license("") + .licenseUrl("") + .build(); + } + @Bean + public ApiListingScannerPlugin listingScanner() { + return new CaronteLoginSwagger(); + } + @Override + protected void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + } +}