Skip to content

Commit 662c901

Browse files
Merge pull request #1178 from microsoft/mk/bugfix-security-scheme-reference
Fix: Error generated when security scheme in Components is a reference
2 parents 2d9cffe + a663407 commit 662c901

File tree

6 files changed

+62
-8
lines changed

6 files changed

+62
-8
lines changed

src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ private void ResolveReferences(OpenApiDiagnostic diagnostic, OpenApiDocument doc
166166
}
167167
}
168168

169-
170169
/// <summary>
171170
/// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
172171
/// </summary>

src/Microsoft.OpenApi.Readers/V3/OpenApiSecuritySchemeDeserializer.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ internal static partial class OpenApiV3Deserializer
7676
public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node)
7777
{
7878
var mapNode = node.CheckMapNode("securityScheme");
79-
79+
var pointer = mapNode.GetReferencePointer();
80+
if (pointer != null)
81+
{
82+
return mapNode.GetReferencedObject<OpenApiSecurityScheme>(ReferenceType.SecurityScheme, pointer);
83+
}
8084
var securityScheme = new OpenApiSecurityScheme();
8185
foreach (var property in mapNode)
8286
{

src/Microsoft.OpenApi/Services/OpenApiWalker.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;
@@ -116,7 +116,18 @@ internal void Walk(OpenApiComponents components)
116116
}
117117
}
118118
});
119-
119+
120+
Walk(OpenApiConstants.SecuritySchemes, () =>
121+
{
122+
if (components.SecuritySchemes != null)
123+
{
124+
foreach (var item in components.SecuritySchemes)
125+
{
126+
Walk(item.Key, () => Walk(item.Value, isComponent: true));
127+
}
128+
}
129+
});
130+
120131
Walk(OpenApiConstants.Callbacks, () =>
121132
{
122133
if (components.Callbacks != null)
@@ -996,9 +1007,9 @@ internal void Walk(OpenApiSecurityRequirement securityRequirement)
9961007
/// <summary>
9971008
/// Visits <see cref="OpenApiSecurityScheme"/> and child objects
9981009
/// </summary>
999-
internal void Walk(OpenApiSecurityScheme securityScheme)
1010+
internal void Walk(OpenApiSecurityScheme securityScheme, bool isComponent = false)
10001011
{
1001-
if (securityScheme == null || ProcessAsReference(securityScheme))
1012+
if (securityScheme == null || ProcessAsReference(securityScheme, isComponent))
10021013
{
10031014
return;
10041015
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
<EmbeddedResource Include="V3Tests\Samples\OpenApiDocument\minimalDocument.yaml">
138138
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
139139
</EmbeddedResource>
140+
<EmbeddedResource Include="V3Tests\Samples\OpenApiDocument\docWithSecuritySchemeReference.yaml">
141+
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
142+
</EmbeddedResource>
140143
<EmbeddedResource Include="V3Tests\Samples\OpenApiDocument\apiWithFullHeaderComponent.yaml">
141144
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
142145
</EmbeddedResource>

test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.Contracts;
67
using System.Globalization;
78
using System.IO;
89
using System.Linq;
@@ -1334,10 +1335,10 @@ public void DoesNotChangeExternalReferences()
13341335
{
13351336
// Arrange
13361337
using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "documentWithExternalRefs.yaml"));
1337-
1338+
13381339
// Act
13391340
var doc = new OpenApiStreamReader(
1340-
new OpenApiReaderSettings { ReferenceResolution = ReferenceResolutionSetting.DoNotResolveReferences})
1341+
new OpenApiReaderSettings { ReferenceResolution = ReferenceResolutionSetting.DoNotResolveReferences })
13411342
.Read(stream, out var diagnostic);
13421343

13431344
var externalRef = doc.Components.Schemas["Nested"].Properties["AnyOf"].AnyOf.First().Reference.ReferenceV3;
@@ -1347,5 +1348,24 @@ public void DoesNotChangeExternalReferences()
13471348
Assert.Equal("file:///C:/MySchemas.json#/definitions/ArrayObject", externalRef);
13481349
Assert.Equal("../foo/schemas.yaml#/components/schemas/Number", externalRef2);
13491350
}
1351+
1352+
[Fact]
1353+
public void ParseDocumentWithReferencedSecuritySchemeWorks()
1354+
{
1355+
// Arrange
1356+
using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "docWithSecuritySchemeReference.yaml"));
1357+
1358+
// Act
1359+
var doc = new OpenApiStreamReader(new OpenApiReaderSettings
1360+
{
1361+
ReferenceResolution = ReferenceResolutionSetting.ResolveLocalReferences
1362+
}).Read(stream, out var diagnostic);
1363+
1364+
var securityScheme = doc.Components.SecuritySchemes["OAuth2"];
1365+
1366+
// Assert
1367+
Assert.False(securityScheme.UnresolvedReference);
1368+
Assert.NotNull(securityScheme.Flows);
1369+
}
13501370
}
13511371
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Example API
4+
version: 1.0.0
5+
paths: { }
6+
components:
7+
securitySchemes:
8+
OAuth2:
9+
$ref: '#/components/securitySchemes/RefOAuth2'
10+
RefOAuth2:
11+
type: oauth2
12+
flows:
13+
implicit:
14+
authorizationUrl: https://example.com/api/oauth/dialog
15+
scopes:
16+
write:pets: modify pets in your account
17+
read:pets: read your pets

0 commit comments

Comments
 (0)