This commit is contained in:
Justin Yoo 2021-02-26 00:34:03 +09:00 коммит произвёл GitHub
Родитель a06c271e70
Коммит 1b5092f245
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
26 изменённых файлов: 186 добавлений и 145 удалений

4
.gitignore поставляемый
Просмотреть файл

@ -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 поставляемый

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 738 B

После

Ширина:  |  Высота:  |  Размер: 665 B

Двоичные данные
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>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -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);
}
}
}