From b6aed36c2cb01f6426bb99e52cdc2865bf097faa Mon Sep 17 00:00:00 2001 From: Jamil Date: Fri, 3 Jan 2025 18:48:06 -0800 Subject: [PATCH] feat(apple): Set account slug from Swift -> Rust to hydrate Sentry with (#7662) - Refactor Telemetry module to expose firezoneId and accountSlug for easier access in the Adapter module - Set accountSlug to WrappedSession.connect for hydrating the Rust sentry context --- rust/connlib/clients/apple/src/lib.rs | 3 ++ .../Firezone/Application/FirezoneApp.swift | 2 +- .../FirezoneKit/Helpers/Telemetry.swift | 42 +++++++++++-------- .../FirezoneKit/Managers/TunnelManager.swift | 4 +- .../FirezoneNetworkExtension/Adapter.swift | 5 +-- .../PacketTunnelProvider.swift | 6 +-- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/rust/connlib/clients/apple/src/lib.rs b/rust/connlib/clients/apple/src/lib.rs index 2a52b89aa..65963510e 100644 --- a/rust/connlib/clients/apple/src/lib.rs +++ b/rust/connlib/clients/apple/src/lib.rs @@ -57,6 +57,7 @@ mod ffi { api_url: String, token: String, device_id: String, + account_slug: String, device_name_override: Option, os_version_override: Option, log_dir: String, @@ -236,6 +237,7 @@ impl WrappedSession { api_url: String, token: String, device_id: String, + account_slug: String, device_name_override: Option, os_version_override: Option, log_dir: String, @@ -246,6 +248,7 @@ impl WrappedSession { let mut telemetry = Telemetry::default(); telemetry.start(&api_url, RELEASE, APPLE_DSN); telemetry.set_firezone_id(device_id.clone()); + telemetry.set_account_slug(account_slug); init_logging(log_dir.into(), log_filter)?; install_rustls_crypto_provider(); diff --git a/swift/apple/Firezone/Application/FirezoneApp.swift b/swift/apple/Firezone/Application/FirezoneApp.swift index b1c13fb6a..ffcd97db8 100644 --- a/swift/apple/Firezone/Application/FirezoneApp.swift +++ b/swift/apple/Firezone/Application/FirezoneApp.swift @@ -86,7 +86,7 @@ struct FirezoneApp: App { let id = try await FirezoneId.createIfMissing() // Hydrate telemetry userId with our firezone id - Telemetry.setFirezoneId(id.uuid.uuidString) + Telemetry.firezoneId = id.uuid.uuidString } if let store = store { diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift index 80f437bde..02ba33bcc 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/Telemetry.swift @@ -11,8 +11,26 @@ public enum Telemetry { // the existing one. So we need to collect these fields from various codepaths // during initialization / sign in so we can build a new User object any time // one of these is updated. - private static var userId: String? - private static var accountSlug: String? + private static var _firezoneId: String? + private static var _accountSlug: String? + public static var firezoneId: String? { + set { + self._firezoneId = newValue + updateUser(id: self._firezoneId, slug: self._accountSlug) + } + get { + return self._firezoneId + } + } + public static var accountSlug: String? { + set { + self._accountSlug = newValue + updateUser(id: self._firezoneId, slug: self._accountSlug) + } + get { + return self._accountSlug + } + } public static func start() { SentrySDK.start { options in @@ -53,27 +71,17 @@ public enum Telemetry { SentrySDK.capture(error: err) } - public static func setFirezoneId(_ id: String?) { - self.userId = id - updateUser() - } - - public static func setAccountSlug(_ slug: String?) { - self.accountSlug = slug - updateUser() - } - - private static func updateUser() { - guard let userId, - let accountSlug + private static func updateUser(id: String?, slug: String?) { + guard let id, + let slug else { return } SentrySDK.configureScope { configuration in // Matches the format we use in rust/telemetry/lib.rs - let user = User(userId: userId) - user.data = ["account_slug": accountSlug] + let user = User(userId: id) + user.data = ["account_slug": slug] configuration.setUser(user) } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift index 43e2d0a88..bf91caa87 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Managers/TunnelManager.swift @@ -190,9 +190,7 @@ public class TunnelManager { // Configure our Telemetry environment Telemetry.setEnvironmentOrClose(settings.apiURL) - Telemetry.setAccountSlug( - providerConfiguration[TunnelManagerKeys.accountSlug] - ) + Telemetry.accountSlug = providerConfiguration[TunnelManagerKeys.accountSlug] // Share what we found with our caller callback(status, settings, actorName) diff --git a/swift/apple/FirezoneNetworkExtension/Adapter.swift b/swift/apple/FirezoneNetworkExtension/Adapter.swift index d38300f09..dfa666083 100644 --- a/swift/apple/FirezoneNetworkExtension/Adapter.swift +++ b/swift/apple/FirezoneNetworkExtension/Adapter.swift @@ -137,14 +137,13 @@ class Adapter { let jsonEncoder = JSONEncoder() jsonEncoder.keyEncodingStrategy = .convertToSnakeCase - let firezoneId = try await FirezoneId.load() - // Grab a session pointer let session = try WrappedSession.connect( apiURL, "\(token)", - "\(firezoneId!)", + "\(Telemetry.firezoneId!)", + "\(Telemetry.accountSlug!)", DeviceMetadata.getDeviceName(), DeviceMetadata.getOSVersion(), connlibLogFolderPath, diff --git a/swift/apple/FirezoneNetworkExtension/PacketTunnelProvider.swift b/swift/apple/FirezoneNetworkExtension/PacketTunnelProvider.swift index 2c7c58540..36d42ab36 100644 --- a/swift/apple/FirezoneNetworkExtension/PacketTunnelProvider.swift +++ b/swift/apple/FirezoneNetworkExtension/PacketTunnelProvider.swift @@ -48,7 +48,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let id = try await FirezoneId.createIfMissing() // Hydrate the telemetry userId with our firezone id - Telemetry.setFirezoneId(id.uuid.uuidString) + Telemetry.firezoneId = id.uuid.uuidString let passedToken = options?["token"] as? String let keychainToken = try await Token.load() @@ -87,9 +87,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } // Hydrate telemetry account slug - Telemetry.setAccountSlug( - providerConfiguration[TunnelManagerKeys.accountSlug] - ) + Telemetry.accountSlug = providerConfiguration[TunnelManagerKeys.accountSlug] let internetResourceEnabled: Bool = if let internetResourceEnabledJSON = providerConfiguration[TunnelManagerKeys.internetResourceEnabled]?.data(using: .utf8) { (try? JSONDecoder().decode(Bool.self, from: internetResourceEnabledJSON )) ?? false