1 /*
2  *
3  *  * Copyright 2019-2020 the original author or authors.
4  *  *
5  *  * Licensed under the Apache License, Version 2.0 (the "License");
6  *  * you may not use this file except in compliance with the License.
7  *  * You may obtain a copy of the License at
8  *  *
9  *  *      https://www.apache.org/licenses/LICENSE-2.0
10  *  *
11  *  * Unless required by applicable law or agreed to in writing, software
12  *  * distributed under the License is distributed on an "AS IS" BASIS,
13  *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  * See the License for the specific language governing permissions and
15  *  * limitations under the License.
16  *
17  */

18
19 package org.springdoc.webmvc.ui;
20
21 import java.util.Map;
22
23 import javax.servlet.http.HttpServletRequest;
24
25 import io.swagger.v3.oas.annotations.Operation;
26 import org.apache.commons.lang3.ArrayUtils;
27 import org.apache.commons.lang3.StringUtils;
28 import org.springdoc.core.SpringDocConfigProperties;
29 import org.springdoc.core.SpringDocConfiguration;
30 import org.springdoc.core.SwaggerUiConfigProperties;
31 import org.springdoc.ui.AbstractSwaggerWelcome;
32
33 import org.springframework.beans.factory.annotation.Value;
34 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
35 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
36 import org.springframework.http.MediaType;
37 import org.springframework.stereotype.Controller;
38 import org.springframework.web.bind.annotation.GetMapping;
39 import org.springframework.web.bind.annotation.ResponseBody;
40 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
41 import org.springframework.web.util.UriComponentsBuilder;
42
43 import static org.springdoc.core.Constants.MVC_SERVLET_PATH;
44 import static org.springdoc.core.Constants.SPRINGDOC_SWAGGER_UI_ENABLED;
45 import static org.springdoc.core.Constants.SWAGGER_CONFIG_URL;
46 import static org.springdoc.core.Constants.SWAGGER_UI_OAUTH_REDIRECT_URL;
47 import static org.springdoc.core.Constants.SWAGGER_UI_PATH;
48 import static org.springdoc.core.Constants.SWAGGER_UI_URL;
49 import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
50 import static org.springframework.web.servlet.view.UrlBasedViewResolver.REDIRECT_URL_PREFIX;
51
52 @Controller
53 @ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true)
54 @ConditionalOnBean(SpringDocConfiguration.class)
55 public class SwaggerWelcome extends AbstractSwaggerWelcome {
56
57     @Value(MVC_SERVLET_PATH)
58     private String mvcServletPath;
59
60     public SwaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties) {
61         super(swaggerUiConfig, springDocConfigProperties);
62     }
63
64     @Operation(hidden = true)
65     @GetMapping(SWAGGER_UI_PATH)
66     public String redirectToUi(HttpServletRequest request) {
67         buildConfigUrl(request.getContextPath(), ServletUriComponentsBuilder.fromCurrentContextPath());
68         String sbUrl = REDIRECT_URL_PREFIX + this.uiRootPath + SWAGGER_UI_URL;
69         UriComponentsBuilder uriBuilder = getUriComponentsBuilder(sbUrl);
70         return uriBuilder.build().encode().toString();
71     }
72
73     @Operation(hidden = true)
74     @GetMapping(value = SWAGGER_CONFIG_URL, produces = MediaType.APPLICATION_JSON_VALUE)
75     @ResponseBody
76     public Map<String, Object> openapiYaml(HttpServletRequest request) {
77         buildConfigUrl(request.getContextPath(), ServletUriComponentsBuilder.fromCurrentContextPath());
78         return swaggerUiConfig.getConfigParameters();
79     }
80
81     @Override
82     protected void calculateUiRootPath(StringBuilder... sbUrls) {
83         StringBuilder sbUrl = new StringBuilder();
84         if (StringUtils.isNotBlank(mvcServletPath))
85             sbUrl.append(mvcServletPath);
86         if (ArrayUtils.isNotEmpty(sbUrls))
87             sbUrl = sbUrls[0];
88         String swaggerPath = swaggerUiConfig.getPath();
89         if (swaggerPath.contains(DEFAULT_PATH_SEPARATOR))
90             sbUrl.append(swaggerPath, 0, swaggerPath.lastIndexOf(DEFAULT_PATH_SEPARATOR));
91         this.uiRootPath = sbUrl.toString();
92     }
93
94     @Override
95     protected String buildUrl(String contextPath, final String docsUrl) {
96         if (StringUtils.isNotBlank(mvcServletPath))
97             contextPath += mvcServletPath;
98         return super.buildUrl(contextPath, docsUrl);
99     }
100
101     @Override
102     protected void calculateOauth2RedirectUrl(UriComponentsBuilder uriComponentsBuilder) {
103         if (StringUtils.isEmpty(oauth2RedirectUrl))
104             swaggerUiConfig.setOauth2RedirectUrl(uriComponentsBuilder.path(this.uiRootPath).path(SWAGGER_UI_OAUTH_REDIRECT_URL).build().toString());
105         else if (!swaggerUiConfig.isValidUrl(swaggerUiConfig.getOauth2RedirectUrl()))
106             swaggerUiConfig.setOauth2RedirectUrl(uriComponentsBuilder.path(this.uiRootPath).path(swaggerUiConfig.getOauth2RedirectUrl()).build().toString());
107     }
108 }