Skip to content

Commit 0c7dac5

Browse files
committed
Merge remote-tracking branch 'origin/master' into dm/smoketests2
2 parents ba31015 + 80099fc commit 0c7dac5

File tree

11 files changed

+145
-9
lines changed

11 files changed

+145
-9
lines changed

src/Microsoft.OpenApi.Readers/Services/OpenApiReferenceResolver.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,31 @@ public override void Visit(OpenApiResponses responses)
9999
ResolveMap(responses);
100100
}
101101

102+
/// <summary>
103+
/// Resolve all references to SecuritySchemes
104+
/// </summary>
105+
public override void Visit(OpenApiSecurityRequirement securityRequirement)
106+
{
107+
foreach (var scheme in securityRequirement.Keys.ToList())
108+
{
109+
ResolveObject(scheme, (resolvedScheme) => {
110+
// If scheme was unresolved
111+
// copy Scopes and remove old unresolved scheme
112+
var scopes = securityRequirement[scheme];
113+
securityRequirement.Remove(scheme);
114+
securityRequirement.Add(resolvedScheme, scopes);
115+
});
116+
}
117+
}
118+
119+
/// <summary>
120+
/// Resolve all references to parameters
121+
/// </summary>
122+
public override void Visit(IList<OpenApiParameter> parameters)
123+
{
124+
ResolveList(parameters);
125+
}
126+
102127
/// <summary>
103128
/// Resolve all references to links
104129
/// </summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ internal static partial class OpenApiV3Deserializer
8787
{
8888
"examples", (o, n) =>
8989
{
90-
o.Examples = ((ListNode)n).Select(s => LoadExample(s)).ToList();
90+
o.Examples = n.CreateMap(LoadExample);
9191
}
9292
},
9393
{

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public class OpenApiParameter : IOpenApiSerializable, IOpenApiReferenceable, IOp
101101
/// Furthermore, if referencing a schema which contains an example,
102102
/// the examples value SHALL override the example provided by the schema.
103103
/// </summary>
104-
public IList<OpenApiExample> Examples { get; set; } = new List<OpenApiExample>();
104+
public IDictionary<string,OpenApiExample> Examples { get; set; } = new Dictionary<string,OpenApiExample>();
105105

106106
/// <summary>
107107
/// Example of the media type. The example SHOULD match the specified schema and encoding properties
@@ -189,7 +189,7 @@ public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
189189
writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, s) => w.WriteAny(s));
190190

191191
// examples
192-
writer.WriteOptionalCollection(OpenApiConstants.Examples, Examples, (w, e) => e.SerializeAsV3(w));
192+
writer.WriteOptionalMap(OpenApiConstants.Examples, Examples, (w, e) => e.SerializeAsV3(w));
193193

194194
// content
195195
writer.WriteOptionalMap(OpenApiConstants.Content, Content, (w, c) => c.SerializeAsV3(w));

src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ public virtual void Visit(IList<OpenApiTag> openApiTags)
279279
{
280280
}
281281

282+
/// <summary>
283+
/// Visits list of <see cref="OpenApiSecurityRequirement"/>
284+
/// </summary>
285+
public virtual void Visit(IList<OpenApiSecurityRequirement> openApiSecurityRequirements)
286+
{
287+
}
288+
282289
/// <summary>
283290
/// Visits <see cref="IOpenApiExtensible"/>
284291
/// </summary>

src/Microsoft.OpenApi/Services/OpenApiWalker.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public void Walk(OpenApiDocument doc)
4444
Walk(OpenApiConstants.Servers, () => Walk(doc.Servers));
4545
Walk(OpenApiConstants.Paths, () => Walk(doc.Paths));
4646
Walk(OpenApiConstants.Components, () => Walk(doc.Components));
47+
Walk(OpenApiConstants.Security, () => Walk(doc.SecurityRequirements));
4748
Walk(OpenApiConstants.ExternalDocs, () => Walk(doc.ExternalDocs));
4849
Walk(OpenApiConstants.Tags, () => Walk(doc.Tags));
4950
Walk(doc as IOpenApiExtensible);
@@ -425,6 +426,7 @@ internal void Walk(OpenApiPathItem pathItem)
425426

426427
if (pathItem != null)
427428
{
429+
Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters));
428430
Walk(pathItem.Operations);
429431
}
430432
_visitor.Visit(pathItem as IOpenApiExtensible);
@@ -470,10 +472,32 @@ internal void Walk(OpenApiOperation operation)
470472
Walk(OpenApiConstants.Responses, () => Walk(operation.Responses));
471473
Walk(OpenApiConstants.Callbacks, () => Walk(operation.Callbacks));
472474
Walk(OpenApiConstants.Tags, () => Walk(operation.Tags));
473-
475+
Walk(OpenApiConstants.Security, () => Walk(operation.Security));
474476
Walk(operation as IOpenApiExtensible);
475477
}
476478

