Skip to content

Commit e449abb

Browse files
committed
add new security scheme fields
1 parent 857e1a5 commit e449abb

File tree

5 files changed

+53
-23
lines changed

5 files changed

+53
-23
lines changed

Sources/OpenAPIKit/Security/SecurityScheme.swift

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ extension OpenAPI {
1515
public struct SecurityScheme: Equatable, CodableVendorExtendable, Sendable {
1616
public var type: SecurityType
1717
public var description: String?
18+
/// Indication of if the security scheme is deprecated. Defaults to
19+
/// `false` and OpenAPIKit only encodes this property if it is set to
20+
/// `true`.
21+
public var deprecated: Bool
1822

1923
/// Dictionary of vendor extensions.
2024
///
@@ -26,37 +30,39 @@ extension OpenAPI {
2630
public init(
2731
type: SecurityType,
2832
description: String? = nil,
29-
vendorExtensions: [String: AnyCodable] = [:]
33+
vendorExtensions: [String: AnyCodable] = [:],
34+
deprecated: Bool = false
3035
) {
3136
self.type = type
3237
self.description = description
3338
self.vendorExtensions = vendorExtensions
39+
self.deprecated = deprecated
3440
}
3541

36-
public static func apiKey(name: String, location: Location, description: String? = nil) -> SecurityScheme {
37-
return .init(type: .apiKey(name: name, location: location), description: description)
42+
public static func apiKey(name: String, location: Location, description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
43+
return .init(type: .apiKey(name: name, location: location), description: description, deprecated: deprecated)
3844
}
3945

40-
public static func http(scheme: String, bearerFormat: String? = nil, description: String? = nil) -> SecurityScheme {
41-
return .init(type: .http(scheme: scheme, bearerFormat: bearerFormat), description: description)
46+
public static func http(scheme: String, bearerFormat: String? = nil, description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
47+
return .init(type: .http(scheme: scheme, bearerFormat: bearerFormat), description: description, deprecated: deprecated)
4248
}
4349

44-
public static func oauth2(flows: OAuthFlows, description: String? = nil) -> SecurityScheme {
45-
return .init(type: .oauth2(flows: flows), description: description)
50+
public static func oauth2(flows: OAuthFlows, metadataUrl: URL? = nil, description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
51+
return .init(type: .oauth2(flows: flows, metadataUrl: metadataUrl), description: description, deprecated: deprecated)
4652
}
4753

48-
public static func openIdConnect(url: URL, description: String? = nil) -> SecurityScheme {
49-
return .init(type: .openIdConnect(openIdConnectUrl: url), description: description)
54+
public static func openIdConnect(url: URL, description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
55+
return .init(type: .openIdConnect(openIdConnectUrl: url), description: description, deprecated: deprecated)
5056
}
5157

52-
public static func mutualTLS(description: String? = nil) -> SecurityScheme {
53-
return .init(type: .mutualTLS, description: description)
58+
public static func mutualTLS(description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
59+
return .init(type: .mutualTLS, description: description, deprecated: deprecated)
5460
}
5561

5662
public enum SecurityType: Equatable, Sendable {
5763
case apiKey(name: String, location: Location)
5864
case http(scheme: String, bearerFormat: String?)
59-
case oauth2(flows: OAuthFlows)
65+
case oauth2(flows: OAuthFlows, metadataUrl: URL?)
6066
case openIdConnect(openIdConnectUrl: URL)
6167
case mutualTLS
6268
}
@@ -106,6 +112,10 @@ extension OpenAPI.SecurityScheme: Encodable {
106112

107113
try container.encodeIfPresent(description, forKey: .description)
108114

115+
if deprecated {
116+
try container.encode(deprecated, forKey: .deprecated)
117+
}
118+
109119
switch type {
110120
case .apiKey(name: let name, location: let location):
111121
try container.encode(SecurityType.Name.apiKey, forKey: .type)
@@ -118,9 +128,10 @@ extension OpenAPI.SecurityScheme: Encodable {
118128
case .openIdConnect(openIdConnectUrl: let url):
119129
try container.encode(SecurityType.Name.openIdConnect, forKey: .type)
120130
try container.encode(url.absoluteString, forKey: .openIdConnectUrl)
121-
case .oauth2(flows: let flows):
131+
case .oauth2(flows: let flows, metadataUrl: let url):
122132
try container.encode(SecurityType.Name.oauth2, forKey: .type)
123133
try container.encode(flows, forKey: .flows)
134+
try container.encodeIfPresent(url?.absoluteString, forKey: .oauth2MetadataUrl)
124135
case .mutualTLS:
125136
try container.encode(SecurityType.Name.mutualTLS, forKey: .type)
126137
}
@@ -137,6 +148,8 @@ extension OpenAPI.SecurityScheme: Decodable {
137148

138149
description = try container.decodeIfPresent(String.self, forKey: .description)
139150

151+
deprecated = try container.decodeIfPresent(Bool.self, forKey: .deprecated) ?? false
152+
140153
let typeName = try container.decode(SecurityType.Name.self, forKey: .type)
141154

142155
switch typeName {
@@ -154,7 +167,8 @@ extension OpenAPI.SecurityScheme: Decodable {
154167
)
155168
case .oauth2:
156169
type = .oauth2(
157-
flows: try container.decode(OpenAPI.OAuthFlows.self, forKey: .flows)
170+
flows: try container.decode(OpenAPI.OAuthFlows.self, forKey: .flows),
171+
metadataUrl: try container.decodeURLAsStringIfPresent(forKey: .oauth2MetadataUrl)
158172
)
159173
case .openIdConnect:
160174
type = .openIdConnect(
@@ -186,24 +200,28 @@ extension OpenAPI.SecurityScheme {
186200
internal enum CodingKeys: ExtendableCodingKey {
187201
case type
188202
case description
203+
case deprecated
189204
case name
190205
case location
191206
case scheme
192207
case bearerFormat
193208
case flows
194209
case openIdConnectUrl
210+
case oauth2MetadataUrl
195211
case extended(String)
196212

197213
static var allBuiltinKeys: [CodingKeys] {
198214
return [
199215
.type,
200216
.description,
217+
.deprecated,
201218
.name,
202219
.location,
203220
.scheme,
204221
.bearerFormat,
205222
.flows,
206-
.openIdConnectUrl
223+
.openIdConnectUrl,
224+
.oauth2MetadataUrl
207225
]
208226
}
209227

@@ -217,6 +235,8 @@ extension OpenAPI.SecurityScheme {
217235
self = .type
218236
case "description":
219237
self = .description
238+
case "deprecated":
239+
self = .deprecated
220240
case "name":
221241
self = .name
222242
case "in":
@@ -229,6 +249,8 @@ extension OpenAPI.SecurityScheme {
229249
self = .flows
230250
case "openIdConnectUrl":
231251
self = .openIdConnectUrl
252+
case "oauth2MetadataUrl":
253+
self = .oauth2MetadataUrl
232254
default:
233255
self = .extendedKey(for: stringValue)
234256
}
@@ -240,6 +262,8 @@ extension OpenAPI.SecurityScheme {
240262
return "type"
241263
case .description:
242264
return "description"
265+
case .deprecated:
266+
return "deprecated"
243267
case .name:
244268
return "name"
245269
case .location:
@@ -252,6 +276,8 @@ extension OpenAPI.SecurityScheme {
252276
return "flows"
253277
case .openIdConnectUrl:
254278
return "openIdConnectUrl"
279+
case .oauth2MetadataUrl:
280+
return "oauth2MetadataUrl"
255281
case .extended(let key):
256282
return key
257283
}
@@ -281,3 +307,5 @@ extension OpenAPI.SecurityScheme: ExternallyDereferenceable {
281307
return (self, .init(), [])
282308
}
283309
}
310+
311+
extension OpenAPI.SecurityScheme: Validatable {}

Sources/OpenAPIKitCompat/Compat30To31.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ extension OpenAPIKit30.OpenAPI.SecurityScheme.SecurityType: To31 {
485485
case .http(scheme: let scheme, bearerFormat: let bearerFormat):
486486
return .http(scheme: scheme, bearerFormat: bearerFormat)
487487
case .oauth2(flows: let flows):
488-
return .oauth2(flows: flows.to31())
488+
return .oauth2(flows: flows.to31(), metadataUrl: nil)
489489
case .openIdConnect(openIdConnectUrl: let openIdConnectUrl):
490490
return .openIdConnect(openIdConnectUrl: openIdConnectUrl)
491491
}

Tests/OpenAPIKitCompatTests/DocumentConversionTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,8 @@ fileprivate func assertEqualNewToOld(_ newScheme: OpenAPIKit.OpenAPI.SecuritySch
15931593
case (.http(let scheme, let format), .http(let scheme2, let format2)):
15941594
XCTAssertEqual(scheme, scheme2)
15951595
XCTAssertEqual(format, format2)
1596-
case (.oauth2(let flows), .oauth2(let flows2)):
1596+
case (.oauth2(let flows, let metadataUrl), .oauth2(let flows2)):
1597+
XCTAssertNil(metadataUrl)
15971598
try assertEqualNewToOld(flows, flows2)
15981599
case (.openIdConnect(let url), .openIdConnect(let url2)):
15991600
XCTAssertEqual(url, url2)

Tests/OpenAPIKitTests/EaseOfUseTests.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,17 @@ final class DeclarativeEaseOfUseTests: XCTestCase {
359359
"read:widgets" : "read those widgets"
360360
]
361361
)
362-
)
362+
),
363+
metadataUrl: URL(string: "https://google.com")!
363364
),
364365
description: "OAuth Flows"
365366
)
366367
])
367368

368369
let securityRequirements: [OpenAPI.SecurityRequirement] = [
369370
[
370-
.component( named: "basic_auth"): [],
371-
.component( named: "oauth_flow"): ["read:widgets"]
371+
.component(named: "basic_auth"): [],
372+
.component(named: "oauth_flow"): ["read:widgets"]
372373
]
373374
]
374375

Tests/OpenAPIKitTests/Security/SecuritySchemeTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ final class SecuritySchemeTests: XCTestCase {
2424
)
2525

2626
XCTAssertEqual(
27-
OpenAPI.SecurityScheme(type: .oauth2(flows: .init()), description: "description"),
28-
OpenAPI.SecurityScheme.oauth2(flows: .init(), description: "description")
27+
OpenAPI.SecurityScheme(type: .oauth2(flows: .init(), metadataUrl: URL(string: "https://google.com")!), description: "description"),
28+
OpenAPI.SecurityScheme.oauth2(flows: .init(), metadataUrl: URL(string: "https://google.com")!, description: "description")
2929
)
3030

3131
XCTAssertEqual(
@@ -60,7 +60,7 @@ final class SecuritySchemeTests: XCTestCase {
6060
)
6161

6262
XCTAssertEqual(
63-
OpenAPI.SecurityScheme(type: .oauth2(flows: .init()), description: "description").type.name,
63+
OpenAPI.SecurityScheme(type: .oauth2(flows: .init(), metadataUrl: nil), description: "description").type.name,
6464
.oauth2
6565
)
6666

0 commit comments

Comments
 (0)