This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
Commit cec92abd authored by Michael Breu's avatar Michael Breu :speech_balloon:
Browse files

Resolve "Anpassen Dokumentation Connector API"

parent e3b97c3b
Branches
2 merge requests!1772023 März Release,!172Resolve "Anpassen Dokumentation Connector API"
...@@ -164,7 +164,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { ...@@ -164,7 +164,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
.and() .and()
.permissionsPolicy(permissions -> permissions .permissionsPolicy(permissions -> permissions
.policy("geolocation=(none)")) .policy("geolocation=()")) // Keine Ahnung warum das hier und nicht in der content security policy steht
.and() .and()
.frameOptions() .frameOptions()
.deny() .deny()
...@@ -192,12 +192,14 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { ...@@ -192,12 +192,14 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.antMatchers(HttpMethod.GET, "/api/pages").permitAll() .antMatchers(HttpMethod.GET, "/api/pages").permitAll()
.antMatchers(HttpMethod.DELETE, "/api/pages").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers(HttpMethod.DELETE, "/api/pages").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers(HttpMethod.GET, "/api/pages/attachment").permitAll() .antMatchers(HttpMethod.GET, "/api/pages/attachment").permitAll()
.antMatchers("/api/currentuser-watch-lists/**").authenticated() .antMatchers("/api/currentuser-watch-lists/**").authenticated()
.antMatchers("/api/**").authenticated() .antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll() .antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll() .antMatchers("/management/info").permitAll()
.antMatchers("/management/prometheus/**").permitAll() .antMatchers("/management/prometheus/**").permitAll()
.antMatchers("/management/prometheusHourly/**").permitAll() .antMatchers("/management/prometheusHourly/**").permitAll()
.antMatchers("/management/jhiopenapigroups").permitAll()
.antMatchers("/v3/api-docs/connector").permitAll() // api-docs are permitted anyway
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and() .and()
.httpBasic() .httpBasic()
......
package at.ac.uibk.gitsearch.config;
/*
* Copyright 2016-2022 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* 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.
*/
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springframework.core.Ordered;
/**
* A OpenApi customizer to setup {@link io.swagger.v3.oas.models.OpenAPI} with
* JHipster settings.
*/
public class SwaggerConfig implements OpenApiCustomiser, Ordered {
/**
* The default order for the customizer.
*/
public static final int DEFAULT_ORDER = 0;
private int order = DEFAULT_ORDER;
/** {@inheritDoc} */
@Override
public void customise(OpenAPI openAPI) {
Contact contact = new Contact();
//
openAPI.info(
new Info()
.contact(contact)
.title("Sharing Plattform Connector API")
.description("This is a description of the Sharing Plattform Connector API")
.version("1.0")
.termsOfService(null)
.license(new License().name("License: Open Source, details still to be considered"))
);
// for (JHipsterProperties.ApiDocs.Server server : properties.getServers()) {
// openAPI.addServersItem(new Server().url(server.getUrl()).description(server.getDescription()));
// }
}
/**
* <p>
* Setter for the field <code>order</code>.
* </p>
*
* @param order a int.
*/
public void setOrder(int order) {
this.order = order;
}
/** {@inheritDoc} */
@Override
public int getOrder() {
return order;
}
}
...@@ -5,10 +5,13 @@ import static java.net.URLDecoder.decode; ...@@ -5,10 +5,13 @@ import static java.net.URLDecoder.decode;
import java.io.File; import java.io.File;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Paths; import java.nio.file.Paths;
import javax.servlet.*; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.web.server.*; import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -108,4 +111,15 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor ...@@ -108,4 +111,15 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor
log.debug("Initialize H2 console"); log.debug("Initialize H2 console");
H2ConfigurationHelper.initH2Console(servletContext); H2ConfigurationHelper.initH2Console(servletContext);
} }
/**
* added documentation of connector api
*
* @return
*/
@Bean
public GroupedOpenApi storeOpenApi() {
String[] paths = { "/api/pluginIF/**" };
return GroupedOpenApi.builder().group("connector").pathsToMatch(paths).addOpenApiCustomiser(new SwaggerConfig()).build();
}
} }
...@@ -6,6 +6,9 @@ import at.ac.uibk.gitsearch.service.SearchService; ...@@ -6,6 +6,9 @@ import at.ac.uibk.gitsearch.service.SearchService;
import at.ac.uibk.gitsearch.service.ShoppingBasketService; import at.ac.uibk.gitsearch.service.ShoppingBasketService;
import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO;
import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.codeability.sharing.plugins.api.ShoppingBasket; import org.codeability.sharing.plugins.api.ShoppingBasket;
...@@ -38,6 +41,9 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; ...@@ -38,6 +41,9 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
@Transactional @Transactional
public class PluginInterfaceResource { public class PluginInterfaceResource {
public static final String API_DOCU_URL =
"https://sharing-codeability.uibk.ac.at/sharing/codeability-sharing-platform/-/wikis/technical/Connector-Interface";
private final Logger log = LoggerFactory.getLogger(PluginInterfaceResource.class); private final Logger log = LoggerFactory.getLogger(PluginInterfaceResource.class);
@Autowired @Autowired
...@@ -60,6 +66,16 @@ public class PluginInterfaceResource { ...@@ -60,6 +66,16 @@ public class PluginInterfaceResource {
* @param basketInfo * @param basketInfo
* @return * @return
*/ */
@Operation(
summary = "returns an redirect URL for handlung basketInfo requests",
description = "Assigns a shopping basket on server, and provides a redirect link together with the shopping basket token.\n" +
" This is called by the local frontend. It has no side effects, beside storing the shopping basket for a limited time frame and return it to the requesting " +
" service.",
deprecated = false,
externalDocs = @ExternalDocumentation(description = "reference documentation", url = API_DOCU_URL),
tags = "shopping basket",
parameters = @Parameter(name = "basketInfo", description = "the shopping basket info transferred by the submitted callback API.")
)
@PostMapping("/pluginIF/getPluginRedirectInfos") @PostMapping("/pluginIF/getPluginRedirectInfos")
public ShoppingBasketRedirectInfoDTO getRedirectInfos(@RequestBody ShoppingBasketInfoDTO basketInfo) { public ShoppingBasketRedirectInfoDTO getRedirectInfos(@RequestBody ShoppingBasketInfoDTO basketInfo) {
final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
...@@ -67,12 +83,25 @@ public class PluginInterfaceResource { ...@@ -67,12 +83,25 @@ public class PluginInterfaceResource {
} }
/** /**
* {@code SEARCH /search/page-details} : search for the searchResults corresponding * {@code POST /search/page-details} : search for the searchResults
* corresponding
* to the query. * to the query.
* *
* @param query the query of the searchResult search. * @param query the query of the searchResult search.
* @return the result of the search. * @return the result of the search.
*/ */
@Operation(
summary = "returns the (pagged) list of search hits",
description = "Allows for searching the sharing plattform with the respective search parameters. See SearchRequestDTO schema for details",
deprecated = false,
externalDocs = @ExternalDocumentation(description = "reference documentation", url = API_DOCU_URL),
tags = "search",
parameters = @Parameter(
name = "searchRequest",
description = "the search query, including information of the requested page and page size. See the SearchRequestDTO for Details"
)
)
@PostMapping("/pluginIF/v0.1/page-details") @PostMapping("/pluginIF/v0.1/page-details")
public SearchResultsDTO searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchRequestDTO searchRequest) public SearchResultsDTO searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchRequestDTO searchRequest)
throws IOException { throws IOException {
...@@ -94,18 +123,48 @@ public class PluginInterfaceResource { ...@@ -94,18 +123,48 @@ public class PluginInterfaceResource {
} }
/** /**
* {@code SEARCH /search/page-details} : search for the searchResults corresponding * {@code {GET basket/{basketToken} : returns the content of the basket (i.e.
* to the query. * the files in the git project) as a zipped octet stream.
* *
* @param query the query of the searchResult search. * @param basketToken the basket token
* @return the result of the search. *
* @return the zipped octet stream of the git project contents.
*/ */
@Operation(
summary = "returns the content of the basket (i.e. the files in the git project) as a zipped octet stream.",
description = "Uses the basketToken to identify the shopping basket," +
" loads the git project content from gitlab, and returns it as a zipped octet stream.",
deprecated = false,
externalDocs = @ExternalDocumentation(description = "see reference documentation", url = API_DOCU_URL),
tags = "shopping basket",
parameters = @Parameter(name = "basketToken", description = "The token to identify the shopping basket")
)
@GetMapping("/pluginIF/v0.1/basket/{basketToken}") @GetMapping("/pluginIF/v0.1/basket/{basketToken}")
public ShoppingBasket getBasket(@PathVariable("basketToken") String basketToken) { public ShoppingBasket getBasket(@PathVariable("basketToken") String basketToken) {
log.debug("REST request for basket {}", basketToken); log.debug("REST request for basket {}", basketToken);
return basketService.getBasket(basketToken); return basketService.getBasket(basketToken);
} }
/**
* {@code {GET /pluginIF/v0.1/basket/{basketToken}/repository/{exerciseId}} :
* returns the content of an exercise in the basket (i.e.
* the files in the git project) as a zipped octet stream.
*
* @param basketToken the basket token
*
* @return the zipped octet stream of the git project contents.
*/
@Operation(
summary = "returns the content of an exercise in the basket (i.e. the respective files in the git project) as a zipped octet stream.",
description = "Uses the basketToken and the exerciseId to identify the exercise in the shopping basket, loads the files from the git project from gitlab, and returns it as a zipped octet stream.",
deprecated = false,
externalDocs = @ExternalDocumentation(description = "see reference documentation", url = API_DOCU_URL),
tags = "shopping basket",
parameters = {
@Parameter(name = "basketToken", description = "The token to identify the shopping basket"),
@Parameter(name = "exerciseId", description = "The id of the exercise in the shopping basket"),
}
)
@GetMapping("/pluginIF/v0.1/basket/{basketToken}/repository/{exerciseId}") @GetMapping("/pluginIF/v0.1/basket/{basketToken}/repository/{exerciseId}")
@SuppressWarnings("PMD.CloseResource") @SuppressWarnings("PMD.CloseResource")
public ResponseEntity<?> getRepositoryZip(@PathVariable String basketToken, @PathVariable int exerciseId) throws IOException { public ResponseEntity<?> getRepositoryZip(@PathVariable String basketToken, @PathVariable int exerciseId) throws IOException {
......
...@@ -4,6 +4,9 @@ import at.ac.uibk.gitsearch.service.UserWatchListService; ...@@ -4,6 +4,9 @@ import at.ac.uibk.gitsearch.service.UserWatchListService;
import at.ac.uibk.gitsearch.service.WatchListEntryService; import at.ac.uibk.gitsearch.service.WatchListEntryService;
import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO;
import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.List; import java.util.List;
...@@ -57,6 +60,8 @@ public class WatchListEntryResource { ...@@ -57,6 +60,8 @@ public class WatchListEntryResource {
* @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new watchListEntryDTO, or with status {@code 400 (Bad Request)} if the watchListEntry has already an ID. * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new watchListEntryDTO, or with status {@code 400 (Bad Request)} if the watchListEntry has already an ID.
* @throws URISyntaxException if the Location URI syntax is incorrect. * @throws URISyntaxException if the Location URI syntax is incorrect.
*/ */
@Operation(summary = "Creates a watch list entry")
@ApiResponses(@ApiResponse(responseCode = "201", description = "created the watch list entry"))
@PostMapping("/watch-list-entries") @PostMapping("/watch-list-entries")
public ResponseEntity<WatchListEntryDTO> createWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) public ResponseEntity<WatchListEntryDTO> createWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO)
throws URISyntaxException { throws URISyntaxException {
......
...@@ -195,12 +195,12 @@ jhipster: ...@@ -195,12 +195,12 @@ jhipster:
management-include-pattern: ${server.servlet.context-path:}/management/** management-include-pattern: ${server.servlet.context-path:}/management/**
title: Gitsearch API title: Gitsearch API
description: Gitsearch API documentation description: Gitsearch API documentation
version: 0.0.1 version: 1.0.0
terms-of-service-url: terms-of-service-url:
contact-name: contact-name:
contact-url: contact-url:
contact-email: contact-email:
license: unlicensed license: License under Discussion
license-url: license-url:
security: security:
content-security-policy: "default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:" content-security-policy: "default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:"
......
...@@ -46,6 +46,11 @@ ...@@ -46,6 +46,11 @@
>{{ language | findLanguageFromKey }}</a >{{ language | findLanguageFromKey }}</a
> >
</li> </li>
<!-- Just for backup, we add a hidden local login link in the menu -->
<li>
<a id="localLogin" class="dropdown-item" href="/login">Local Login</a>
</li>
-->
</ul> </ul>
</li> </li>
<!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here --> <!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here -->
......
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>gitsearch - Swagger UI</title> <title>gitsearch - Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" /> <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" /> <link rel="icon" type="image/png" href="../favicon.ico" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
</head> </head>
<body> <body>
...@@ -60,6 +59,8 @@ ...@@ -60,6 +59,8 @@
urls.sort(function (a, b) { urls.sort(function (a, b) {
var x = a.name.toLowerCase(), var x = a.name.toLowerCase(),
y = b.name.toLowerCase(); y = b.name.toLowerCase();
if (x.includes('connector')) return -1;
if (y.includes('connector')) return 1;
if (x.includes('(default)')) return -1; if (x.includes('(default)')) return -1;
if (y.includes('(default)')) return 1; if (y.includes('(default)')) return 1;
if (x.includes('(management)')) return -1; if (x.includes('(management)')) return -1;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment