Move swagger-ui under /api/v1 (#2746)

* Move swagger interface under /api/v1

* Update swagger-ui

* Add /api/swagger and prepare for multiple api version

* Update test links

* Fix footer link
release/v1.15
Antoine GIRARD 2017-10-21 16:05:50 +02:00 committed by Lunny Xiao
parent bc8d72666c
commit 619b9b5547
17 changed files with 166 additions and 192 deletions

View File

@ -304,10 +304,10 @@ generate-stylesheets:
.PHONY: swagger-ui .PHONY: swagger-ui
swagger-ui: swagger-ui:
rm -Rf public/vendor/assets/swagger-ui rm -Rf public/vendor/assets/swagger-ui
git clone --depth=10 -b v3.0.7 --single-branch https://github.com/swagger-api/swagger-ui.git $(TMPDIR)/swagger-ui git clone --depth=10 -b v3.3.2 --single-branch https://github.com/swagger-api/swagger-ui.git $(TMPDIR)/swagger-ui
mv $(TMPDIR)/swagger-ui/dist public/vendor/assets/swagger-ui mv $(TMPDIR)/swagger-ui/dist public/vendor/assets/swagger-ui
rm -Rf $(TMPDIR)/swagger-ui rm -Rf $(TMPDIR)/swagger-ui
$(SED_INPLACE) "s;http://petstore.swagger.io/v2/swagger.json;../../swagger.v1.json;g" public/assets/swagger-ui/index.html $(SED_INPLACE) "s;http://petstore.swagger.io/v2/swagger.json;../../../swagger.v1.json;g" public/vendor/assets/swagger-ui/index.html
.PHONY: update-translations .PHONY: update-translations
update-translations: update-translations:

View File

@ -26,7 +26,8 @@ func TestLinksNoLogin(t *testing.T) {
"/user/sign_up", "/user/sign_up",
"/user/login", "/user/login",
"/user/forgot_password", "/user/forgot_password",
"/swagger", "/api/swagger",
"/api/v1/swagger",
// TODO: follow this page and test every link // TODO: follow this page and test every link
"/vendor/librejs.html", "/vendor/librejs.html",
} }
@ -47,7 +48,8 @@ func testLinksAsUser(userName string, t *testing.T) {
"/explore/organizations?q=test&tab=", "/explore/organizations?q=test&tab=",
"/", "/",
"/user/forgot_password", "/user/forgot_password",
"/swagger", "/api/swagger",
"/api/v1/swagger",
"/issues", "/issues",
"/issues?type=your_repositories&repo=0&sort=&state=open", "/issues?type=your_repositories&repo=0&sort=&state=open",
"/issues?type=assigned&repo=0&sort=&state=open", "/issues?type=assigned&repo=0&sort=&state=open",

View File

@ -71,10 +71,12 @@
<script src="./swagger-ui-standalone-preset.js"> </script> <script src="./swagger-ui-standalone-preset.js"> </script>
<script> <script>
window.onload = function() { window.onload = function() {
// Build a system // Build a system
const ui = SwaggerUIBundle({ const ui = SwaggerUIBundle({
url: "../../swagger.v1.json", url: "../../../swagger.v1.json",
dom_id: '#swagger-ui', dom_id: '#swagger-ui',
deepLinking: true,
presets: [ presets: [
SwaggerUIBundle.presets.apis, SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset SwaggerUIStandalonePreset

View File

@ -8,11 +8,18 @@
function run () { function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2; var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state; var sentState = oauth2.state;
var isValid, qp; var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
qp = (window.location.hash || location.search).substring(1); if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g, '":"') + '"}', arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) { function (key, value) {
return key === "" ? value : decodeURIComponent(value) return key === "" ? value : decodeURIComponent(value)
} }
@ -33,51 +40,18 @@
if (qp.code) { if (qp.code) {
delete oauth2.state; delete oauth2.state;
oauth2.auth.code = qp.code; oauth2.auth.code = qp.code;
createForm(oauth2.auth, qp).submit(); oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else { } else {
oauth2.errCb({ oauth2.errCb({
authId: oauth2.auth.name, authId: oauth2.auth.name,
source: "auth", source: "auth",
level: "error", level: "error",
message: "Authorization failed: no accessCode came from the server" message: "Authorization failed: no accessCode received from the server"
}); });
window.close();
} }
} else { } else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid}); oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close(); window.close();
} }
}
function createForm(auth, qp) {
var form = document.createElement("form");
var schema = auth.schema;
var action = schema.get("tokenUrl");
var name, input;
var fields = {
code: qp.code,
"redirect_uri": location.protocol + "//" + location.host + location.pathname,
"grant_type": "authorization_code",
"client_secret": auth.clientSecret,
"client_id": auth.clientId
}
for ( name in fields ) {
input = document.createElement("input");
input.name = name;
input.value = fields[name];
input.type = "hidden";
form.appendChild(input);
}
form.method = "POST";
form.action = action;
document.body.appendChild(form);
return form;
}
</script> </script>

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;AAu/FA;AA6+FA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0dA;;;;;;AAoIA;AAk7FA;AAmtCA;;;;;AA0uIA;AA+4IA;AAm9FA;AA2rGA;AA8lFA;AA2nFA;AAu9CA;AAyhDA;AAqrCA;AAy4EA;AA8/GA;;;;;;;;;;;;;;AA+mJA;AA4mIA;AAquJA;AAwsHA;AAinGA;AAmiEA;AAy4DA;AAm2DA;AA0nBA;;;;;;AA4iFA;AAk0FA;;;;;AA23CA;AA2qFA;AAw2CA;AAglCA;AA0/CA;AAykFA;AA+1FA;;;;;;;;;AAk4CA;AA2zIA;AAk4DA;AAolDA","sourceRoot":""} {"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAsnMA;;;;;;AAm5DA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0kUA;;;;;;;;;;;;;;AAq4JA;AA4/iBA;;;;;;;;;AA+vIA;;;;;AAk8QA;;;;;AAynBA;AAo0CA;;;;;;AAuqxBA;AAixYA;;;;;;AA6gbA","sourceRoot":""}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA4QA;AAitGA","sourceRoot":""} {"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA6mCA;;;;;;AA41FA","sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA4wCA;AAoyHA;AAuxHA;AAy4FA;AA8rCA;AAugCA;AA+hCA;AA24BA","sourceRoot":""} {"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAs9eA","sourceRoot":""}

View File

@ -275,8 +275,11 @@ func mustAllowPulls(ctx *context.Context) {
func RegisterRoutes(m *macaron.Macaron) { func RegisterRoutes(m *macaron.Macaron) {
bind := binding.Bind bind := binding.Bind
m.Get("/swagger", misc.Swagger) //Render V1 by default
m.Group("/v1", func() { m.Group("/v1", func() {
// Miscellaneous // Miscellaneous
m.Get("/swagger", misc.Swagger)
m.Get("/version", misc.Version) m.Get("/version", misc.Version)
m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
m.Post("/markdown/raw", misc.MarkdownRaw) m.Post("/markdown/raw", misc.MarkdownRaw)

View File

@ -0,0 +1,19 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package misc
import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
)
// tplSwagger swagger page template
const tplSwagger base.TplName = "swagger"
// Swagger render swagger-ui page with v1 json
func Swagger(ctx *context.Context) {
ctx.Data["APIJSONVersion"] = "v1"
ctx.HTML(200, tplSwagger)
}

View File

@ -20,8 +20,6 @@ import (
const ( const (
// tplHome home page template // tplHome home page template
tplHome base.TplName = "home" tplHome base.TplName = "home"
// tplSwagger swagger page template
tplSwagger base.TplName = "swagger"
// tplExploreRepos explore repositories page template // tplExploreRepos explore repositories page template
tplExploreRepos base.TplName = "explore/repos" tplExploreRepos base.TplName = "explore/repos"
// tplExploreUsers explore users page template // tplExploreUsers explore users page template
@ -53,11 +51,6 @@ func Home(ctx *context.Context) {
ctx.HTML(200, tplHome) ctx.HTML(200, tplHome)
} }
// Swagger render swagger-ui page
func Swagger(ctx *context.Context) {
ctx.HTML(200, tplSwagger)
}
// RepoSearchOptions when calling search repositories // RepoSearchOptions when calling search repositories
type RepoSearchOptions struct { type RepoSearchOptions struct {
OwnerID int64 OwnerID int64

View File

@ -160,7 +160,6 @@ func RegisterRoutes(m *macaron.Macaron) {
return "" return ""
}) })
m.Get("/", ignSignIn, routers.Home) m.Get("/", ignSignIn, routers.Home)
m.Get("/swagger", ignSignIn, routers.Swagger)
m.Group("/explore", func() { m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) { m.Get("", func(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/explore/repos") ctx.Redirect(setting.AppSubURL + "/explore/repos")

View File

@ -23,7 +23,7 @@
</div> </div>
</div> </div>
<a href="{{AppSubUrl}}/vendor/librejs.html" data-jslicense="1">Javascript licenses</a> <a href="{{AppSubUrl}}/vendor/librejs.html" data-jslicense="1">Javascript licenses</a>
<a href="{{AppSubUrl}}/swagger">API</a> <a href="{{AppSubUrl}}/api/swagger">API</a>
<a target="_blank" rel="noopener" href="https://gitea.io">{{.i18n.Tr "website"}}</a> <a target="_blank" rel="noopener" href="https://gitea.io">{{.i18n.Tr "website"}}</a>
{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}} {{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
</div> </div>

View File

@ -70,11 +70,13 @@
<script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script> <script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-bundle.js"> </script>
<script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-standalone-preset.js"> </script> <script src="{{AppSubUrl}}/vendor/assets/swagger-ui/swagger-ui-standalone-preset.js"> </script>
<script> <script>
window.onload = function() { window.onload = function() {
// Build a system // Build a system
const ui = SwaggerUIBundle({ const ui = SwaggerUIBundle({
url: "{{AppUrl}}swagger.v1.json", url: "{{AppUrl}}swagger.{{.APIJSONVersion}}.json",
dom_id: '#swagger-ui', dom_id: '#swagger-ui',
deepLinking: true,
presets: [ presets: [
SwaggerUIBundle.presets.apis, SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset SwaggerUIStandalonePreset