Skip to content

Commit 3aac661

Browse files
Merge pull request #2278 from microsoft/fix/missing-security-scheme-on-inline-references
fix: always serialize security schemes in components
2 parents ff287bc + fd4c368 commit 3aac661

File tree

4 files changed

+97
-4
lines changed

4 files changed

+97
-4
lines changed

src/Microsoft.OpenApi/Models/OpenApiComponents.cs

+17-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using Microsoft.OpenApi.Interfaces;
78
using Microsoft.OpenApi.Models.Interfaces;
89
using Microsoft.OpenApi.Models.References;
@@ -110,7 +111,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
110111
// however if they have cycles, then we will need a component rendered
111112
if (writer.GetSettings().InlineLocalReferences)
112113
{
113-
RenderComponents(writer, (writer, element) => element.SerializeAsV31(writer));
114+
RenderComponents(writer, (writer, element) => element.SerializeAsV31(writer), OpenApiSpecVersion.OpenApi3_1);
114115
return;
115116
}
116117

@@ -148,7 +149,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
148149
// however if they have cycles, then we will need a component rendered
149150
if (writer.GetSettings().InlineLocalReferences)
150151
{
151-
RenderComponents(writer, (writer, element) => element.SerializeAsV3(writer));
152+
RenderComponents(writer, (writer, element) => element.SerializeAsV3(writer), OpenApiSpecVersion.OpenApi3_0);
152153
return;
153154
}
154155

@@ -315,14 +316,27 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
315316
writer.WriteEndObject();
316317
}
317318

318-
private void RenderComponents(IOpenApiWriter writer, Action<IOpenApiWriter, IOpenApiSerializable> callback)
319+
private void RenderComponents(IOpenApiWriter writer, Action<IOpenApiWriter, IOpenApiSerializable> callback, OpenApiSpecVersion version)
319320
{
320321
var loops = writer.GetSettings().LoopDetector.Loops;
321322
writer.WriteStartObject();
322323
if (loops.TryGetValue(typeof(OpenApiSchema), out var schemas))
323324
{
324325
writer.WriteOptionalMap(OpenApiConstants.Schemas, Schemas, callback);
325326
}
327+
// always render security schemes as inlining of security requirement objects is not allowed in the spec
328+
if (SecuritySchemes is not null && SecuritySchemes.Any())
329+
{
330+
writer.WriteOptionalMap(
331+
OpenApiConstants.SecuritySchemes,
332+
SecuritySchemes,
333+
(w, key, component) =>
334+
{
335+
if (version is OpenApiSpecVersion.OpenApi3_1)
336+
component.SerializeAsV31(writer);
337+
component.SerializeAsV3(writer);
338+
});
339+
}
326340
writer.WriteEndObject();
327341
}
328342

test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFramework>net8.0</TargetFramework>
44
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
@@ -51,6 +51,10 @@
5151
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5252
</None>
5353

54+
<None Update="Models\Samples\docWithSecurityScheme.yaml">
55+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
56+
</None>
57+
5458
<None Update="PublicApi\PublicApi.approved.txt" CopyToOutputDirectory="Always" />
5559
</ItemGroup>
5660
</Project>

test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs

+43
Original file line numberDiff line numberDiff line change
@@ -2179,5 +2179,48 @@ public void SerializeAsThrowsIfVersionIsNotSupported()
21792179
Assert.Equal("version", actual.ParamName);
21802180
Assert.Equal(version, actual.ActualValue);
21812181
}
2182+
2183+
[Fact]
2184+
public async Task SerializeDocWithSecuritySchemeWithInlineRefererencesWorks()
2185+
{
2186+
var expected = @"openapi: 3.0.4
2187+
info:
2188+
title: Repair Service
2189+
version: 1.0.0
2190+
servers:
2191+
- url: https://pluginrentu.azurewebsites.net/api
2192+
paths:
2193+
/repairs:
2194+
get:
2195+
summary: List all repairs with oauth
2196+
description: Returns a list of repairs with their details and images
2197+
operationId: listRepairs
2198+
responses:
2199+
'200':
2200+
description: A list of repairs
2201+
content:
2202+
application/json:
2203+
schema:
2204+
type: object
2205+
security:
2206+
- oAuth2AuthCode: [ ]
2207+
components:
2208+
securitySchemes:
2209+
oAuth2AuthCode:
2210+
type: oauth2
2211+
description: OAuth configuration for the repair service
2212+
flows:
2213+
authorizationCode:
2214+
authorizationUrl: https://login.microsoftonline.com/2f13b28c-bd4d-43e2-8ae6-48594aaba125/oauth2/v2.0/authorize
2215+
tokenUrl: https://login.microsoftonline.com/2f13b28c-bd4d-43e2-8ae6-48594aaba125/oauth2/v2.0/token
2216+
scopes:
2217+
api://a2a7226d-e8d1-4ded-8c53-dd4c136ff456/repairs_read: Read repair records";
2218+
2219+
var doc = (await OpenApiDocument.LoadAsync("Models/Samples/docWithSecurityScheme.yaml", SettingsFixture.ReaderSettings)).Document;
2220+
var stringWriter = new StringWriter();
2221+
doc.SerializeAsV3(new OpenApiYamlWriter(stringWriter, new OpenApiWriterSettings { InlineLocalReferences = true }));
2222+
var actual = stringWriter.ToString();
2223+
Assert.Equal(expected.MakeLineBreaksEnvironmentNeutral(), actual.MakeLineBreaksEnvironmentNeutral());
2224+
}
21822225
}
21832226
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Repair Service
4+
version: 1.0.0
5+
servers:
6+
- url: https://pluginrentu.azurewebsites.net/api
7+
components:
8+
securitySchemes:
9+
oAuth2AuthCode:
10+
type: oauth2
11+
description: OAuth configuration for the repair service
12+
flows:
13+
authorizationCode:
14+
authorizationUrl: https://login.microsoftonline.com/2f13b28c-bd4d-43e2-8ae6-48594aaba125/oauth2/v2.0/authorize
15+
tokenUrl: https://login.microsoftonline.com/2f13b28c-bd4d-43e2-8ae6-48594aaba125/oauth2/v2.0/token
16+
scopes:
17+
api://a2a7226d-e8d1-4ded-8c53-dd4c136ff456/repairs_read: Read repair records
18+
paths:
19+
/repairs:
20+
get:
21+
operationId: listRepairs
22+
summary: List all repairs with oauth
23+
description: Returns a list of repairs with their details and images
24+
security:
25+
- oAuth2AuthCode: []
26+
responses:
27+
'200':
28+
description: A list of repairs
29+
content:
30+
application/json:
31+
schema:
32+
type: object

0 commit comments

Comments
 (0)