Skip to content

Commit 8372253

Browse files
authored
Dynamic OpenAPI document injection (#90)
1 parent 9ba8b98 commit 8372253

File tree

23 files changed

+806
-257
lines changed

23 files changed

+806
-257
lines changed

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V1Proxy/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V1Proxy.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,4 @@
4141
</None>
4242
</ItemGroup>
4343

44-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
45-
<ItemGroup>
46-
<Compile Include="..\..\templates\OpenApiEndpoints\IOpenApiHttpTriggerContext.cs" />
47-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTriggerContext.cs" />
48-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTrigger.cs" />
49-
</ItemGroup>
50-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
51-
5244
</Project>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2IoC.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,4 @@
3838
</None>
3939
</ItemGroup>
4040

41-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
42-
<ItemGroup>
43-
<Compile Include="..\..\templates\OpenApiEndpoints\IOpenApiHttpTriggerContext.cs" />
44-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTriggerContext.cs" />
45-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTrigger.cs" />
46-
</ItemGroup>
47-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
48-
4941
</Project>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V2Static.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,4 @@
3737
</None>
3838
</ItemGroup>
3939

40-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
41-
<ItemGroup>
42-
<Compile Include="..\..\templates\OpenApiEndpoints\IOpenApiHttpTriggerContext.cs" />
43-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTriggerContext.cs" />
44-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTrigger.cs" />
45-
</ItemGroup>
46-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
47-
4840
</Project>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3IoC.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,4 @@
3838
</None>
3939
</ItemGroup>
4040

41-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
42-
<ItemGroup>
43-
<Compile Include="..\..\templates\OpenApiEndpoints\IOpenApiHttpTriggerContext.cs" />
44-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTriggerContext.cs" />
45-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTrigger.cs" />
46-
</ItemGroup>
47-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
48-
4941
</Project>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,4 @@
4747
</ItemGroup> -->
4848
<!-- Uncomment this block if you want to use custom UI -->
4949

50-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
51-
<ItemGroup>
52-
<Compile Include="..\..\templates\OpenApiEndpoints\IOpenApiHttpTriggerContext.cs" />
53-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTriggerContext.cs" />
54-
<Compile Include="..\..\templates\OpenApiEndpoints\OpenApiHttpTrigger.cs" />
55-
</ItemGroup>
56-
<!-- Comment this block if you want to use NuGet package from https://nuget.org -->
57-
5850
</Project>

samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/local.settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66

77
"AZURE_FUNCTION_PROXY_DISABLE_LOCAL_CALL": "true",
88

9+
"OpenApi__HideSwaggerUI": "false",
910
"OpenApi__ApiKey": "",
11+
"OpenApi__AuthLevel__Document": "Anonymous",
12+
"OpenApi__AuthLevel__UI": "Anonymous",
1013
"OpenApi__BackendProxyUrl": "http://localhost:7071"
1114
}
1215
}

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/SwaggerUIExtensions.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Threading.Tasks;
22

3+
using Microsoft.Azure.WebJobs.Extensions.Http;
34
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
45

56
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions
@@ -14,29 +15,31 @@ public static class SwaggerUIExtensions
1415
/// </summary>
1516
/// <param name="ui"><see cref="ISwaggerUI"/> instance.</param>
1617
/// <param name="endpoint">The endpoint of the Swagger document.</param>
18+
/// <param name="authLevel">The authorisation level of the Swagger document.</param>
1719
/// <param name="authKey">API key of the HTTP endpoint to render OpenAPI document.</param>
1820
/// <returns>The OpenAPI UI in HTML.</returns>
19-
public static async Task<string> RenderAsync(this Task<ISwaggerUI> ui, string endpoint, string authKey = null)
21+
public static async Task<string> RenderAsync(this Task<ISwaggerUI> ui, string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
2022
{
2123
var instance = await ui.ThrowIfNullOrDefault().ConfigureAwait(false);
2224
endpoint.ThrowIfNullOrWhiteSpace();
2325

24-
return await instance.RenderAsync(endpoint, authKey).ConfigureAwait(false);
26+
return await instance.RenderAsync(endpoint, authLevel, authKey).ConfigureAwait(false);
2527
}
2628

2729
/// <summary>
2830
/// Renders the OAuth2 Redirect page in HTML.
2931
/// </summary>
3032
/// <param name="ui"><see cref="ISwaggerUI"/> instance.</param>
3133
/// <param name="endpoint">The endpoint of the OAuth2 Redirect page.</param>
34+
/// <param name="authLevel">The authorisation level of the Swagger document.</param>
3235
/// <param name="authKey">API key of the HTTP endpoint to render OpenAPI document.</param>
3336
/// <returns>The OAuth2 Redirect page in HTML.</returns>
34-
public static async Task<string> RenderOAuth2RedirectAsync(this Task<ISwaggerUI> ui, string endpoint, string authKey = null)
37+
public static async Task<string> RenderOAuth2RedirectAsync(this Task<ISwaggerUI> ui, string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
3538
{
3639
var instance = await ui.ThrowIfNullOrDefault().ConfigureAwait(false);
3740
endpoint.ThrowIfNullOrWhiteSpace();
3841

39-
return await instance.RenderOAuth2RedirectAsync(endpoint, authKey).ConfigureAwait(false);
42+
return await instance.RenderOAuth2RedirectAsync(endpoint, authLevel, authKey).ConfigureAwait(false);
4043
}
4144
}
4245
}

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/ISwaggerUI.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Threading.Tasks;
33

