Skip to content

Commit

Permalink
Add error pixels for Subscription keychain access errors (#3147)
Browse files Browse the repository at this point in the history
Task/Issue URL:
https://app.asana.com/0/1201037661562251/1208146974665104/f

**Description**:
Add missing pixel reporting for subscription related keychain access
errors.
  • Loading branch information
miasma13 authored Aug 28, 2024
1 parent 60df756 commit da7daf0
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 13 deletions.
6 changes: 5 additions & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@
1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 1EA7B8D42B7E078C000330A4 /* Subscription */; };
1ED910D52B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; };
1ED910D62B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; };
1EFA1A072C7C7F0E0099F508 /* PrivacyProPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */; };
1EFA1A082C7C7F0F0099F508 /* PrivacyProPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */; };
310E79BF294A19A8007C49E8 /* FireproofingReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310E79BE294A19A8007C49E8 /* FireproofingReferenceTests.swift */; };
311B262728E73E0A00FD181A /* TabShadowConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311B262628E73E0A00FD181A /* TabShadowConfig.swift */; };
31267C692B640C4200FEF811 /* DataBrokerProtectionFeatureGatekeeper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C5FFB82AF64D120008A79F /* DataBrokerProtectionFeatureGatekeeper.swift */; };
Expand Down Expand Up @@ -11414,6 +11416,7 @@
31A83FB72BE28D8A00F74E67 /* UserText+DBP.swift in Sources */,
F1D042942BFBA12300A31506 /* DataBrokerProtectionSettings+Environment.swift in Sources */,
F1C70D822BFF510000599292 /* SubscriptionEnvironment+Default.swift in Sources */,
1EFA1A072C7C7F0E0099F508 /* PrivacyProPixel.swift in Sources */,
9D9AE91D2AAA3B450026E7DC /* DuckDuckGoDBPBackgroundAgentAppDelegate.swift in Sources */,
9D9AE9212AAA3B450026E7DC /* UserText.swift in Sources */,
31ECDA132BED339600AE679F /* DataBrokerAuthenticationManagerBuilder.swift in Sources */,
Expand All @@ -11430,6 +11433,7 @@
31A83FB82BE28D8A00F74E67 /* UserText+DBP.swift in Sources */,
F1D042952BFBA12300A31506 /* DataBrokerProtectionSettings+Environment.swift in Sources */,
F1C70D832BFF510000599292 /* SubscriptionEnvironment+Default.swift in Sources */,
1EFA1A082C7C7F0F0099F508 /* PrivacyProPixel.swift in Sources */,
9D9AE91E2AAA3B450026E7DC /* DuckDuckGoDBPBackgroundAgentAppDelegate.swift in Sources */,
9D9AE9222AAA3B450026E7DC /* UserText.swift in Sources */,
31ECDA142BED339600AE679F /* DataBrokerAuthenticationManagerBuilder.swift in Sources */,
Expand Down Expand Up @@ -13594,7 +13598,7 @@
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 188.0.0;
version = 188.1.0;
};
};
9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "faf25f57d1d61ff855216178c454616031585c07",
"version" : "188.0.0"
"revision" : "ce1b7228a38d2b18525590256051a012109cfee6",
"version" : "188.1.0"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
let subscriptionEndpointService = DefaultSubscriptionEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
let authEndpointService = DefaultAuthEndpointService(currentServiceEnvironment: subscriptionEnvironment.serviceEnvironment)
let accountManager = DefaultAccountManager(accessTokenStorage: tokenStore,
entitlementsCache: entitlementsCache,
subscriptionEndpointService: subscriptionEndpointService,
authEndpointService: authEndpointService)
entitlementsCache: entitlementsCache,
subscriptionEndpointService: subscriptionEndpointService,
authEndpointService: authEndpointService)

let entitlementsCheck = {
await accountManager.hasEntitlement(forProductName: .networkProtection, cachePolicy: .reloadIgnoringLocalCacheData)
Expand All @@ -474,6 +474,7 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
entitlementCheck: entitlementsCheck)

setupPixels()
accountManager.delegate = self
observeServerChanges()
observeStatusUpdateRequests()
}
Expand Down Expand Up @@ -659,3 +660,11 @@ final class DefaultWireGuardInterface: WireGuardInterface {
wgSetLogger(context, logFunction)
}
}

