Skip to content

Commit

Permalink
Improve thread credentials sharing logging (#3070)
Browse files Browse the repository at this point in the history
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
  • Loading branch information
bgoncal authored Sep 30, 2024
1 parent 635bbd9 commit ae007eb
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 17 deletions.
16 changes: 16 additions & 0 deletions HomeAssistant.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,8 @@
42AA4C842C2DACAD00EA2E99 /* UIImage+Circle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42AA4C832C2DACAD00EA2E99 /* UIImage+Circle.swift */; };
42B1A7432C11E65100904548 /* WatchAssistService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B1A7422C11E65100904548 /* WatchAssistService.swift */; };
42B1A7452C1305C300904548 /* WatchCommunicatorService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B1A7442C1305C300904548 /* WatchCommunicatorService.swift */; };
42B942F62CAA1E5600E36E02 /* PayloadConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B942F52CAA1E5600E36E02 /* PayloadConstants.swift */; };
42B942F82CAA1ECC00E36E02 /* PayloadConstants.test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B942F72CAA1ECC00E36E02 /* PayloadConstants.test.swift */; };
42B94BDE2B9606CD00DEE060 /* AssistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B94BDB2B9606CD00DEE060 /* AssistViewModel.swift */; };
42B94BDF2B9606CD00DEE060 /* AssistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B94BDC2B9606CD00DEE060 /* AssistView.swift */; };
42B94BEC2B96083C00DEE060 /* AssistModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42B94BE72B9607D100DEE060 /* AssistModel.swift */; };
Expand Down Expand Up @@ -1946,6 +1948,8 @@
42AA4C832C2DACAD00EA2E99 /* UIImage+Circle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Circle.swift"; sourceTree = "<group>"; };
42B1A7422C11E65100904548 /* WatchAssistService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchAssistService.swift; sourceTree = "<group>"; };
42B1A7442C1305C300904548 /* WatchCommunicatorService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchCommunicatorService.swift; sourceTree = "<group>"; };
42B942F52CAA1E5600E36E02 /* PayloadConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadConstants.swift; sourceTree = "<group>"; };
42B942F72CAA1ECC00E36E02 /* PayloadConstants.test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadConstants.test.swift; sourceTree = "<group>"; };
42B94BDA2B9606CD00DEE060 /* AssistChatItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssistChatItem.swift; sourceTree = "<group>"; };
42B94BDB2B9606CD00DEE060 /* AssistViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssistViewModel.swift; sourceTree = "<group>"; };
42B94BDC2B9606CD00DEE060 /* AssistView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssistView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3003,6 +3007,7 @@
11AD2E2A2528FDB700FBC437 /* WebView */ = {
isa = PBXGroup;
children = (
42B942F42CAA1E4400E36E02 /* Payload */,
42BE698B2C4691E000745ECA /* Views */,
11DE822F24FAE66F00E636B8 /* UIWindow+Additions.swift */,
113FB1122515A065000AC680 /* ScaleFactorMutator.swift */,
Expand Down Expand Up @@ -3412,6 +3417,7 @@
isa = PBXGroup;
children = (
39A32EE02C0E380600985722 /* CredentialsSharing */,
42B942F72CAA1ECC00E36E02 /* PayloadConstants.test.swift */,
);
path = Thread;
sourceTree = "<group>";
Expand Down Expand Up @@ -3839,6 +3845,14 @@
path = Mocks;
sourceTree = "<group>";
};
42B942F42CAA1E4400E36E02 /* Payload */ = {
isa = PBXGroup;
children = (
42B942F52CAA1E5600E36E02 /* PayloadConstants.swift */,
);
path = Payload;
sourceTree = "<group>";
};
42B94BD92B9606CD00DEE060 /* Assist */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -6561,6 +6575,7 @@
42F1DA6D2B4ED29C002729BC /* CarPlayPaginatedListTemplate.swift in Sources */,
11DA6B4B27137A60008ADFAF /* InputAccessoryView.swift in Sources */,
42FCD0142B9B29740057783F /* ThreadCredentialDetailsView.swift in Sources */,
42B942F62CAA1E5600E36E02 /* PayloadConstants.swift in Sources */,
42E95C552CA44FC90010ECE3 /* SafariWebView.swift in Sources */,
11A71C6D24A4641600D9565F /* ZoneManagerEvent.swift in Sources */,
42FCD0122B9B29740057783F /* ThreadCredentialsManagementView+Build.swift in Sources */,
Expand Down Expand Up @@ -6737,6 +6752,7 @@
116D3A4627252C3200EF5D21 /* OnboardingAuthStepConfig.test.swift in Sources */,
420F53E52C4E67FC003C8415 /* MockLocalNotificationDispatcher.swift in Sources */,
11C95E3628BC20EA00171F1C /* OnboardingAuthLoginViewController.test.swift in Sources */,
42B942F82CAA1ECC00E36E02 /* PayloadConstants.test.swift in Sources */,
117D8A0A24A9381F00580913 /* UIColor+CSSRGB.test.swift in Sources */,
425573DA2B57DDE000145217 /* WindowScenesManager.test.swift in Sources */,
11ED43A027279AFA00B5FD45 /* OnboardingAuthLoginImpl.test.swift in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions Sources/App/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ Home Assistant is free and open source home automation software with a focus on
"thread.save_credential.fail.alert.message" = "Failed to save thread network credential.";
"thread.save_credential.fail.alert.title" = "Failed to save thread network credential, error: %@";
"thread.save_credential.fail.continue.button" = "Continue";
"thread.store_in_keychain.error.generic.body" = "Failed to store thread credential in keychain, check logs for more information.";
"thread.store_in_keychain.error.message" = "Failed to store thread credential in keychain, error: %@";
"thread.store_in_keychain.error.hexadecimal_conversion.body" = "Failed to convert input to hexadecimal while storing thread credential in keychain";
"thread.store_in_keychain.error.title" = "Operation failed";
"thread.transter_to_apple.title" = "Transfer to Apple Keychain";
Expand Down Expand Up @@ -996,4 +996,4 @@ Home Assistant is free and open source home automation software with a focus on
"widgets.scripts.description" = "Run Scripts";
"widgets.scripts.not_configured" = "No Scripts Configured";
"widgets.scripts.title" = "Scripts";
"yes_label" = "Yes";
"yes_label" = "Yes";
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class ThreadTransferCredentialToKeychainViewModel: ThreadCredentialsSharin
Current.Log.error("Failed to store thread credential in keychain: \(error.localizedDescription)")
alertType = .error(
title: L10n.Thread.StoreInKeychain.Error.title,
message: L10n.Thread.StoreInKeychain.Error.Generic.body
message: L10n.Thread.StoreInKeychain.Error.message(error.localizedDescription)
)
}
showAlert = true
Expand Down
7 changes: 7 additions & 0 deletions Sources/App/WebView/Payload/PayloadConstants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Foundation

enum PayloadConstants: String {
case macExtendedAddress = "mac_extended_address"
case activeOperationalDataset = "active_operational_dataset"
case extendedPanId = "extended_pan_id"
}
30 changes: 21 additions & 9 deletions Sources/App/WebView/WebViewExternalMessageHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,28 @@ final class WebViewExternalMessageHandler {
private func matterComissioningHandler(incomingMessage: WebSocketMessage) {
// So we avoid conflicting credentials (or absence) between servers
cleanPreferredThreadCredentials()
let preferredNetWorkMacExtendedAddress = incomingMessage
.Payload?[PayloadConstants.macExtendedAddress.rawValue] as? String
let preferredNetWorkActiveOperationalDataset = incomingMessage
.Payload?[PayloadConstants.activeOperationalDataset.rawValue] as? String
let preferredNetworkExtendedPANID = incomingMessage.Payload?[PayloadConstants.extendedPanId.rawValue] as? String

if let preferredNetWorkMacExtendedAddress = incomingMessage.Payload?["mac_extended_address"] as? String,
let preferredNetWorkActiveOperationalDataset = incomingMessage
.Payload?["active_operational_dataset"] as? String,
let preferredNetworkExtendedPANID = incomingMessage.Payload?["extended_pan_id"] as? String {
Current.Log
.verbose(
"Matter comission received preferredNetWorkMacExtendedAddress from frontend: \(String(describing: preferredNetWorkMacExtendedAddress))"
)
Current.Log
.verbose(
"Matter comission received preferredNetWorkActiveOperationalDataset from frontend: \(String(describing: preferredNetWorkActiveOperationalDataset))"
)
Current.Log
.verbose(
"Matter comission received preferredNetworkExtendedPANID from frontend: \(String(describing: preferredNetworkExtendedPANID))"
)

if let preferredNetWorkMacExtendedAddress, !preferredNetWorkMacExtendedAddress.isEmpty,
let preferredNetWorkActiveOperationalDataset, !preferredNetWorkActiveOperationalDataset.isEmpty,
let preferredNetworkExtendedPANID, !preferredNetworkExtendedPANID.isEmpty {
// This information will be used in 'MatterRequestHandler'
Current.settingsStore
.matterLastPreferredNetWorkMacExtendedAddress = preferredNetWorkMacExtendedAddress
Expand All @@ -266,11 +283,6 @@ final class WebViewExternalMessageHandler {
Current.settingsStore
.matterLastPreferredNetWorkExtendedPANID = preferredNetworkExtendedPANID

Current.Log
.verbose(
"Matter comission requested using preferredNetWorkMacExtendedAddress: \(String(describing: preferredNetWorkMacExtendedAddress)) and preferredNetWorkActiveOperationalDataset: \(String(describing: preferredNetWorkActiveOperationalDataset))"
)

// Saving credential in keychain before moving forward as required, docs: https://developer.apple.com/documentation/mattersupport/matteradddeviceextensionrequesthandler/selectthreadnetwork(from:)
Current.matter.threadClientService.saveCredential(
macExtendedAddress: preferredNetWorkMacExtendedAddress,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Extensions/Matter/MatterRequestHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class MatterRequestHandler: MatterAddDeviceExtensionRequestHandler {
)
Current.Log
.verbose(
"Preferred Extended PAN ID: \(String(describing: UInt64(Current.settingsStore.matterLastPreferredNetWorkExtendedPANID ?? "", radix: 16)))"
"Preferred Extended PAN ID (UInt64): \(String(describing: UInt64(Current.settingsStore.matterLastPreferredNetWorkExtendedPANID ?? "", radix: 16)))"
)
if let matterLastPreferredNetWorkExtendedPANID = Current.settingsStore.matterLastPreferredNetWorkExtendedPANID,
let preferredExtendedPANID = UInt64(matterLastPreferredNetWorkExtendedPANID, radix: 16),
Expand Down
8 changes: 4 additions & 4 deletions Sources/Shared/Resources/Swiftgen/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2369,12 +2369,12 @@ public enum L10n {
}
public enum StoreInKeychain {
public enum Error {
/// Failed to store thread credential in keychain, error: %@
public static func message(_ p1: Any) -> String {
return L10n.tr("Localizable", "thread.store_in_keychain.error.message", String(describing: p1))
}
/// Operation failed
public static var title: String { return L10n.tr("Localizable", "thread.store_in_keychain.error.title") }
public enum Generic {
/// Failed to store thread credential in keychain, check logs for more information.
public static var body: String { return L10n.tr("Localizable", "thread.store_in_keychain.error.generic.body") }
}
public enum HexadecimalConversion {
/// Failed to convert input to hexadecimal while storing thread credential in keychain
public static var body: String { return L10n.tr("Localizable", "thread.store_in_keychain.error.hexadecimal_conversion.body") }
Expand Down
16 changes: 16 additions & 0 deletions Tests/App/Thread/PayloadConstants.test.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@testable import HomeAssistant
import Testing

struct PayloadConstants_test {
@Test func validateWebViewMessageHandlerPayloadConstants() async throws {
#expect(
PayloadConstants.macExtendedAddress.rawValue == "mac_extended_address",
"Wrong value for macExtendedAddress"
)
#expect(PayloadConstants.extendedPanId.rawValue == "extended_pan_id", "Wrong value for extendedPanId")
#expect(
PayloadConstants.activeOperationalDataset.rawValue == "active_operational_dataset",
"Wrong value for activeOperationalDataset"
)
}
}

0 comments on commit ae007eb

Please sign in to comment.