479+
/// <summary>
480+
/// Visits list of <see cref="OpenApiSecurityRequirement"/>
481+
/// </summary>
482+
internal void Walk(IList<OpenApiSecurityRequirement> securityRequirements)
483+
{
484+
if (securityRequirements == null)
485+
{
486+
return;
487+
}
488+
489+
_visitor.Visit(securityRequirements);
490+
491+
if (securityRequirements != null)
492+
{
493+
for (int i = 0; i < securityRequirements.Count; i++)
494+
{
495+
Walk(i.ToString(), () => Walk(securityRequirements[i]));
496+
}
497+
}
498+
}
499+
500+
477501
/// <summary>
478502
/// Visits list of <see cref="OpenApiParameter"/>
479503
/// </summary>
@@ -508,6 +532,8 @@ internal void Walk(OpenApiParameter parameter)
508532
_visitor.Visit(parameter);
509533
Walk(OpenApiConstants.Schema, () => Walk(parameter.Schema));
510534
Walk(OpenApiConstants.Content, () => Walk(parameter.Content));
535+
Walk(OpenApiConstants.Examples, () => Walk(parameter.Examples));
536+
511537
Walk(parameter as IOpenApiExtensible);
512538
}
513539

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
<SignAssembly>true</SignAssembly>
1313
<AssemblyOriginatorKeyFile>..\..\src\Microsoft.OpenApi.snk</AssemblyOriginatorKeyFile>
1414
</PropertyGroup>
15+
<ItemGroup>
16+
<None Remove="V3Tests\Samples\OpenApiDocument\securedApi.yaml" />
17+
<None Remove="V3Tests\Samples\OpenApiOperation\securedOperation.yaml" />
18+
</ItemGroup>
1519
<ItemGroup>
1620
<EmbeddedResource Include="OpenApiReaderTests\Samples\unsupported.v1.yaml">
1721
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
@@ -94,6 +98,7 @@
9498
<EmbeddedResource Include="V3Tests\Samples\OpenApiDocument\petStoreWithTagAndSecurity.yaml">
9599
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
96100
</EmbeddedResource>
101+
<EmbeddedResource Include="V3Tests\Samples\OpenApiDocument\securedApi.yaml" />
97102
<EmbeddedResource Include="V3Tests\Samples\OpenApiEncoding\advancedEncoding.yaml">
98103
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
99104
</EmbeddedResource>
@@ -109,6 +114,7 @@
109114
<EmbeddedResource Include="V3Tests\Samples\OpenApiInfo\minimalInfo.yaml">
110115
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
111116
</EmbeddedResource>
117+
<EmbeddedResource Include="V3Tests\Samples\OpenApiOperation\securedOperation.yaml" />
112118
<EmbeddedResource Include="V3Tests\Samples\OpenApiSchema\advancedSchemaWithReference.yaml">
113119
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
114120
</EmbeddedResource>

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.IO;
7+
using System.Linq;
78
using FluentAssertions;
89
using Microsoft.OpenApi.Models;
910
using Newtonsoft.Json;
@@ -1110,5 +1111,18 @@ public void ParsePetStoreExpandedShouldSucceed()
11101111
context.ShouldBeEquivalentTo(
11111112
new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 });
11121113
}
1114+
1115+
[Fact]
1116+
public void GlobalSecurityRequirementShouldReferenceSecurityScheme()
1117+
{
1118+
using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "securedApi.yaml")))
1119+
{
1120+
var openApiDoc = new OpenApiStreamReader().Read(stream, out var diagnostic);
1121+
1122+
var securityRequirement = openApiDoc.SecurityRequirements.First();
1123+
1124+
Assert.Same(securityRequirement.Keys.First(), openApiDoc.Components.SecuritySchemes.First().Value);
1125+
}
1126+
}
11131127
}
11141128
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System.IO;
5+
using System.Linq;
6+
using Xunit;
7+
8+
namespace Microsoft.OpenApi.Readers.Tests.V3Tests
9+
{
10+
public class OpenApiOperationTests
11+
{
12+
private const string SampleFolderPath = "V3Tests/Samples/OpenApiOperation/";
13+
14+
[Fact]
15+
public void OperationWithSecurityRequirementShouldReferenceSecurityScheme()
16+
{
17+
using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "securedOperation.yaml")))
18+
{
19+
var openApiDoc = new OpenApiStreamReader().Read(stream, out var diagnostic);
20+
21+
var securityRequirement = openApiDoc.Paths["/"].Operations[Models.OperationType.Get].Security.First();
22+
23+
Assert.Same(securityRequirement.Keys.First(), openApiDoc.Components.SecuritySchemes.First().Value);
24+
}
25+
}
26+
27+
28+
}
29+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Example of Security Requirement referencing a security scheme
4+
version: 1.0.0
5+
paths: {}
6+
security:
7+
- basicAuth: []
8+
components:
9+
securitySchemes:
10+
basicAuth:
11+
type: http
12+
scheme: basic
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Example of Security Requirement referencing a security scheme
4+
version: 1.0.0
5+
paths:
6+
'/':
7+
get:
8+
security:
9+
- basicAuth: []
10+
responses:
11+
'200':
12+
description: OK
13+
components:
14+
securitySchemes:
15+
basicAuth:
16+
type: http
17+
scheme: basic

0 commit comments

Comments
 (0)