Improve error messaging when installing the Privileged Helper Tool (#103)

* Improve error messaging when installing the Privileged Helper Tool

* Squash those linter warnings

* Fix typo
This commit is contained in:
Nindi Gill 2023-10-29 20:42:12 +11:00 committed by GitHub
parent 29238d1959
commit c5aea7eddc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 35 deletions

View file

@ -10,7 +10,7 @@ import Foundation
/// Helper struct to update a Property List key-pair value.
struct PropertyListUpdater {
/// Edit a key-pair value in a Property List.
/// Update a key-pair value in a Property List.
///
/// - Parameters:
/// - url: The URL of the property list to be updated.

View file

@ -10,4 +10,5 @@ import SwiftUI
enum FirmwareAlertType: String {
case compatibility = "Compatiblity"
case helperTool = "Helper Tool"
case error = "Error"
}

View file

@ -10,4 +10,5 @@ enum InstallerAlertType: String {
case helperTool = "Helper Tool"
case fullDiskAccess = "Full Disk Access"
case cacheDirectory = "Cache Directory"
case error = "Error"
}

View file

@ -23,6 +23,7 @@ struct ListRowFirmware: View {
@State private var showAlert: Bool = false
@State private var showSavePanel: Bool = false
@State private var downloading: Bool = false
@State private var error: Error?
private let length: CGFloat = 48
private let spacing: CGFloat = 5
private let padding: CGFloat = 3
@ -34,6 +35,14 @@ struct ListRowFirmware: View {
return "This macOS Firmware download cannot be used to restore macOS on this \(architecture.description) Mac.\n\nAre you sure you want to continue?"
}
private var errorMessage: String {
if let error: BlessError = error as? BlessError {
return error.description
}
return error?.localizedDescription ?? ""
}
var body: some View {
HStack {
@ -68,10 +77,16 @@ struct ListRowFirmware: View {
case .helperTool:
return Alert(
title: Text("Privileged Helper Tool not installed!"),
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when downloading macOS Firmwares"),
primaryButton: .default(Text("Install...")) { installPrivilegedHelperTool() },
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when downloading macOS Firmwares."),
primaryButton: .default(Text("Install...")) { Task { installPrivilegedHelperTool() } },
secondaryButton: .default(Text("Cancel"))
)
case .error:
return Alert(
title: Text("An error has occured!"),
message: Text(errorMessage),
dismissButton: .default(Text("OK"))
)
}
}
.onChange(of: showSavePanel) { boolean in
@ -132,7 +147,13 @@ struct ListRowFirmware: View {
}
private func installPrivilegedHelperTool() {
try? PrivilegedHelperManager.shared.authorizeAndBless()
do {
try PrivilegedHelperManager.shared.authorizeAndBless()
} catch {
self.error = error
alertType = .error
showAlert = true
}
}
}

View file

@ -48,6 +48,7 @@ struct ListRowInstaller: View {
@State private var showOpenPanel: Bool = false
@State private var exports: [InstallerExportType] = []
@State private var volume: InstallerVolume?
@State private var error: Error?
private let length: CGFloat = 48
private let spacing: CGFloat = 5
private let padding: CGFloat = 3
@ -62,6 +63,14 @@ struct ListRowInstaller: View {
private var cacheDirectoryMessage: String {
"The cache directory has incorrect ownership and/or permissions, which will cause issues caching macOS Installers.\n\nRepair the cache directory ownership and/or permissions and try again."
}
private var errorMessage: String {
if let error: BlessError = error as? BlessError {
return error.description
}
return error?.localizedDescription ?? ""
}
var body: some View {
HStack {
@ -97,36 +106,7 @@ struct ListRowInstaller: View {
.clipShape(Capsule())
}
.alert(isPresented: $showAlert) {
switch alertType {
case .compatibility:
return Alert(
title: Text("macOS Installer not compatible!"),
message: Text(compatibilityMessage),
primaryButton: .default(Text("Cancel")),
secondaryButton: .default(Text("Continue")) { Task { validate() } }
)
case .helperTool:
return Alert(
title: Text("Privileged Helper Tool not installed!"),
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when creating macOS Installers."),
primaryButton: .default(Text("Install...")) { installPrivilegedHelperTool() },
secondaryButton: .default(Text("Cancel"))
)
case .fullDiskAccess:
return Alert(
title: Text("Full Disk Access required!"),
message: Text("Mist requires Full Disk Access to perform Administrator tasks when creating macOS Installers."),
primaryButton: .default(Text("Allow...")) { openFullDiskAccessPreferences() },
secondaryButton: .default(Text("Cancel"))
)
case .cacheDirectory:
return Alert(
title: Text("Cache directory settings incorrect!"),
message: Text(cacheDirectoryMessage),
primaryButton: .default(Text("Repair...")) { Task { try await repairCacheDirectoryOwnershipAndPermissions() } },
secondaryButton: .default(Text("Cancel"))
)
}
alert(for: alertType)
}
.onChange(of: showOpenPanel) { boolean in
@ -309,7 +289,13 @@ struct ListRowInstaller: View {
}
private func installPrivilegedHelperTool() {
try? PrivilegedHelperManager.shared.authorizeAndBless()
do {
try PrivilegedHelperManager.shared.authorizeAndBless()
} catch {
self.error = error
alertType = .error
showAlert = true
}
}
private func openFullDiskAccessPreferences() {
@ -326,6 +312,45 @@ struct ListRowInstaller: View {
let ownerAccountName: String = NSUserName()
try await FileAttributesUpdater.update(url: url, ownerAccountName: ownerAccountName)
}
private func alert(for alertType: InstallerAlertType) -> Alert {
switch alertType {
case .compatibility:
return Alert(
title: Text("macOS Installer not compatible!"),
message: Text(compatibilityMessage),
primaryButton: .default(Text("Cancel")),
secondaryButton: .default(Text("Continue")) { Task { validate() } }
)
case .helperTool:
return Alert(
title: Text("Privileged Helper Tool not installed!"),
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when creating macOS Installers."),
primaryButton: .default(Text("Install...")) { Task { installPrivilegedHelperTool() } },
secondaryButton: .default(Text("Cancel"))
)
case .fullDiskAccess:
return Alert(
title: Text("Full Disk Access required!"),
message: Text("Mist requires Full Disk Access to perform Administrator tasks when creating macOS Installers."),
primaryButton: .default(Text("Allow...")) { openFullDiskAccessPreferences() },
secondaryButton: .default(Text("Cancel"))
)
case .cacheDirectory:
return Alert(
title: Text("Cache directory settings incorrect!"),
message: Text(cacheDirectoryMessage),
primaryButton: .default(Text("Repair...")) { Task { try await repairCacheDirectoryOwnershipAndPermissions() } },
secondaryButton: .default(Text("Cancel"))
)
case .error:
return Alert(
title: Text("An error has occured!"),
message: Text(errorMessage),
dismissButton: .default(Text("OK"))
)
}
}
}
struct ListRowInstaller_Previews: PreviewProvider {