Skip to content

Commit

Permalink
chore: Use privacy mask when logging Authorization header (#29)
Browse files Browse the repository at this point in the history
Co-authored-by: danthorpe <[email protected]>
  • Loading branch information
danthorpe and danthorpe authored Oct 19, 2023
1 parent 93ee749 commit 033b997
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 42 deletions.
95 changes: 53 additions & 42 deletions Sources/Networking/Components/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,68 @@ import os.log

extension NetworkingComponent {

public func server(authority: String?) -> some NetworkingComponent {
server(mutate: \.authority) { _ in
authority
} log: { logger, request in
logger?.info("💁 authority -> '\(authority ?? "no value")' \(request.debugDescription)")
}
public func server(authority: String?) -> some NetworkingComponent {
server(mutate: \.authority) { _ in
authority
} log: { logger, request in
logger?.info("💁 authority -> '\(authority ?? "no value")' \(request.debugDescription)")
}
}

public func server(headerField name: HTTPField.Name, value: String?) -> some NetworkingComponent {
server(mutate: \.headerFields) { headers in
var copy = headers
copy[name] = value
return copy
} log: { logger, request in
logger?.info("💁 header \(name) -> '\(value ?? "no value")' \(request.debugDescription)")
}
public func server(headerField name: HTTPField.Name, value: String?) -> some NetworkingComponent {
server(mutate: \.headerFields) { headers in
var copy = headers
copy[name] = value
return copy
} log: { logger, request in
// swiftlint:disable line_length
guard let logger else { return }
guard name.requiresPrivateLogging else {
logger.info("💁 header \(name) -> '\(value ?? "no value", privacy: .public)' \(request.debugDescription)")
return
}
if name.requireHashPrivateLogging {
logger.info("💁 header \(name) -> '\(value ?? "no value", privacy: .private(mask: .hash))' \(request.debugDescription)")
} else {
logger.info("💁 header \(name) -> '\(value ?? "no value", privacy: .private)' \(request.debugDescription)")
}
// swiftlint:enable line_length
}
}

public func server(prefixPath: String, delimiter: String = "/") -> some NetworkingComponent {
server(mutate: \.path) { path in
guard let path else { return prefixPath }
return prefixPath + delimiter + path
} log: { logger, request in
logger?.info("💁 prefix path -> '\(prefixPath)' \(request.debugDescription)")
}
public func server(prefixPath: String, delimiter: String = "/") -> some NetworkingComponent {
server(mutate: \.path) { path in
guard let path else { return prefixPath }
return prefixPath + delimiter + path
} log: { logger, request in
logger?.info("💁 prefix path -> '\(prefixPath)' \(request.debugDescription)")
}
}

public func server<Value>(
mutate keypath: WritableKeyPath<HTTPRequestData, Value>,
with transform: @escaping (Value) -> Value,
log: @escaping (Logger?, HTTPRequestData) -> Void
) -> some NetworkingComponent {
server { request in
@NetworkEnvironment(\.logger) var logger
request[keyPath: keypath] = transform(request[keyPath: keypath])
log(logger, request)
}
public func server<Value>(
mutate keypath: WritableKeyPath<HTTPRequestData, Value>,
with transform: @escaping (Value) -> Value,
log: @escaping (Logger?, HTTPRequestData) -> Void
) -> some NetworkingComponent {
server { request in
@NetworkEnvironment(\.logger) var logger
request[keyPath: keypath] = transform(request[keyPath: keypath])
log(logger, request)
}
}

public func server(
_ mutateRequest: @escaping (inout HTTPRequestData) -> Void
) -> some NetworkingComponent {
modified(MutateRequest(mutate: mutateRequest))
}
public func server(
_ mutateRequest: @escaping (inout HTTPRequestData) -> Void
) -> some NetworkingComponent {
modified(MutateRequest(mutate: mutateRequest))
}
}

private struct MutateRequest: NetworkingModifier {
let mutate: (inout HTTPRequestData) -> Void
func send(upstream: NetworkingComponent, request: HTTPRequestData) -> ResponseStream<HTTPResponseData> {
var copy = request
mutate(&copy)
return upstream.send(copy)
}
let mutate: (inout HTTPRequestData) -> Void
func send(upstream: NetworkingComponent, request: HTTPRequestData) -> ResponseStream<HTTPResponseData> {
var copy = request
mutate(&copy)
return upstream.send(copy)
}
}
13 changes: 13 additions & 0 deletions Sources/Networking/Core/HTTPFieldName+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import HTTPTypes
import os.log

extension HTTPField.Name {
static let requiresPrivateLogging: Set<Self> = Self.requireHashPrivateLogging
static let requireHashPrivateLogging: Set<Self> = [.authorization]
public var requiresPrivateLogging: Bool {
Self.requiresPrivateLogging.contains(self)
}
public var requireHashPrivateLogging: Bool {
Self.requireHashPrivateLogging.contains(self)
}
}

0 comments on commit 033b997

Please sign in to comment.