Update Swagger UI (#57)
This commit is contained in:
Родитель
a06c271e70
Коммит
1b5092f245
|
@ -289,4 +289,6 @@ __pycache__/
|
|||
|
||||
*.bak
|
||||
*.org
|
||||
outputs/
|
||||
outputs/
|
||||
|
||||
.DS_Store
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Acknowledgement ##
|
||||
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [3.20.5](https://github.com/swagger-api/swagger-ui/releases/tag/v3.20.5) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [v3.44.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.44.0) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
|
||||
|
||||
## Getting Started ##
|
||||
|
|
|
@ -9,7 +9,7 @@ This enables Azure Functions to render Open API document and Swagger UI. The mor
|
|||
|
||||
## Acknowledgement ##
|
||||
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [3.20.5](https://github.com/swagger-api/swagger-ui/releases/tag/v3.20.5) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [v3.44.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.44.0) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
|
||||
|
||||
## Issues? ##
|
||||
|
|
|
@ -9,7 +9,7 @@ This enables Azure Functions to render Open API document and Swagger UI. The mor
|
|||
|
||||
## Acknowledgement ##
|
||||
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [3.20.5](https://github.com/swagger-api/swagger-ui/releases/tag/v3.20.5) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
* [Swagger UI](https://github.com/swagger-api/swagger-ui) version used for this library is [v3.44.0](https://github.com/swagger-api/swagger-ui/releases/tag/v3.44.0) under the [Apache 2.0 license](https://opensource.org/licenses/Apache-2.0).
|
||||
|
||||
|
||||
## Issues? ##
|
||||
|
|
|
@ -23,5 +23,20 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions
|
|||
|
||||
return await instance.RenderAsync(endpoint, authKey).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the OAuth2 Redirect page in HTML.
|
||||
/// </summary>
|
||||
/// <param name="ui"><see cref="ISwaggerUI"/> instance.</param>
|
||||
/// <param name="endpoint">The endpoint of the OAuth2 Redirect page.</param>
|
||||
/// <param name="authKey">API key of the HTTP endpoint to render Open API document.</param>
|
||||
/// <returns>The OAuth2 Redirect page in HTML.</returns>
|
||||
public static async Task<string> RenderOAuth2RedirectAsync(this Task<ISwaggerUI> ui, string endpoint, string authKey = null)
|
||||
{
|
||||
var instance = await ui.ThrowIfNullOrDefault().ConfigureAwait(false);
|
||||
endpoint.ThrowIfNullOrWhiteSpace();
|
||||
|
||||
return await instance.RenderOAuth2RedirectAsync(endpoint, authKey).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
|
|||
/// Adds metadata to build Open API document.
|
||||
/// </summary>
|
||||
/// <param name="info"><see cref="OpenApiInfo"/> instance.</param>
|
||||
/// <returns><see cref="IDocument"/> instance.</returns>
|
||||
/// <returns><see cref="ISwaggerUI"/> instance.</returns>
|
||||
ISwaggerUI AddMetadata(OpenApiInfo info);
|
||||
|
||||
/// <summary>
|
||||
|
@ -24,15 +24,21 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
|
|||
/// <param name="req"><see cref="HttpRequest"/> instance.</param>
|
||||
/// <param name="routePrefix">Route prefix value.</param>
|
||||
/// <param name="options"><see cref="IOpenApiConfigurationOptions"/> instance.</param>
|
||||
/// <returns><see cref="IDocument"/> instance.</returns>
|
||||
/// <returns><see cref="ISwaggerUI"/> instance.</returns>
|
||||
ISwaggerUI AddServer(HttpRequest req, string routePrefix, IOpenApiConfigurationOptions options = null);
|
||||
|
||||
/// <summary>
|
||||
/// Builds Open API document.
|
||||
/// Builds Swagger UI document.
|
||||
/// </summary>
|
||||
/// <returns><see cref="IDocument"/> instance.</returns>
|
||||
/// <returns><see cref="ISwaggerUI"/> instance.</returns>
|
||||
Task<ISwaggerUI> BuildAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Builds OAuth2 Redirect document.
|
||||
/// </summary>
|
||||
/// <returns><see cref="ISwaggerUI"/> instance.</returns>
|
||||
Task<ISwaggerUI> BuildOAuth2RedirectAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Renders Open API UI in HTML.
|
||||
/// </summary>
|
||||
|
@ -40,5 +46,13 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
|
|||
/// <param name="authKey">API key of the HTTP endpoint to render Open API document.</param>
|
||||
/// <returns>Open API UI in HTML.</returns>
|
||||
Task<string> RenderAsync(string endpoint, string authKey = null);
|
||||
|
||||
/// <summary>
|
||||
/// Renders OAuth Redirect in HTML.
|
||||
/// </summary>
|
||||
/// <param name="endpoint">The endpoint of the OAuth2 Redirect page.</param>
|
||||
/// <param name="authKey">API key of the HTTP endpoint to render Open API document.</param>
|
||||
/// <returns>OAuth Redirect in HTML.</returns>
|
||||
Task<string> RenderOAuth2RedirectAsync(string endpoint, string authKey = null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="dist/index.html" />
|
||||
<EmbeddedResource Include="dist/oauth2-redirect.html" />
|
||||
<EmbeddedResource Include="dist/swagger-ui.css" />
|
||||
<EmbeddedResource Include="dist/swagger-ui-bundle.js" />
|
||||
<EmbeddedResource Include="dist/swagger-ui-standalone-preset.js" />
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
|
|||
private const string SwaggerUrlPlaceholder = "[[SWAGGER_URL]]";
|
||||
|
||||
private readonly string indexHtml = $"{typeof(SwaggerUI).Namespace}.dist.index.html";
|
||||
private readonly string oauth2RedirectHtml = $"{typeof(SwaggerUI).Namespace}.dist.oauth2-redirect.html";
|
||||
private readonly string swaggerUiCss = $"{typeof(SwaggerUI).Namespace}.dist.swagger-ui.css";
|
||||
private readonly string swaggerUiBundleJs = $"{typeof(SwaggerUI).Namespace}.dist.swagger-ui-bundle.js";
|
||||
private readonly string swaggerUiStandalonePresetJs = $"{typeof(SwaggerUI).Namespace}.dist.swagger-ui-standalone-preset.js";
|
||||
|
@ -33,6 +34,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
|
|||
private string _swaggerUiBundleJs;
|
||||
private string _swaggerUiStandalonePresetJs;
|
||||
private string _indexHtml;
|
||||
private string _oauth2RedirectHtml;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISwaggerUI AddMetadata(OpenApiInfo info)
|
||||
|
@ -99,6 +101,20 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
|
|||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ISwaggerUI> BuildOAuth2RedirectAsync()
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
using (var stream = assembly.GetManifestResourceStream(oauth2RedirectHtml))
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
this._oauth2RedirectHtml = await reader.ReadToEndAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> RenderAsync(string endpoint, string authKey = null)
|
||||
{
|
||||
|
@ -111,6 +127,16 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
|
|||
return html;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> RenderOAuth2RedirectAsync(string endpoint, string authKey = null)
|
||||
{
|
||||
var html = await Task.Factory
|
||||
.StartNew(() => this.RenderOAuth2Redirect(endpoint, authKey))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
private string Render(string endpoint, string authKey = null)
|
||||
{
|
||||
var swaggerUiTitle = $"{this._info.Title} - Swagger UI";
|
||||
|
@ -128,5 +154,19 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
|
|||
|
||||
return html;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
private string RenderOAuth2Redirect(string endpoint, string authKey = null)
|
||||
{
|
||||
var pageUrl = $"{this._baseUrl.TrimEnd('/')}/{endpoint}";
|
||||
if (!string.IsNullOrWhiteSpace(authKey))
|
||||
{
|
||||
pageUrl += $"?code={authKey}";
|
||||
}
|
||||
|
||||
var html = this._oauth2RedirectHtml;
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Двоичные данные
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/favicon-16x16.png
поставляемый
Двоичные данные
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/favicon-16x16.png
поставляемый
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 738 B После Ширина: | Высота: | Размер: 665 B |
Двоичные данные
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/favicon-32x32.png
поставляемый
Двоичные данные
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/favicon-32x32.png
поставляемый
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 628 B |
|
@ -1,4 +1,4 @@
|
|||
<!-- HTML for static distribution bundle build -->
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
@ -7,6 +7,8 @@
|
|||
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
[[SWAGGER_UI_CSS]]
|
||||
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
|
@ -26,8 +28,6 @@
|
|||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
[[SWAGGER_UI_CSS]]
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
@ -51,11 +51,11 @@
|
|||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
});
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
window.ui = ui;
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
|
@ -17,19 +18,20 @@
|
|||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
}
|
||||
) : {}
|
||||
) : {};
|
||||
|
||||
isValid = qp.state === sentState
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
|
@ -45,7 +47,7 @@
|
|||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
|
@ -64,4 +66,10 @@
|
|||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
run();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
3
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle-core.js
поставляемый
Normal file
3
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle-core.js
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
1
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle-core.js.map
поставляемый
Normal file
1
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle-core.js.map
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
3
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle.js
поставляемый
Normal file
3
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle.js
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
1
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle.js.map
поставляемый
Normal file
1
src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/dist/swagger-ui-es-bundle.js.map
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -134,5 +134,35 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
|
|||
|
||||
return content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the HTTP trigger endpoint to render oauth2-redirect.html.
|
||||
/// </summary>
|
||||
/// <param name="req"><see cref="HttpRequest"/> instance.</param>
|
||||
/// <param name="log"><see cref="ILogger"/> instance.</param>
|
||||
/// <returns>oauth2-redirect.html.</returns>
|
||||
[FunctionName(nameof(OpenApiHttpTrigger.RenderOAuth2Redirect))]
|
||||
[OpenApiIgnore]
|
||||
public static async Task<IActionResult> RenderOAuth2Redirect(
|
||||
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "oauth2-redirect.html")] HttpRequest req,
|
||||
ILogger log)
|
||||
{
|
||||
log.LogInformation($"The oauth2-redirect.html page was requested.");
|
||||
|
||||
var result = await context.SwaggerUI
|
||||
.AddServer(req, context.HttpSettings.RoutePrefix, context.OpenApiConfiguration)
|
||||
.BuildOAuth2RedirectAsync()
|
||||
.RenderOAuth2RedirectAsync("oauth2-redirect.html", context.GetSwaggerAuthKey())
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var content = new ContentResult()
|
||||
{
|
||||
Content = result,
|
||||
ContentType = "text/html",
|
||||
StatusCode = (int)HttpStatusCode.OK
|
||||
};
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Extensions
|
|||
public class SwaggerUIExtensionsTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void Given_Null_Method_Should_Throw_Exception()
|
||||
public void Given_Null_When_RenderAsync_Invoked_Then_It_Should_Throw_Exception()
|
||||
{
|
||||
Func<Task> func = async () => await SwaggerUIExtensions.RenderAsync(null, null).ConfigureAwait(false);
|
||||
func.Should().Throw<ArgumentNullException>();
|
||||
|
@ -29,7 +29,7 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Extensions
|
|||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Given_Value_Method_Should_Return_Value()
|
||||
public async Task Given_Value_When_RenderAsync_Invoked_Then_It_Should_Return_Value()
|
||||
{
|
||||
var endpoint = "swagger/ui";
|
||||
var rendered = "hello world";
|
||||
|
@ -43,5 +43,34 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Extensions
|
|||
|
||||
result.Should().BeEquivalentTo(rendered);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Given_Null_When_RenderOAuth2RedirectAsync_Invoked_Then_It_Should_Throw_Exception()
|
||||
{
|
||||
Func<Task> func = async () => await SwaggerUIExtensions.RenderOAuth2RedirectAsync(null, null).ConfigureAwait(false);
|
||||
func.Should().Throw<ArgumentNullException>();
|
||||
|
||||
var ui = new Mock<ISwaggerUI>();
|
||||
var task = Task.FromResult(ui.Object);
|
||||
|
||||
func = async () => await SwaggerUIExtensions.RenderOAuth2RedirectAsync(task, null).ConfigureAwait(false);
|
||||
func.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Given_Value_When_RenderOAuth2RedirectAsync_Invoked_Then_It_Should_Return_Value()
|
||||
{
|
||||
var endpoint = "oauth2-redirect.html";
|
||||
var rendered = "hello world";
|
||||
|
||||
var ui = new Mock<ISwaggerUI>();
|
||||
ui.Setup(p => p.RenderOAuth2RedirectAsync(It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(rendered);
|
||||
|
||||
var task = Task.FromResult(ui.Object);
|
||||
|
||||
var result = await SwaggerUIExtensions.RenderOAuth2RedirectAsync(task, endpoint).ConfigureAwait(false);
|
||||
|
||||
result.Should().BeEquivalentTo(rendered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче