-
Notifications
You must be signed in to change notification settings - Fork 276
Expand file tree
/
Copy pathOpenApiSecurityRequirement.cs
More file actions
153 lines (133 loc) · 5.27 KB
/
OpenApiSecurityRequirement.cs
File metadata and controls
153 lines (133 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.OpenApi
{
/// <summary>
/// Security Requirement Object.
/// Each name MUST correspond to a security scheme which is declared in
/// the Security Schemes under the Components Object.
/// If the security scheme is of type "oauth2" or "openIdConnect",
/// then the value is a list of scope names required for the execution.
/// For other security scheme types, the array MUST be empty.
/// </summary>
public class OpenApiSecurityRequirement : Dictionary<OpenApiSecuritySchemeReference, List<string>>,
IOpenApiSerializable
{
/// <summary>
/// Initializes the <see cref="OpenApiSecurityRequirement"/> class.
/// This constructor ensures that only Reference.Id is considered when two dictionary keys
/// of type <see cref="OpenApiSecurityScheme"/> are compared.
/// </summary>
public OpenApiSecurityRequirement()
: base(new OpenApiSecuritySchemeReferenceEqualityComparer())
{
}
/// <summary>
/// Serialize <see cref="OpenApiSecurityRequirement"/> to Open Api v3.1
/// </summary>
public virtual void SerializeAsV31(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) =>
{
if(!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null)
{
w.WritePropertyName(s.Reference.ReferenceV3);
}
});
}
/// <summary>
/// Serialize <see cref="OpenApiSecurityRequirement"/> to Open Api v3.0
/// </summary>
public virtual void SerializeAsV3(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) =>
{
if (!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null)
{
w.WritePropertyName(s.Reference.ReferenceV3);
}
});
}
/// <summary>
/// Serialize <see cref="OpenApiSecurityRequirement"/>
/// </summary>
private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, OpenApiSecuritySchemeReference> callback)
{
Utils.CheckArgumentNull(writer);
writer.WriteStartObject();
foreach (var securitySchemeAndScopesValuePair in this.Where(static p => CanSerializeSecurityScheme(p.Key)))
{
var securityScheme = securitySchemeAndScopesValuePair.Key;
var scopes = securitySchemeAndScopesValuePair.Value;
callback(writer, securityScheme);
writer.WriteStartArray();
foreach (var scope in scopes)
{
writer.WriteValue(scope);
}
writer.WriteEndArray();
}
writer.WriteEndObject();
}
private static bool CanSerializeSecurityScheme(OpenApiSecuritySchemeReference? securityScheme)
{
if (securityScheme is null)
{
return false;
}
if (securityScheme.Target is not null)
{
return true;
}
var schemeId = securityScheme.Reference?.Id;
var securitySchemes = securityScheme.Reference?.HostDocument?.Components?.SecuritySchemes;
return !string.IsNullOrEmpty(schemeId)
&& securitySchemes is not null
&& securitySchemes.ContainsKey(schemeId!);
}
/// <summary>
/// Serialize <see cref="OpenApiSecurityRequirement"/> to Open Api v2.0
/// </summary>
public virtual void SerializeAsV2(IOpenApiWriter writer)
{
SerializeInternal(writer, (w, s) => s.SerializeAsV2(w));
}
/// <summary>
/// Comparer for OpenApiSecurityScheme that only considers the Id in the Reference
/// (i.e. the string that will actually be displayed in the written document)
/// </summary>
private sealed class OpenApiSecuritySchemeReferenceEqualityComparer : IEqualityComparer<OpenApiSecuritySchemeReference>
{
/// <summary>
/// Determines whether the specified objects are equal.
/// </summary>
public bool Equals(OpenApiSecuritySchemeReference? x, OpenApiSecuritySchemeReference? y)
{
if (x == null && y == null)
{
return true;
}
if (x == null || y == null)
{
return false;
}
return GetHashCode(x) == GetHashCode(y);
}
/// <summary>
/// Returns a hash code for the specified object.
/// </summary>
public int GetHashCode(OpenApiSecuritySchemeReference obj)
{
if (obj is null)
{
return 0;
}
var id = obj.Reference?.Id;
return string.IsNullOrEmpty(id) ? 0 : id!.GetHashCode();
}
}
}
}