Skip to content

Commit

Permalink
Add a VPN metadata section to the debug UI (#2502)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/414235014887631/1206688960052937/f
Tech Design URL:
CC:

Description:

This PR adds a VPN metadata section to the debug menu.
  • Loading branch information
samsymons authored Mar 18, 2024
1 parent 9820385 commit 5643fac
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
3 changes: 2 additions & 1 deletion DuckDuckGo/Feedback/VPNMetadataCollector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct VPNMetadata: Encodable {

func toPrettyPrintedJSON() -> String? {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

guard let encodedMetadata = try? encoder.encode(self) else {
assertionFailure("Failed to encode metadata")
Expand All @@ -81,6 +81,7 @@ struct VPNMetadata: Encodable {

func toBase64() -> String {
let encoder = JSONEncoder()
encoder.outputFormatting = [.sortedKeys]

do {
let encodedMetadata = try encoder.encode(self)
Expand Down
61 changes: 56 additions & 5 deletions DuckDuckGo/NetworkProtectionDebugViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ final class NetworkProtectionDebugViewController: UITableViewController {
Sections.networkPath: "Network Path",
Sections.lastDisconnectError: "Last Disconnect Error",
Sections.connectionTest: "Connection Test",
Sections.vpnConfiguration: "VPN Configuration"

Sections.vpnConfiguration: "VPN Configuration",
Sections.vpnMetadata: "VPN Metadata",
]

enum Sections: Int, CaseIterable {
Expand All @@ -59,13 +59,12 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case networkPath
case lastDisconnectError
case vpnConfiguration
case vpnMetadata
}

enum ClearDataRows: Int, CaseIterable {

case clearAuthToken
case clearAllVPNData

}

enum DebugFeatureRows: Int, CaseIterable {
Expand Down Expand Up @@ -108,6 +107,11 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case fullProtocolConfigurationData
}

enum MetadataRows: Int, CaseIterable {
case refreshMetadata
case metadataContents
}

// MARK: Properties

private let debugFeatures: NetworkProtectionDebugFeatures
Expand All @@ -118,6 +122,7 @@ final class NetworkProtectionDebugViewController: UITableViewController {
private var lastDisconnectError: String?
private var baseConfigurationData: String?
private var fullProtocolConfigurationData: String?
private var vpnMetadata: VPNMetadata?

private struct ConnectionTestResult {
let interface: String
Expand Down Expand Up @@ -151,6 +156,10 @@ final class NetworkProtectionDebugViewController: UITableViewController {
loadLastDisconnectError()
loadConfigurationData()
startPathMonitor()

Task {
await self.refreshMetadata()
}
}

// MARK: Table View
Expand Down Expand Up @@ -208,13 +217,17 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case .vpnConfiguration:
configure(cell, forConfigurationRow: indexPath.row)

case .vpnMetadata:
configure(cell, forMetadataRow: indexPath.row)

case.none:
break
}

return cell
}

// swiftlint:disable:next cyclomatic_complexity
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch Sections(rawValue: section) {
case .clearData: return ClearDataRows.allCases.count
Expand All @@ -226,6 +239,7 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case .lastDisconnectError: return LastDisconnectErrorRows.allCases.count
case .connectionTest: return ConnectionTestRows.allCases.count + connectionTestResults.count
case .vpnConfiguration: return ConfigurationRows.allCases.count
case .vpnMetadata: return MetadataRows.allCases.count
case .none: return 0

}
Expand Down Expand Up @@ -260,6 +274,8 @@ final class NetworkProtectionDebugViewController: UITableViewController {
}
case .vpnConfiguration:
break
case .vpnMetadata:
didSelectVPNMetadataAction(at: indexPath)
case .none:
break
}
Expand Down Expand Up @@ -548,7 +564,6 @@ final class NetworkProtectionDebugViewController: UITableViewController {
case .none:
assertionFailure("Couldn't map configuration row")
}

}

private func loadConfigurationData() {
Expand Down Expand Up @@ -586,6 +601,42 @@ final class NetworkProtectionDebugViewController: UITableViewController {
}
}

// MARK: - VPN Metadata

private func configure(_ cell: UITableViewCell, forMetadataRow row: Int) {
cell.textLabel?.font = .systemFont(ofSize: 17)

switch MetadataRows(rawValue: row) {
case .refreshMetadata:
cell.textLabel?.text = "Refresh Metadata"
case .metadataContents:
cell.textLabel?.font = .monospacedSystemFont(ofSize: 13.0, weight: .regular)
cell.textLabel?.text = vpnMetadata?.toPrettyPrintedJSON() ?? "No Metadata"
case .none:
assertionFailure("Couldn't map configuration row")
}
}

private func didSelectVPNMetadataAction(at indexPath: IndexPath) {
switch MetadataRows(rawValue: indexPath.row) {
case .refreshMetadata:
Task {
await refreshMetadata()
}
case .metadataContents:
break
case .none:
break
}
}

@MainActor
private func refreshMetadata() async {
let collector = DefaultVPNMetadataCollector()
self.vpnMetadata = await collector.collectMetadata()
self.tableView.reloadData()
}

// MARK: Selection Actions

private func clearAuthToken() {
Expand Down

0 comments on commit 5643fac

Please sign in to comment.