diff --git a/README.md b/README.md index bb1ede559..c34cf18bc 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,14 @@ ## Requirements_ -* Java 8 (note that ONLY Java 8 is supported at this time; other later versions might work) +* Java 11 (note that ONLY Java 11 is supported at this time; other later versions might work) ## Running There are currently 2 ways to run the application: -1. As an executable -1. deployed in a Java Servlet 3.0 container +1. As an executable WAR using Java +1. deployed in a Java Servlet 3.0 container such as Tomcat or Jetty Note that some features require encoded slashes in the URL. In tomcat (which is embedded in the war), this can be allowed with: @@ -57,6 +57,7 @@ beginning with `#` are commented out. # Server Configuration #server.port=8080 + # Logging Configuration #logging.config=classpath:log4j2.xml #logging.level.org.springframework.web=ERROR @@ -110,4 +111,10 @@ spring.profiles.active=default # Password for the default user. If not set, a password will be generated at startup #shibui.default-password= -``` + +springdoc.use-management-port=true +springdoc.pathsToMatch=/entities, /api/** +# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path. +management.endpoints.web.exposure.include=openapi, swagger-ui +management.server.port=9090 +``` \ No newline at end of file diff --git a/backend/build.gradle b/backend/build.gradle index f41778d28..7bdef8336 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -171,9 +171,8 @@ dependencies { runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.2.0' runtimeOnly 'mysql:mysql-connector-java:5.1.48' - //Swagger - compile 'io.springfox:springfox-swagger2:2.9.2' - compile 'io.springfox:springfox-swagger-ui:2.9.2' + //Swagger 3 + implementation 'org.springdoc:springdoc-openapi-ui:1.6.8' testCompile "org.springframework.boot:spring-boot-starter-test" testCompile "org.springframework.security:spring-security-test" diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityAttributesFiltersUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityAttributesFiltersUiDefinitionController.groovy index 556adb962..5ae31882c 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityAttributesFiltersUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityAttributesFiltersUiDefinitionController.groovy @@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -24,6 +26,7 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR */ @RestController @RequestMapping('/api/ui/EntityAttributesFilters') +@Tags(value = [@Tag(name = "ui")]) class EntityAttributesFiltersUiDefinitionController { @Autowired @@ -58,4 +61,4 @@ class EntityAttributesFiltersUiDefinitionController { void init() { this.jsonSchemaLocation = entityAttributesFiltersSchema(this.jsonSchemaResourceLocationRegistry); } -} +} \ No newline at end of file diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy index e6c878b0b..35815d31e 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolverUiDefinitionController.groovy @@ -3,6 +3,8 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -10,11 +12,11 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.filesystemMetadataProviderSchema import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema -import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR /** * Controller implementing REST resource responsible for exposing structure definition for metadata resolvers user @@ -25,6 +27,7 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResour */ @RestController @RequestMapping('/api/ui/MetadataResolver') +@Tags(value = [@Tag(name = "ui")]) class MetadataResolverUiDefinitionController { @Autowired @@ -66,4 +69,4 @@ class MetadataResolverUiDefinitionController { ResponseEntity getResolverTypes() { return ResponseEntity.ok(SchemaType.getResolverTypes()) } -} +} \ No newline at end of file diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy index bf685db05..db00c31d3 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy @@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -26,6 +28,7 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR */ @RestController @RequestMapping('/api/ui/MetadataSources') +@Tags(value = [@Tag(name = "ui")]) class MetadataSourcesUiDefinitionController { private static final Logger logger = LoggerFactory.getLogger(MetadataSourcesUiDefinitionController.class); @@ -63,4 +66,4 @@ class MetadataSourcesUiDefinitionController { void init() { this.jsonSchemaLocation = metadataSourcesSchema(this.jsonSchemaResourceLocationRegistry); } -} +} \ No newline at end of file diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/NameIdFormatFilterUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/NameIdFormatFilterUiDefinitionController.groovy index 3dcfcaffe..2283183be 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/NameIdFormatFilterUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/NameIdFormatFilterUiDefinitionController.groovy @@ -5,6 +5,8 @@ import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocat import edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocationRegistry import edu.internet2.tier.shibboleth.admin.ui.service.JsonSchemaBuilderService import groovy.util.logging.Slf4j +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -25,6 +27,7 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR @RestController @RequestMapping('/api/ui/NameIdFormatFilter') @Slf4j +@Tags(value = [@Tag(name = "ui")]) class NameIdFormatFilterUiDefinitionController { @Autowired @@ -57,4 +60,4 @@ class NameIdFormatFilterUiDefinitionController { void init() { this.jsonSchemaLocation = nameIdFormatFilterSchema(this.jsonSchemaResourceLocationRegistry) } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java index d539ad025..41393a625 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java @@ -2,6 +2,8 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Info; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +33,7 @@ @EnableScheduling @EnableWebSecurity @EnableAsync +@OpenAPIDefinition(info=@Info(description = "The Shibboleth UI is specifically designed to help manage and edit metadata-driven configuration support for Shibboleth", title = "Shibboleth UI API", version = "1.0")) public class ShibbolethUiApplication extends SpringBootServletInitializer { private static final Logger logger = LoggerFactory.getLogger(ShibbolethUiApplication.class); @@ -86,4 +89,4 @@ public void initializeResolvers(ApplicationStartedEvent e) { }); } } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SwaggerConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SwaggerConfig.java deleted file mode 100644 index 1f48b6e2f..000000000 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SwaggerConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package edu.internet2.tier.shibboleth.admin.ui.configuration; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -@Configuration -@EnableSwagger2 -public class SwaggerConfig { - - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.regex("/api/.*")) - .build(); - } -} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java index 8584ff303..f04f2f716 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/auto/WebSecurityConfig.java @@ -135,6 +135,7 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { public void configure(WebSecurity web) throws Exception { super.configure(web); web.httpFirewall(allowUrlEncodedSlashHttpFirewall()); + web.ignoring().antMatchers("/actuator/**"); } }; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java index 60705cd15..c9e0f20f5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ActivateController.java @@ -2,6 +2,8 @@ import javax.script.ScriptException; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -25,6 +27,7 @@ @RestController @RequestMapping("/api/activate") +@Tags(value = {@Tag(name = "activate")}) public class ActivateController { @Autowired @@ -62,4 +65,4 @@ public ResponseEntity enableProvider(@PathVariable String resourceId, @PathVa return ResponseEntity.ok(existingResolver); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java index 1dbe5e026..92c498781 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/AttributeBundleController.java @@ -7,6 +7,8 @@ import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; import edu.internet2.tier.shibboleth.admin.ui.service.AttributeBundleService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -25,6 +27,7 @@ @RestController @RequestMapping("/api/custom/entity/bundles") @Slf4j +@Tags(value = {@Tag(name = "bundles")}) public class AttributeBundleController { @Autowired AttributeBundleService attributeBundleService; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java index fa458816a..b9c58d60f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java @@ -3,19 +3,20 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomPropertiesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.security.model.Role; import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository; -import edu.internet2.tier.shibboleth.admin.ui.service.EmailService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.stream.Collectors; /** * @author Bill Smith (wsmith@unicon.net) */ -@Controller +@RestController @RequestMapping(value = "/api") public class ConfigurationController { @@ -26,12 +27,14 @@ public class ConfigurationController { RoleRepository roleRepository; @GetMapping(value = "/customAttributes") + @Tags(value = {@Tag(name = "attributes")}) public ResponseEntity getCustomAttributes() { return ResponseEntity.ok(customPropertiesConfiguration.getAttributes()); } @GetMapping(value = "/supportedRoles") + @Tags(value = {@Tag(name = "admin")}) public ResponseEntity getSupportedRoles() { return ResponseEntity.ok(roleRepository.findAll().stream().map(Role::getName).collect(Collectors.toList())); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java index bd683de22..517be9958 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/CustomEntityAttributesDefinitionsController.java @@ -1,10 +1,13 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; +import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; +import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -13,13 +16,12 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import edu.internet2.tier.shibboleth.admin.ui.domain.CustomEntityAttributeDefinition; -import edu.internet2.tier.shibboleth.admin.ui.service.CustomEntityAttributesDefinitionService; - -@Controller +@RestController @RequestMapping(value = "/api/custom/entity") +@Tags(value = {@Tag(name = "attributes")}) public class CustomEntityAttributesDefinitionsController { @Autowired private CustomEntityAttributesDefinitionService caService; @@ -102,4 +104,4 @@ public ResponseEntity delete(@PathVariable String resourceId) { caService.deleteDefinition(cad); return ResponseEntity.noContent().build(); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesController.java index 6adc4c95b..10b8a2eec 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesController.java @@ -1,15 +1,14 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.text.SimpleDateFormat; -import java.time.Instant; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.Date; - -import javax.servlet.http.HttpServletRequest; - +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; +import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository; +import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; +import lombok.extern.slf4j.Slf4j; +import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.apache.http.client.utils.DateUtils; import org.opensaml.core.xml.io.MarshallingException; import org.opensaml.saml.saml2.metadata.EntityDescriptor; @@ -17,28 +16,29 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; -import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; -import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository; -import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; -import lombok.extern.slf4j.Slf4j; -import net.shibboleth.utilities.java.support.resolver.ResolverException; +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.Date; -@Controller +/** + * EntitiesController is here to meet the requirements for this project being an MDQ. Despite similar logic to the + * EntitiesDescriptorController, the required endpoints that make this project an MDQ server are served by this controller. + */ +@RestController @RequestMapping(value = { "/entities", // per protocol - https://spaces.at.internet2.edu/display/MDQ/Metadata+Query+Protocol "/api/entities" }, // existing - included to break no existing code method = RequestMethod.GET) @Slf4j -/** -* EntitiesController is here to meet the requirements for this project being an MDQ. Despite similar logic to the -* EntitiesDescriptorController, the required endpoints that make this project an MDQ server are served by this controller. -*/ +@Tags(value = {@Tag(name = "entity")}) public class EntitiesController { @Autowired private EntityDescriptorService entityDescriptorService; @@ -50,6 +50,8 @@ public class EntitiesController { private EntityDescriptorRepository entityDescriptorRepository; @RequestMapping(value = "/{entityId:.*}") + @Operation(description = "Endpoint based on the MDQ spec to return a single entity's information. see: https://spaces.at.internet2.edu/display/MDQ/Metadata+Query+Protocol", + summary = "Return a single entity from the entity's id", method = "GET") @Transactional(readOnly = true) public ResponseEntity getOne(final @PathVariable String entityId, HttpServletRequest request) throws UnsupportedEncodingException, ResolverException { EntityDescriptor entityDescriptor = this.getEntityDescriptor(entityId); @@ -69,6 +71,8 @@ private String formatModifiedDate(EntityDescriptorRepresentation entityDescripto } @RequestMapping(value = "/{entityId:.*}", produces = "application/xml") + @Operation(description = "Endpoint based on the MDQ spec to return a single entity's information. see: https://spaces.at.internet2.edu/display/MDQ/Metadata+Query+Protocol", + summary = "Return a single entity from the entity's id", method = "GET") @Transactional(readOnly = true) public ResponseEntity getOneXml(final @PathVariable String entityId) throws MarshallingException, ResolverException, UnsupportedEncodingException { EntityDescriptor entityDescriptor = this.getEntityDescriptor(entityId); @@ -91,4 +95,4 @@ private EntityDescriptor getEntityDescriptor(final String entityId) throws Resol } return entityDescriptor; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index 3122eb90e..c2d9b81a0 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -9,6 +9,8 @@ import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; import org.opensaml.core.xml.io.MarshallingException; import org.springframework.beans.factory.annotation.Autowired; @@ -35,6 +37,7 @@ @RestController @RequestMapping("/api") @Slf4j +@Tags(value = {@Tag(name = "entity")}) public class EntityDescriptorController { static URI getResourceUriFor(String resourceId) { return ServletUriComponentsBuilder diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java index 034556c92..13db0fd22 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java @@ -1,6 +1,8 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; import edu.internet2.tier.shibboleth.admin.ui.service.EntityIdsSearchService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -10,6 +12,7 @@ @RestController @RequestMapping("/api/EntityIds/search") +@Tags(value = {@Tag(name = "entity")}) public class EntityIdsSearchController { EntityIdsSearchService entityIdsSearchService; @@ -26,4 +29,4 @@ ResponseEntity search(@RequestParam(required = false) String resourceId, final int resultLimit = (limit != null ? limit : 10); return ResponseEntity.ok(this.entityIdsSearchService.findBySearchTermAndOptionalLimit(resourceId, term, resultLimit)); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/InternationalizationMessagesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/InternationalizationMessagesController.java index c5ec89f6c..288533290 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/InternationalizationMessagesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/InternationalizationMessagesController.java @@ -1,11 +1,13 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; import edu.internet2.tier.shibboleth.admin.ui.i18n.MappedResourceBundleMessageSource; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.util.Collections; import java.util.HashSet; @@ -18,8 +20,9 @@ /** * @author Bill Smith (wsmith@unicon.net) */ -@Controller +@RestController @RequestMapping(value = "/api/messages") +@Tags(value = {@Tag(name = "messages")}) public class InternationalizationMessagesController { @Autowired MappedResourceBundleMessageSource messageSource; @@ -57,4 +60,4 @@ private Set getResourceBundles() { return Collections.unmodifiableSet(resourceBundles); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java index a9191dffc..a70fc2f9b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersController.java @@ -9,6 +9,9 @@ import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; import static java.util.stream.Collectors.toList; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import static org.springframework.http.HttpStatus.BAD_REQUEST; @@ -38,6 +41,7 @@ @RestController @RequestMapping("/api/MetadataResolvers/{metadataResolverId}") +@Tags(value = {@Tag(name = "metadata filters")}) public class MetadataFiltersController { private static final Supplier HTTP_400_BAD_REQUEST_EXCEPTION = () -> new HttpClientErrorException(BAD_REQUEST); private static final Supplier HTTP_404_CLIENT_ERROR_EXCEPTION = () -> new HttpClientErrorException(NOT_FOUND); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersPositionOrderController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersPositionOrderController.java index 4c7d70ec0..fc44c188c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersPositionOrderController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataFiltersPositionOrderController.java @@ -4,6 +4,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; @@ -26,6 +28,7 @@ */ @RestController @RequestMapping("/api/MetadataResolvers/{metadataResolverId}/FiltersPositionOrder") +@Tags(value = {@Tag(name = "metadata filters")}) public class MetadataFiltersPositionOrderController { @Autowired @@ -80,4 +83,4 @@ public ResponseEntity getFiltersPositionOrder(@PathVariable String metadataRe return ResponseEntity.ok(resourceIds); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index d8e09ff56..0f7b92338 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -13,6 +13,8 @@ import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverVersionService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; import edu.internet2.tier.shibboleth.admin.util.OpenSamlChainingMetadataResolverUtil; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.ResolverException; @@ -48,6 +50,7 @@ @RestController @RequestMapping("/api") @Slf4j +@Tags(value = {@Tag(name = "metadata resolvers")}) public class MetadataResolversController { @Autowired diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java index ab78e4a52..e498f5113 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java @@ -3,6 +3,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -16,6 +18,7 @@ */ @RestController @RequestMapping("/api/MetadataResolversPositionOrder") +@Tags(value = {@Tag(name = "metadata resolvers")}) public class MetadataResolversPositionOrderController { @Autowired @@ -31,4 +34,4 @@ public ResponseEntity createOrUpdate(@RequestBody MetadataResolversPositionOr public ResponseEntity getPositionOrderContainer() { return ResponseEntity.ok(positionOrderContainerService.retrieveExistingOrEmpty()); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/RootUiViewController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/RootUiViewController.java index 5aef3d9e2..0af16ada6 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/RootUiViewController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/RootUiViewController.java @@ -1,12 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.controller; -import com.google.common.io.ByteStreams; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; -import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -15,7 +10,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.net.URISyntaxException; -import java.nio.charset.Charset; import java.util.stream.Collectors; @Controller @@ -41,4 +35,4 @@ public void indexHtml(HttpServletRequest request, HttpServletResponse response) writer.write(content.getBytes()); } } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAuditable.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAuditable.java index 6600307af..c6013ff64 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAuditable.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAuditable.java @@ -15,6 +15,7 @@ import javax.persistence.Transient; import javax.validation.constraints.NotNull; +import io.swagger.v3.oas.annotations.Hidden; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import org.hibernate.envers.Audited; @@ -38,38 +39,46 @@ public abstract class AbstractAuditable implements Auditable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) + @Hidden protected Long id; @CreationTimestamp @CreatedDate @Column(nullable = false, updatable = false, columnDefinition = "DATETIME(6)") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS") + @Hidden private LocalDateTime createdDate; @UpdateTimestamp @LastModifiedDate @Column(nullable = false, columnDefinition = "DATETIME(6)") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS") + @Hidden private LocalDateTime modifiedDate; @Column(name = "created_by") @CreatedBy + @Hidden private String createdBy; @Column(name = "modified_by") @LastModifiedBy + @Hidden private String modifiedBy; @Transient @JsonProperty + @Hidden private boolean current; @Override + @Hidden public Long getAudId() { return id; } @Override + @Hidden public void setAudId(@NotNull Long id) { this.id = id; } @@ -134,4 +143,4 @@ private static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime) { .toZonedDateTime() .truncatedTo(ChronoUnit.MILLIS); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java index bcb1b047c..c287a14a7 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java @@ -1,12 +1,17 @@ package edu.internet2.tier.shibboleth.admin.ui.security.controller; +import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; +import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; +import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; +import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; +import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; -import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -15,17 +20,11 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import edu.internet2.tier.shibboleth.admin.ui.controller.ErrorResponse; -import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException; -import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupDeleteException; -import edu.internet2.tier.shibboleth.admin.ui.security.exception.GroupExistsConflictException; -import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; -import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; +import org.springframework.web.bind.annotation.RestController; -@Controller +@RestController @RequestMapping(value = "/api/admin/groups") +@Tags(value = {@Tag(name = "admin")}) public class GroupController { @Autowired private IGroupService groupService; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java index d576e0630..539dc3195 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/RolesController.java @@ -2,6 +2,8 @@ import java.util.Optional; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -24,6 +26,7 @@ @RestController @RequestMapping("/api/admin/roles") +@Tags(value = {@Tag(name = "admin")}) public class RolesController { @Autowired private IRolesService rolesService; @@ -71,4 +74,4 @@ public ResponseEntity update(@RequestBody Role incomingRoleDetail, @PathVaria Role result = rolesService.updateRole(updateRole); return ResponseEntity.ok(result); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java index 93fec88aa..cf1119f9a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/UsersController.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Optional; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.tags.Tags; import org.apache.commons.lang.StringUtils; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -37,6 +39,7 @@ @RestController @RequestMapping("/api/admin/users") @Slf4j +@Tags(value = {@Tag(name = "admin")}) public class UsersController { private UserRepository userRepository; private UserService userService; @@ -149,4 +152,4 @@ ResponseEntity updateOne(@PathVariable(value = "username") String username, @ User savedUser = userService.save(persistedUser); return ResponseEntity.ok(savedUser); } - } + } \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 0556e5b45..99b2ed200 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -106,4 +106,10 @@ shibui.roles.authenticated=ADMIN,ENABLE,USER #This property must be set to true in order to enable posting stats to beacon endpoint. Furthermore, appropriate #environment variables must be set for beacon publisher to be used (the ones that are set when running shib-ui in #docker container -shibui.beacon-enabled=true \ No newline at end of file +shibui.beacon-enabled=true + +springdoc.use-management-port=true +springdoc.pathsToMatch=/entities, /api/** +# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path. +management.endpoints.web.exposure.include=openapi, swagger-ui +management.server.port=9090 \ No newline at end of file