Skip to content

Deprecate redactedHeaderFields #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/OpenAPIRuntime/Conversion/CurrencyExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation
extension HeaderField: CustomStringConvertible {
public var description: String {
let value: String
if HeaderField.redactedHeaderFields.contains(name.lowercased()) {
if HeaderField.internalRedactedHeaderFields.contains(name.lowercased()) {
value = "<redacted>"
} else {
value = self.value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftOpenAPIGenerator open source project
//
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
#if canImport(Darwin)
import Foundation
#else
@preconcurrency import Foundation
#endif

/// A protected-by-locks storage for ``redactedHeaderFields``.
private class RedactedHeadersStorage: @unchecked Sendable {
/// The underlying storage of ``redactedHeaderFields``,
/// protected by a lock.
private var _locked_redactedHeaderFields: Set<String> = HeaderField.defaultRedactedHeaderFields

/// The header fields to be redacted.
var redactedHeaderFields: Set<String> {
get {
lock.lock()
defer {
lock.unlock()
}
return _locked_redactedHeaderFields
}
set {
lock.lock()
defer {
lock.unlock()
}
_locked_redactedHeaderFields = newValue
}
}

/// The lock used for protecting access to `_locked_redactedHeaderFields`.
private let lock: NSLock = {
let lock = NSLock()
lock.name = "com.apple.swift-openapi-runtime.lock.redactedHeaderFields"
return lock
}()
}

extension HeaderField {
/// Names of the header fields whose values should be redacted.
///
/// All header field names are lowercased when added to the set.
///
/// The values of header fields with the provided names will are replaced
/// with "<redacted>" when using `HeaderField.description`.
///
/// Use this to avoid leaking sensitive tokens into application logs.
@available(*, deprecated, message: "This feature is deprecated and will be removed in a future version.")
public static var redactedHeaderFields: Set<String> {
set {
internalRedactedHeaderFields = newValue
}
get {
internalRedactedHeaderFields
}
}

/// Names of the header fields whose values should be redacted.
///
/// Should be called by code in the runtime library to avoid emitting a deprecation warning.
internal static var internalRedactedHeaderFields: Set<String> {
set {
// Save lowercased versions of the header field names to make
// membership checking O(1).
redactedHeadersStorage.redactedHeaderFields = Set(newValue.map { $0.lowercased() })
}
get {
return redactedHeadersStorage.redactedHeaderFields
}
}

/// The default header field names whose values are redacted.
public static let defaultRedactedHeaderFields: Set<String> = [
"authorization",
"cookie",
"set-cookie",
]

private static let redactedHeadersStorage = RedactedHeadersStorage()
}
62 changes: 0 additions & 62 deletions Sources/OpenAPIRuntime/Interface/CurrencyTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,6 @@ import Foundation
@preconcurrency import Foundation
#endif

/// A protected-by-locks storage for ``redactedHeaderFields``.
private class RedactedHeadersStorage: @unchecked Sendable {
/// The underlying storage of ``redactedHeaderFields``,
/// protected by a lock.
private var _locked_redactedHeaderFields: Set<String> = HeaderField.defaultRedactedHeaderFields

/// The header fields to be redacted.
var redactedHeaderFields: Set<String> {
get {
lock.lock()
defer {
lock.unlock()
}
return _locked_redactedHeaderFields
}
set {
lock.lock()
defer {
lock.unlock()
}
_locked_redactedHeaderFields = newValue
}
}

/// The lock used for protecting access to `_locked_redactedHeaderFields`.
private let lock: NSLock = {
let lock = NSLock()
lock.name = "com.apple.swift-openapi-runtime.lock.redactedHeaderFields"
return lock
}()
}

/// A header field used in an HTTP request or response.
public struct HeaderField: Equatable, Hashable, Sendable {

Expand All @@ -69,36 +37,6 @@ public struct HeaderField: Equatable, Hashable, Sendable {
}
}

extension HeaderField {
/// Names of the header fields whose values should be redacted.
///
/// All header field names are lowercased when added to the set.
///
/// The values of header fields with the provided names will are replaced
/// with "<redacted>" when using `HeaderField.description`.
///
/// Use this to avoid leaking sensitive tokens into application logs.
public static var redactedHeaderFields: Set<String> {
set {
// Save lowercased versions of the header field names to make
// membership checking O(1).
redactedHeadersStorage.redactedHeaderFields = Set(newValue.map { $0.lowercased() })
}
get {
return redactedHeadersStorage.redactedHeaderFields
}
}

/// The default header field names whose values are redacted.
public static let defaultRedactedHeaderFields: Set<String> = [
"authorization",
"cookie",
"set-cookie",
]

private static let redactedHeadersStorage = RedactedHeadersStorage()
}

/// Describes the HTTP method used in an OpenAPI operation.
///
/// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#fixed-fields-7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
import XCTest
import OpenAPIRuntime
@_spi(Generated)@testable import OpenAPIRuntime

final class Test_CurrencyTypes: Test_Runtime {
final class Test_Deprecated_RedactedHeaderFields: Test_Runtime {

@available(*, deprecated)
func _resetRedactedHeaderFields() {
HeaderField.redactedHeaderFields = HeaderField.defaultRedactedHeaderFields
}
Expand All @@ -35,11 +36,13 @@ final class Test_CurrencyTypes: Test_Runtime {
}
}

@available(*, deprecated)
override func tearDown() async throws {
_resetRedactedHeaderFields()
try await super.tearDown()
}

@available(*, deprecated)
func testDefaultRedactedHeaderFields() {
XCTAssertEqual(
HeaderField.redactedHeaderFields,
Expand All @@ -51,6 +54,7 @@ final class Test_CurrencyTypes: Test_Runtime {
)
}

@available(*, deprecated)
func testCustomizeExtraRedactedHeaderField() {
XCTAssertEqual(
HeaderField.redactedHeaderFields,
Expand Down