extension MacPacketTunnelProvider: AccountManagerKeychainAccessDelegate {

public func accountManagerKeychainAccessFailed(accessType: AccountKeychainAccessType, error: AccountKeychainAccessError) {
PixelKit.fire(PrivacyProErrorPixel.privacyProKeychainAccessError(accessType: accessType, accessError: error),
frequency: .dailyAndCount)
}
}
27 changes: 27 additions & 0 deletions DuckDuckGo/Statistics/PrivacyProPixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//

import Foundation
import Subscription
import PixelKit

// swiftlint:disable private_over_fileprivate
Expand Down Expand Up @@ -119,3 +120,29 @@ enum PrivacyProPixel: PixelKitEventV2 {
return nil
}
}

enum PrivacyProErrorPixel: PixelKitEventV2 {

case privacyProKeychainAccessError(accessType: AccountKeychainAccessType, accessError: AccountKeychainAccessError)

var name: String {
switch self {
case .privacyProKeychainAccessError: return "m_mac_privacy-pro_keychain_access_error"
}
}

var parameters: [String: String]? {
switch self {
case .privacyProKeychainAccessError(let accessType, let accessError):
return [
"type": accessType.rawValue,
"error": accessError.errorDescription
]
}
}

var error: (any Error)? {
return nil
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import Foundation
import Subscription
import Common
import PixelKit

extension DefaultSubscriptionManager {

Expand Down Expand Up @@ -53,5 +54,15 @@ extension DefaultSubscriptionManager {
authEndpointService: authEndpointService,
subscriptionEnvironment: subscriptionEnvironment)
}

accountManager.delegate = self
}
}

extension DefaultSubscriptionManager: AccountManagerKeychainAccessDelegate {

public func accountManagerKeychainAccessFailed(accessType: AccountKeychainAccessType, error: AccountKeychainAccessError) {
PixelKit.fire(PrivacyProErrorPixel.privacyProKeychainAccessError(accessType: accessType, accessError: error),
frequency: .dailyAndCount)
}
}
17 changes: 13 additions & 4 deletions DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import os.log
@objc(Application)
final class DuckDuckGoVPNApplication: NSApplication {

public let accountManager: AccountManager
public var accountManager: AccountManager
private let _delegate: DuckDuckGoVPNAppDelegate

override init() {
Expand All @@ -58,9 +58,9 @@ final class DuckDuckGoVPNApplication: NSApplication {
settings: UserDefaultsCacheSettings(defaultExpirationInterval: .minutes(20)))
let accessTokenStorage = SubscriptionTokenKeychainStorage(keychainType: .dataProtection(.named(subscriptionAppGroup)))
accountManager = DefaultAccountManager(accessTokenStorage: accessTokenStorage,
entitlementsCache: entitlementsCache,
subscriptionEndpointService: subscriptionEndpointService,
authEndpointService: authEndpointService)
entitlementsCache: entitlementsCache,
subscriptionEndpointService: subscriptionEndpointService,
authEndpointService: authEndpointService)

_delegate = DuckDuckGoVPNAppDelegate(accountManager: accountManager,
accessTokenStorage: accessTokenStorage,
Expand All @@ -69,6 +69,7 @@ final class DuckDuckGoVPNApplication: NSApplication {

setupPixelKit()
self.delegate = _delegate
accountManager.delegate = _delegate

#if DEBUG
if accountManager.accessToken != nil {
Expand Down Expand Up @@ -436,3 +437,11 @@ final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate {
}
}
}

extension DuckDuckGoVPNAppDelegate: AccountManagerKeychainAccessDelegate {

public func accountManagerKeychainAccessFailed(accessType: AccountKeychainAccessType, error: AccountKeychainAccessError) {
PixelKit.fire(PrivacyProErrorPixel.privacyProKeychainAccessError(accessType: accessType, accessError: error),
frequency: .dailyAndCount)
}
}
2 changes: 1 addition & 1 deletion LocalPackages/DataBrokerProtection/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ let package = Package(
targets: ["DataBrokerProtection"])
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.0.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.1.0"),
.package(path: "../SwiftUIExtensions"),
.package(path: "../XPCHelper"),
],
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/NetworkProtectionMac/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let package = Package(
.library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]),
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.0.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.1.0"),
.package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.3"),
.package(path: "../AppLauncher"),
.package(path: "../UDSHelper"),
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/SubscriptionUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let package = Package(
targets: ["SubscriptionUI"]),
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.0.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "188.1.0"),
.package(path: "../SwiftUIExtensions")
],
targets: [
Expand Down

0 comments on commit da7daf0

Please sign in to comment.