44
using Microsoft.AspNetCore.Http;
5+
using Microsoft.Azure.WebJobs.Extensions.Http;
56
using Microsoft.OpenApi.Models;
67

78
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
@@ -46,16 +47,18 @@ public interface ISwaggerUI
4647
/// Renders OpenAPI UI in HTML.
4748
/// </summary>
4849
/// <param name="endpoint">The endpoint of the Swagger document.</param>
50+
/// <param name="authLevel">The authorisation level of the Swagger document.</param>
4951
/// <param name="authKey">API key of the HTTP endpoint to render OpenAPI document.</param>
5052
/// <returns>OpenAPI UI in HTML.</returns>
51-
Task<string> RenderAsync(string endpoint, string authKey = null);
53+
Task<string> RenderAsync(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null);
5254

5355
/// <summary>
5456
/// Renders OAuth Redirect in HTML.
5557
/// </summary>
5658
/// <param name="endpoint">The endpoint of the OAuth2 Redirect page.</param>
59+
/// <param name="authLevel">The authorisation level of the Swagger document.</param>
5760
/// <param name="authKey">API key of the HTTP endpoint to render OpenAPI document.</param>
5861
/// <returns>OAuth Redirect in HTML.</returns>
59-
Task<string> RenderOAuth2RedirectAsync(string endpoint, string authKey = null);
62+
Task<string> RenderOAuth2RedirectAsync(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null);
6063
}
6164
}

src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/SwaggerUI.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
using System;
12
using System.IO;
23
using System.Linq;
34
using System.Reflection;
45
using System.Threading.Tasks;
56

67
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Azure.WebJobs.Extensions.Http;
79
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
810
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
911
using Microsoft.OpenApi.Models;
@@ -125,32 +127,32 @@ public async Task<ISwaggerUI> BuildOAuth2RedirectAsync(Assembly assembly)
125127
}
126128

127129
/// <inheritdoc />
128-
public async Task<string> RenderAsync(string endpoint, string authKey = null)
130+
public async Task<string> RenderAsync(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
129131
{
130132
endpoint.ThrowIfNullOrWhiteSpace();
131133

132134
var html = await Task.Factory
133-
.StartNew(() => this.Render(endpoint, authKey))
135+
.StartNew(() => this.Render(endpoint, authLevel, authKey))
134136
.ConfigureAwait(false);
135137

136138
return html;
137139
}
138140

139141
/// <inheritdoc />
140-
public async Task<string> RenderOAuth2RedirectAsync(string endpoint, string authKey = null)
142+
public async Task<string> RenderOAuth2RedirectAsync(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
141143
{
142144
var html = await Task.Factory
143-
.StartNew(() => this.RenderOAuth2Redirect(endpoint, authKey))
145+
.StartNew(() => this.RenderOAuth2Redirect(endpoint, authLevel, authKey))
144146
.ConfigureAwait(false);
145147

146148
return html;
147149
}
148150

149-
private string Render(string endpoint, string authKey = null)
151+
private string Render(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
150152
{
151153
var swaggerUiTitle = $"{this._info.Title} - Swagger UI";
152154
var swaggerUrl = $"{this._baseUrl.TrimEnd('/')}/{endpoint}";
153-
if (!string.IsNullOrWhiteSpace(authKey))
155+
if (this.IsAuthKeyRequired(authLevel, authKey))
154156
{
155157
swaggerUrl += $"?code={authKey}";
156158
}
@@ -167,10 +169,10 @@ private string Render(string endpoint, string authKey = null)
167169
}
168170

169171
/// <inheritdoc />
170-
private string RenderOAuth2Redirect(string endpoint, string authKey = null)
172+
private string RenderOAuth2Redirect(string endpoint, AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
171173
{
172174
var pageUrl = $"{this._baseUrl.TrimEnd('/')}/{endpoint}";
173-
if (!string.IsNullOrWhiteSpace(authKey))
175+
if (this.IsAuthKeyRequired(authLevel, authKey))
174176
{
175177
pageUrl += $"?code={authKey}";
176178
}
@@ -179,5 +181,20 @@ private string RenderOAuth2Redirect(string endpoint, string authKey = null)
179181

180182
return html;
181183
}
184+
185+
private bool IsAuthKeyRequired(AuthorizationLevel authLevel = AuthorizationLevel.Anonymous, string authKey = null)
186+
{
187+
if (authLevel == AuthorizationLevel.Anonymous)
188+
{
189+
return false;
190+
}
191+
192+
if (authKey.IsNullOrWhiteSpace())
193+
{
194+
throw new InvalidOperationException("API key is required to access OpenAPI document");
195+
}
196+
197+
return true;
198+
}
182199
}
183200
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.Azure.WebJobs.Extensions.Http;
2+
3+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Configurations
4+
{
5+
/// <summary>
6+
/// This represents the environment variable settings entity for OpenAPI document auth level.
7+
/// </summary>
8+
public class OpenApiAuthLevelSettings
9+
{
10+
/// <summary>
11+
/// Gets or sets the <see cref="AuthorizationLevel"/> value for OpenAPI document rendering endpoints.
12+
/// </summary>
13+
public virtual AuthorizationLevel? Document { get; set; }
14+
15+
/// <summary>
16+
/// Gets or sets the <see cref="AuthorizationLevel"/> value for Swagger UI page rendering endpoints.
17+
/// </summary>
18+
public virtual AuthorizationLevel? UI { get; set; }
19+
}
20+
}

0 commit comments

Comments
 (0)