Skip to content

Commit 5f279d8

Browse files
committed
add conditional warnings for new security scheme fields
1 parent 8a59716 commit 5f279d8

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

Sources/OpenAPIKit/Security/SecurityScheme.swift

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extension OpenAPI {
1212
/// OpenAPI Spec "Security Scheme Object"
1313
///
1414
/// See [OpenAPI Security Scheme Object](https://spec.openapis.org/oas/v3.1.1.html#security-scheme-object).
15-
public struct SecurityScheme: Equatable, CodableVendorExtendable, Sendable {
15+
public struct SecurityScheme: HasConditionalWarnings, CodableVendorExtendable, Sendable {
1616
public var type: SecurityType
1717
public var description: String?
1818
/// Indication of if the security scheme is deprecated. Defaults to
@@ -26,6 +26,8 @@ extension OpenAPI {
2626
/// `[ "x-extensionKey": <anything>]`
2727
/// where the values are anything codable.
2828
public var vendorExtensions: [String: AnyCodable]
29+
30+
public let conditionalWarnings: [(any Condition, OpenAPI.Warning)]
2931

3032
public init(
3133
type: SecurityType,
@@ -37,6 +39,11 @@ extension OpenAPI {
3739
self.description = description
3840
self.vendorExtensions = vendorExtensions
3941
self.deprecated = deprecated
42+
43+
self.conditionalWarnings = [
44+
nonNilVersionWarning(fieldName: "oauth2MetadataUrl", value: type.oauth2MetadataUrl, minimumVersion: .v3_2_0),
45+
notFalseVersionWarning(fieldName: "deprecated", value: deprecated, minimumVersion: .v3_2_0)
46+
].compactMap { $0 }
4047
}
4148

4249
public static func apiKey(name: String, location: Location, description: String? = nil, deprecated: Bool = false) -> SecurityScheme {
@@ -69,6 +76,15 @@ extension OpenAPI {
6976
}
7077
}
7178

79+
extension OpenAPI.SecurityScheme: Equatable {
80+
public static func == (lhs: Self, rhs: Self) -> Bool {
81+
lhs.type == rhs.type
82+
&& lhs.description == rhs.description
83+
&& lhs.deprecated == rhs.deprecated
84+
&& lhs.vendorExtensions == rhs.vendorExtensions
85+
}
86+
}
87+
7288
fileprivate func notFalseVersionWarning(fieldName: String, value: Bool, minimumVersion: OpenAPI.Document.Version) -> (any Condition, OpenAPI.Warning)? {
7389
guard value else { return nil }
7490

@@ -78,6 +94,15 @@ fileprivate func notFalseVersionWarning(fieldName: String, value: Bool, minimumV
7894
)
7995
}
8096

97+
fileprivate func nonNilVersionWarning<Subject>(fieldName: String, value: Subject?, minimumVersion: OpenAPI.Document.Version) -> (any Condition, OpenAPI.Warning)? {
98+
value.map { _ in
99+
OpenAPI.Document.ConditionalWarnings.version(
100+
lessThan: minimumVersion,
101+
doesNotSupport: "The Security Scheme \(fieldName) field"
102+
)
103+
}
104+
}
105+
81106
extension OpenAPI.SecurityScheme.SecurityType {
82107
public enum Name: String, Codable {
83108
case apiKey
@@ -101,6 +126,12 @@ extension OpenAPI.SecurityScheme.SecurityType {
101126
return .mutualTLS
102127
}
103128
}
129+
130+
public var oauth2MetadataUrl: URL? {
131+
guard case let .oauth2(_, metadataUrl: metadataUrl) = self else { return nil }
132+
133+
return metadataUrl
134+
}
104135
}
105136

106137
// MARK: - Describable
@@ -188,6 +219,11 @@ extension OpenAPI.SecurityScheme: Decodable {
188219
}
189220

190221
vendorExtensions = try Self.extensions(from: decoder)
222+
223+
self.conditionalWarnings = [
224+
nonNilVersionWarning(fieldName: "oauth2MetadataUrl", value: type.oauth2MetadataUrl, minimumVersion: .v3_2_0),
225+
notFalseVersionWarning(fieldName: "deprecated", value: deprecated, minimumVersion: .v3_2_0)
226+
].compactMap { $0 }
191227
}
192228

193229
internal static func decodeAPIKey(from container: KeyedDecodingContainer<OpenAPI.SecurityScheme.CodingKeys>) throws -> (name: String, location: Location) {

Tests/OpenAPIKitTests/Security/OauthFlowsTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ final class OAuthFlowsTests: XCTestCase {
9090
password: passwordFlow,
9191
clientCredentials: clientCredentialsFlow,
9292
authorizationCode: authorizationCodeFlow,
93-
authorizationCode: deviceAuthorizationFlow
93+
deviceAuthorization: deviceAuthorizationFlow
9494
)
9595

9696
XCTAssertEqual(flows2.implicit, implicitFlow)

Tests/OpenAPIKitTests/Security/SecuritySchemeTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ final class SecuritySchemeTests: XCTestCase {
3737
OpenAPI.SecurityScheme(type: .mutualTLS, description: "description"),
3838
OpenAPI.SecurityScheme.mutualTLS(description: "description")
3939
)
40+
41+
let noWarnings = OpenAPI.SecurityScheme(type: .oauth2(flows: .init(), metadataUrl: nil), deprecated: false)
42+
XCTAssertEqual(noWarnings.conditionalWarnings.count, 0)
43+
44+
let twoWarnings = OpenAPI.SecurityScheme(type: .oauth2(flows: .init(), metadataUrl: URL(string: "https://google.com")!), deprecated: true)
45+
XCTAssertEqual(twoWarnings.conditionalWarnings.count, 2)
4046
}
4147

4248
func test_locallyDereferenced() throws {
@@ -686,6 +692,7 @@ extension SecuritySchemeTests {
686692
)
687693

688694
let document = OpenAPI.Document(
695+
openAPIVersion: .v3_2_0,
689696
info: OpenAPI.Document.Info(title: "hi", version: "1.0.0"),
690697
servers: [],
691698
paths: [:],

0 commit comments

Comments
 (0)