Skip to content

Commit 08c12e1

Browse files
authored
Deprecate redactedHeaderFields (#32)
Deprecate redactedHeaderFields ### Motivation For details, see apple/swift-openapi-generator#113. ### Modifications This PR deprecates the feature in the current 0.1.x version, so that it can be removed in 0.2.0. ### Result When adopters use this feature in 0.1.x, they will get a deprecation warning. ### Test Plan Moved the tests to the deprecated section as well, to be removed before we tag 0.2.0. Reviewed by: FranzBusch, simonjbeaumont Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (api breakage) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #32
1 parent b2c9ea8 commit 08c12e1

File tree

4 files changed

+100
-65
lines changed

4 files changed

+100
-65
lines changed

Sources/OpenAPIRuntime/Conversion/CurrencyExtensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Foundation
1616
extension HeaderField: CustomStringConvertible {
1717
public var description: String {
1818
let value: String
19-
if HeaderField.redactedHeaderFields.contains(name.lowercased()) {
19+
if HeaderField.internalRedactedHeaderFields.contains(name.lowercased()) {
2020
value = "<redacted>"
2121
} else {
2222
value = self.value
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftOpenAPIGenerator open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
#if canImport(Darwin)
15+
import Foundation
16+
#else
17+
@preconcurrency import Foundation
18+
#endif
19+
20+
/// A protected-by-locks storage for ``redactedHeaderFields``.
21+
private class RedactedHeadersStorage: @unchecked Sendable {
22+
/// The underlying storage of ``redactedHeaderFields``,
23+
/// protected by a lock.
24+
private var _locked_redactedHeaderFields: Set<String> = HeaderField.defaultRedactedHeaderFields
25+
26+
/// The header fields to be redacted.
27+
var redactedHeaderFields: Set<String> {
28+
get {
29+
lock.lock()
30+
defer {
31+
lock.unlock()
32+
}
33+
return _locked_redactedHeaderFields
34+
}
35+
set {
36+
lock.lock()
37+
defer {
38+
lock.unlock()
39+
}
40+
_locked_redactedHeaderFields = newValue
41+
}
42+
}
43+
44+
/// The lock used for protecting access to `_locked_redactedHeaderFields`.
45+
private let lock: NSLock = {
46+
let lock = NSLock()
47+
lock.name = "com.apple.swift-openapi-runtime.lock.redactedHeaderFields"
48+
return lock
49+
}()
50+
}
51+
52+
extension HeaderField {
53+
/// Names of the header fields whose values should be redacted.
54+
///
55+
/// All header field names are lowercased when added to the set.
56+
///
57+
/// The values of header fields with the provided names will are replaced
58+
/// with "<redacted>" when using `HeaderField.description`.
59+
///
60+
/// Use this to avoid leaking sensitive tokens into application logs.
61+
@available(*, deprecated, message: "This feature is deprecated and will be removed in a future version.")
62+
public static var redactedHeaderFields: Set<String> {
63+
set {
64+
internalRedactedHeaderFields = newValue
65+
}
66+
get {
67+
internalRedactedHeaderFields
68+
}
69+
}
70+
71+
/// Names of the header fields whose values should be redacted.
72+
///
73+
/// Should be called by code in the runtime library to avoid emitting a deprecation warning.
74+
internal static var internalRedactedHeaderFields: Set<String> {
75+
set {
76+
// Save lowercased versions of the header field names to make
77+
// membership checking O(1).
78+
redactedHeadersStorage.redactedHeaderFields = Set(newValue.map { $0.lowercased() })
79+
}
80+
get {
81+
return redactedHeadersStorage.redactedHeaderFields
82+
}
83+
}
84+
85+
/// The default header field names whose values are redacted.
86+
public static let defaultRedactedHeaderFields: Set<String> = [
87+
"authorization",
88+
"cookie",
89+
"set-cookie",
90+
]
91+
92+
private static let redactedHeadersStorage = RedactedHeadersStorage()
93+
}

Sources/OpenAPIRuntime/Interface/CurrencyTypes.swift

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,6 @@ import Foundation
1818
@preconcurrency import Foundation
1919
#endif
2020

21-
/// A protected-by-locks storage for ``redactedHeaderFields``.
22-
private class RedactedHeadersStorage: @unchecked Sendable {
23-
/// The underlying storage of ``redactedHeaderFields``,
24-
/// protected by a lock.
25-
private var _locked_redactedHeaderFields: Set<String> = HeaderField.defaultRedactedHeaderFields
26-
27-
/// The header fields to be redacted.
28-
var redactedHeaderFields: Set<String> {
29-
get {
30-
lock.lock()
31-
defer {
32-
lock.unlock()
33-
}
34-
return _locked_redactedHeaderFields
35-
}
36-
set {
37-
lock.lock()
38-
defer {
39-
lock.unlock()
40-
}
41-
_locked_redactedHeaderFields = newValue
42-
}
43-
}
44-
45-
/// The lock used for protecting access to `_locked_redactedHeaderFields`.
46-
private let lock: NSLock = {
47-
let lock = NSLock()
48-
lock.name = "com.apple.swift-openapi-runtime.lock.redactedHeaderFields"
49-
return lock
50-
}()
51-
}
52-
5321
/// A header field used in an HTTP request or response.
5422
public struct HeaderField: Equatable, Hashable, Sendable {
5523

@@ -69,36 +37,6 @@ public struct HeaderField: Equatable, Hashable, Sendable {
6937
}
7038
}
7139

72-
extension HeaderField {
73-
/// Names of the header fields whose values should be redacted.
74-
///
75-
/// All header field names are lowercased when added to the set.
76-
///
77-
/// The values of header fields with the provided names will are replaced
78-
/// with "<redacted>" when using `HeaderField.description`.
79-
///
80-
/// Use this to avoid leaking sensitive tokens into application logs.
81-
public static var redactedHeaderFields: Set<String> {
82-
set {
83-
// Save lowercased versions of the header field names to make
84-
// membership checking O(1).
85-
redactedHeadersStorage.redactedHeaderFields = Set(newValue.map { $0.lowercased() })
86-
}
87-
get {
88-
return redactedHeadersStorage.redactedHeaderFields
89-
}
90-
}
91-
92-
/// The default header field names whose values are redacted.
93-
public static let defaultRedactedHeaderFields: Set<String> = [
94-
"authorization",
95-
"cookie",
96-
"set-cookie",
97-
]
98-
99-
private static let redactedHeadersStorage = RedactedHeadersStorage()
100-
}
101-
10240
/// Describes the HTTP method used in an OpenAPI operation.
10341
///
10442
/// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#fixed-fields-7

Tests/OpenAPIRuntimeTests/Interface/Test_CurrencyTypes.swift renamed to Tests/OpenAPIRuntimeTests/Deprecated/Test_Deprecated_RedactedHeaderFields.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414
import XCTest
15-
import OpenAPIRuntime
15+
@_spi(Generated)@testable import OpenAPIRuntime
1616

17-
final class Test_CurrencyTypes: Test_Runtime {
17+
final class Test_Deprecated_RedactedHeaderFields: Test_Runtime {
1818

19+
@available(*, deprecated)
1920
func _resetRedactedHeaderFields() {
2021
HeaderField.redactedHeaderFields = HeaderField.defaultRedactedHeaderFields
2122
}
@@ -35,11 +36,13 @@ final class Test_CurrencyTypes: Test_Runtime {
3536
}
3637
}
3738

39+
@available(*, deprecated)
3840
override func tearDown() async throws {
3941
_resetRedactedHeaderFields()
4042
try await super.tearDown()
4143
}
4244

45+
@available(*, deprecated)
4346
func testDefaultRedactedHeaderFields() {
4447
XCTAssertEqual(
4548
HeaderField.redactedHeaderFields,
@@ -51,6 +54,7 @@ final class Test_CurrencyTypes: Test_Runtime {
5154
)
5255
}
5356

57+
@available(*, deprecated)
5458
func testCustomizeExtraRedactedHeaderField() {
5559
XCTAssertEqual(
5660
HeaderField.redactedHeaderFields,

0 commit comments

Comments
 (0)