diff --git a/pass.xcodeproj/project.pbxproj b/pass.xcodeproj/project.pbxproj index a96d099..1995a8e 100644 --- a/pass.xcodeproj/project.pbxproj +++ b/pass.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 3032327422C7F710009EBD9C /* KeyFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3032327322C7F710009EBD9C /* KeyFileManager.swift */; }; 3032328A22C9FBA2009EBD9C /* KeyFileManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3032328922C9FBA2009EBD9C /* KeyFileManagerTest.swift */; }; 3032328E22CBD4CD009EBD9C /* CryptographicKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3032328D22CBD4CD009EBD9C /* CryptographicKeys.swift */; }; + 3066AD6823EE0D6500F65535 /* PGPKeyImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3066AD6723EE0D6500F65535 /* PGPKeyImporter.swift */; }; 30697C2A21F63C5A0064FCAC /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30697C2321F63C580064FCAC /* NotificationNames.swift */; }; 30697C2B21F63C5A0064FCAC /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30697C2421F63C590064FCAC /* Globals.swift */; }; 30697C2C21F63C5A0064FCAC /* FileManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30697C2521F63C590064FCAC /* FileManagerExtension.swift */; }; @@ -135,7 +136,7 @@ DC917BE11E2E8231000FDF54 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC917BDF1E2E8231000FDF54 /* LaunchScreen.storyboard */; }; DC962CDF1E4B62C10033B5D8 /* AboutTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC962CDE1E4B62C10033B5D8 /* AboutTableViewController.swift */; }; DCA0499A1E335CC800522E8F /* GitServerSettingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA049991E335CC800522E8F /* GitServerSettingTableViewController.swift */; }; - DCA0499C1E3362F400522E8F /* PGPKeySettingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA0499B1E3362F400522E8F /* PGPKeySettingTableViewController.swift */; }; + DCA0499C1E3362F400522E8F /* PGPKeyUrlTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA0499B1E3362F400522E8F /* PGPKeyUrlTableViewController.swift */; }; DCAAF7451E2FA66800AB94BC /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAAF7441E2FA66800AB94BC /* SettingsTableViewController.swift */; }; DCC408C71E307DBB00F29B0E /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC408C61E307DBB00F29B0E /* SVProgressHUD.framework */; }; DCC441521E8F6C06008A90C4 /* RawPasswordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC441511E8F6C06008A90C4 /* RawPasswordViewController.swift */; }; @@ -238,6 +239,7 @@ 3032327322C7F710009EBD9C /* KeyFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyFileManager.swift; sourceTree = ""; }; 3032328922C9FBA2009EBD9C /* KeyFileManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyFileManagerTest.swift; sourceTree = ""; }; 3032328D22CBD4CD009EBD9C /* CryptographicKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptographicKeys.swift; sourceTree = ""; }; + 3066AD6723EE0D6500F65535 /* PGPKeyImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PGPKeyImporter.swift; sourceTree = ""; }; 30697C2321F63C580064FCAC /* NotificationNames.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = ""; }; 30697C2421F63C590064FCAC /* Globals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Globals.swift; sourceTree = ""; }; 30697C2521F63C590064FCAC /* FileManagerExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileManagerExtension.swift; sourceTree = ""; }; @@ -358,7 +360,7 @@ DC962CDE1E4B62C10033B5D8 /* AboutTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutTableViewController.swift; sourceTree = ""; }; DCA049951E3357E000522E8F /* SwiftyUserDefaults.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyUserDefaults.framework; path = Carthage/Build/iOS/SwiftyUserDefaults.framework; sourceTree = ""; }; DCA049991E335CC800522E8F /* GitServerSettingTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GitServerSettingTableViewController.swift; sourceTree = ""; }; - DCA0499B1E3362F400522E8F /* PGPKeySettingTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PGPKeySettingTableViewController.swift; sourceTree = ""; }; + DCA0499B1E3362F400522E8F /* PGPKeyUrlTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PGPKeyUrlTableViewController.swift; sourceTree = ""; }; DCA671DE1E7A73B100D3ABE1 /* OneTimePassword.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OneTimePassword.framework; path = Carthage/Build/iOS/OneTimePassword.framework; sourceTree = ""; }; DCA742D91E599ED400D54E16 /* KeychainAccess.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = KeychainAccess.framework; path = Carthage/Build/iOS/KeychainAccess.framework; sourceTree = ""; }; DCAAF7441E2FA66800AB94BC /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = ""; }; @@ -710,18 +712,19 @@ A217ACE31E9BBBBD00A1A6CF /* GitConfigSettingTableViewController.swift */, DCA049991E335CC800522E8F /* GitServerSettingTableViewController.swift */, DCC441531E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift */, - DC8963BF1E38EEB900828B09 /* SSHKeySettingTableViewController.swift */, DC037CA51E4B883900609409 /* OpenSourceComponentsTableViewController.swift */, DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */, DCFB77A81E502FF6008DE471 /* PasswordEditorTableViewController.swift */, DC5734AD1E439AD400D09270 /* PasswordsViewController.swift */, DC5F385A1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift */, - DCA0499B1E3362F400522E8F /* PGPKeySettingTableViewController.swift */, + 3066AD6723EE0D6500F65535 /* PGPKeyImporter.swift */, + DCA0499B1E3362F400522E8F /* PGPKeyUrlTableViewController.swift */, A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */, DCC441511E8F6C06008A90C4 /* RawPasswordViewController.swift */, DCD3C65D1EFB9BB400CBE842 /* SettingsSplitViewController.swift */, DCAAF7441E2FA66800AB94BC /* SettingsTableViewController.swift */, DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */, + DC8963BF1E38EEB900828B09 /* SSHKeySettingTableViewController.swift */, ); path = Controllers; sourceTree = ""; @@ -1381,9 +1384,10 @@ DCC441541E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift in Sources */, A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */, DC8963C01E38EEB900828B09 /* SSHKeySettingTableViewController.swift in Sources */, + 3066AD6823EE0D6500F65535 /* PGPKeyImporter.swift in Sources */, DC193FFA1E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift in Sources */, DCFB77AB1E503729008DE471 /* ContentProvider.swift in Sources */, - DCA0499C1E3362F400522E8F /* PGPKeySettingTableViewController.swift in Sources */, + DCA0499C1E3362F400522E8F /* PGPKeyUrlTableViewController.swift in Sources */, DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */, DC5F385B1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift in Sources */, DCAAF7451E2FA66800AB94BC /* SettingsTableViewController.swift in Sources */, diff --git a/pass/Base.lproj/Main.storyboard b/pass/Base.lproj/Main.storyboard index 8204f7b..3be8433 100644 --- a/pass/Base.lproj/Main.storyboard +++ b/pass/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -505,7 +505,7 @@ - + @@ -617,7 +617,7 @@ - + diff --git a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift index 6daeb18..37a049b 100644 --- a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift +++ b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift @@ -78,37 +78,7 @@ class PGPKeyArmorSettingTableViewController: AutoCellHeightUITableViewController } @IBAction func save(_ sender: Any) { - guard armorPublicKeyTextView.text.isEmpty == false else { - Utils.alert(title: "CannotSave".localize(), message: "SetPublicKey.".localize(), controller: self, completion: nil) - return - } - guard armorPrivateKeyTextView.text.isEmpty == false else { - Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKey.".localize(), controller: self, completion: nil) - return - } - let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertController.Style.alert) - // no - savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertAction.Style.default) { _ in - self.keychain.removeContent(for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = false - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - // yes - savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive) {_ in - // ask for the passphrase - let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertAction.Style.default, handler: {_ in - self.keychain.add(string: alert.textFields?.first?.text, for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = true - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - })) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = self.keychain.get(for: Globals.pgpKeyPassphrase) - textField.isSecureTextEntry = true - }) - self.present(alert, animated: true, completion: nil) - }) - self.present(savePassphraseAlert, animated: true, completion: nil) + savePassphraseDialog() } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { @@ -159,3 +129,36 @@ class PGPKeyArmorSettingTableViewController: AutoCellHeightUITableViewController } } } + +extension PGPKeyArmorSettingTableViewController: PGPKeyImporter { + + static let keySource = PGPKeySource.armor + static let label = "AsciiArmorEncryptedKey".localize() + + func isReadyToUse() -> Bool { + guard !armorPublicKeyTextView.text.isEmpty else { + Utils.alert(title: "CannotSave".localize(), message: "SetPublicKey.".localize(), controller: self, completion: nil) + return false + } + guard !armorPrivateKeyTextView.text.isEmpty else { + Utils.alert(title: "CannotSave".localize(), message: "SetPrivateKey.".localize(), controller: self, completion: nil) + return false + } + return true + } + + func importKeys() throws { + Defaults.pgpKeySource = Self.keySource + + try KeyFileManager.PublicPgp.importKey(from: armorPublicKeyTextView.text ?? "") + try KeyFileManager.PrivatePgp.importKey(from: armorPrivateKeyTextView.text ?? "") + } + + func doAfterImport() { + + } + + func saveImportedKeys() { + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) + } +} diff --git a/pass/Controllers/PGPKeyImporter.swift b/pass/Controllers/PGPKeyImporter.swift new file mode 100644 index 0000000..aa6e6e3 --- /dev/null +++ b/pass/Controllers/PGPKeyImporter.swift @@ -0,0 +1,65 @@ +// +// PGPKeyImporter.swift +// pass +// +// Created by Danny Moesch on 07.02.20. +// Copyright © 2020 Bob Sun. All rights reserved. +// + +import passKit + +protocol PGPKeyImporter { + + static var keySource: PGPKeySource { get } + + static var label: String { get } + + static var menuLabel: String { get } + + func isReadyToUse() -> Bool + + func importKeys() throws + + func doAfterImport() + + func saveImportedKeys() +} + +extension PGPKeyImporter { + + static var menuLabel: String { + if Defaults.pgpKeySource == Self.keySource { + return "✓ \(Self.label)" + } + return Self.label + } +} + +extension PGPKeyImporter where Self: UIViewController { + + func savePassphraseDialog() { + let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertController.Style.alert) + // Do not save the key's passphrase. + savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertAction.Style.default) { _ in + AppKeychain.shared.removeContent(for: Globals.pgpKeyPassphrase) + Defaults.isRememberPGPPassphraseOn = false + self.saveImportedKeys() + }) + // Save the key's passphrase. + savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive) {_ in + // Ask for the passphrase. + let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertController.Style.alert) + alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertAction.Style.default, handler: {_ in + AppKeychain.shared.add(string: alert.textFields?.first?.text, for: Globals.pgpKeyPassphrase) + Defaults.isRememberPGPPassphraseOn = true + self.saveImportedKeys() + })) + alert.addTextField { textField in + textField.text = AppKeychain.shared.get(for: Globals.pgpKeyPassphrase) + textField.isSecureTextEntry = true + } + self.present(alert, animated: true, completion: nil) + }) + self.present(savePassphraseAlert, animated: true, completion: nil) + } +} diff --git a/pass/Controllers/PGPKeySettingTableViewController.swift b/pass/Controllers/PGPKeySettingTableViewController.swift deleted file mode 100644 index 8fa0c93..0000000 --- a/pass/Controllers/PGPKeySettingTableViewController.swift +++ /dev/null @@ -1,69 +0,0 @@ -// -// PGPKeySettingTableViewController.swift -// pass -// -// Created by Mingshen Sun on 21/1/2017. -// Copyright © 2017 Bob Sun. All rights reserved. -// - -import UIKit -import passKit - -class PGPKeySettingTableViewController: AutoCellHeightUITableViewController { - - @IBOutlet weak var pgpPublicKeyURLTextField: UITextField! - @IBOutlet weak var pgpPrivateKeyURLTextField: UITextField! - - let passwordStore = PasswordStore.shared - let keychain = AppKeychain.shared - - override func viewDidLoad() { - super.viewDidLoad() - pgpPublicKeyURLTextField.text = Defaults.pgpPublicKeyURL?.absoluteString - pgpPrivateKeyURLTextField.text = Defaults.pgpPrivateKeyURL?.absoluteString - } - - private func validatePGPKeyURL(input: String?) -> Bool { - guard let path = input, let url = URL(string: path) else { - Utils.alert(title: "CannotSavePgpKey".localize(), message: "SetPgpKeyUrlFirst.".localize(), controller: self, completion: nil) - return false - } - guard let scheme = url.scheme, scheme == "https" else { - Utils.alert(title: "CannotSavePgpKey".localize(), message: "HttpNotSupported.".localize(), controller: self, completion: nil) - return false - } - return true - } - - @IBAction func save(_ sender: Any) { - guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true, - validatePGPKeyURL(input: pgpPrivateKeyURLTextField.text) == true else { - return - } - let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertController.Style.alert) - // no - savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertAction.Style.default) { _ in - self.keychain.removeContent(for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = false - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - // yes - savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive) {_ in - // ask for the passphrase - let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertAction.Style.default, handler: {_ in - self.keychain.add(string: alert.textFields?.first?.text, for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = true - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - })) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = self.keychain.get(for: Globals.pgpKeyPassphrase) - textField.isSecureTextEntry = true - }) - self.present(alert, animated: true, completion: nil) - }) - self.present(savePassphraseAlert, animated: true, completion: nil) - } - - -} diff --git a/pass/Controllers/PGPKeyUrlTableViewController.swift b/pass/Controllers/PGPKeyUrlTableViewController.swift new file mode 100644 index 0000000..6a95f8a --- /dev/null +++ b/pass/Controllers/PGPKeyUrlTableViewController.swift @@ -0,0 +1,70 @@ +// +// PGPKeyUrlTableViewController.swift +// pass +// +// Created by Mingshen Sun on 21/1/2017. +// Copyright © 2017 Bob Sun. All rights reserved. +// + +import UIKit +import passKit + +class PGPKeyUrlTableViewController: AutoCellHeightUITableViewController { + + @IBOutlet weak var pgpPublicKeyURLTextField: UITextField! + @IBOutlet weak var pgpPrivateKeyURLTextField: UITextField! + + let passwordStore = PasswordStore.shared + let keychain = AppKeychain.shared + + override func viewDidLoad() { + super.viewDidLoad() + pgpPublicKeyURLTextField.text = Defaults.pgpPublicKeyURL?.absoluteString + pgpPrivateKeyURLTextField.text = Defaults.pgpPrivateKeyURL?.absoluteString + } + + @IBAction func save(_ sender: Any) { + savePassphraseDialog() + } +} + +extension PGPKeyUrlTableViewController: PGPKeyImporter { + + static let keySource = PGPKeySource.url + static let label = "DownloadFromUrl".localize() + + func isReadyToUse() -> Bool { + return validate(pgpKeyUrl: pgpPublicKeyURLTextField.text) + && validate(pgpKeyUrl: pgpPrivateKeyURLTextField.text) + } + + func importKeys() throws { + Defaults.pgpKeySource = Self.keySource + + Defaults.pgpPrivateKeyURL = URL(string: pgpPrivateKeyURLTextField.text!.trimmed) + Defaults.pgpPublicKeyURL = URL(string: pgpPublicKeyURLTextField.text!.trimmed) + + try KeyFileManager.PublicPgp.importKey(from: Defaults.pgpPublicKeyURL!) + try KeyFileManager.PrivatePgp.importKey(from: Defaults.pgpPrivateKeyURL!) + } + + func doAfterImport() { + Utils.alert(title: "RememberToRemoveKey".localize(), message: "RememberToRemoveKeyFromServer.".localize(), controller: self, completion: nil) + } + + func saveImportedKeys() { + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) + } + + private func validate(pgpKeyUrl: String?) -> Bool { + guard let pgpKeyUrl = pgpKeyUrl, let url = URL(string: pgpKeyUrl), let scheme = url.scheme else { + Utils.alert(title: "CannotSavePgpKey".localize(), message: "SetPgpKeyUrlFirst.".localize(), controller: self, completion: nil) + return false + } + guard scheme == "https" else { + Utils.alert(title: "CannotSavePgpKey".localize(), message: "UseHttps.".localize(), controller: self, completion: nil) + return false + } + return true + } +} diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index a40de20..24c3521 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -26,74 +26,28 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele } @IBAction func savePGPKey(segue: UIStoryboardSegue) { - if let controller = segue.source as? PGPKeySettingTableViewController { - Defaults.pgpPrivateKeyURL = URL(string: controller.pgpPrivateKeyURLTextField.text!.trimmed) - Defaults.pgpPublicKeyURL = URL(string: controller.pgpPublicKeyURLTextField.text!.trimmed) - Defaults.pgpKeySource = "url" - - SVProgressHUD.setDefaultMaskType(.black) - SVProgressHUD.setDefaultStyle(.light) - SVProgressHUD.show(withStatus: "FetchingPgpKey".localize()) - DispatchQueue.global(qos: .userInitiated).async { [unowned self] in - do { - try KeyFileManager.PublicPgp.importKey(from: Defaults.pgpPublicKeyURL!) - try KeyFileManager.PrivatePgp.importKey(from: Defaults.pgpPrivateKeyURL!) - try PGPAgent.shared.initKeys() - DispatchQueue.main.async { - self.setPGPKeyTableViewCellDetailText() - SVProgressHUD.showSuccess(withStatus: "Success".localize()) - SVProgressHUD.dismiss(withDelay: 1) - Utils.alert(title: "RememberToRemoveKey".localize(), message: "RememberToRemoveKeyFromServer.".localize(), controller: self, completion: nil) - } - } catch { - DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize() - Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil) - } - } - } - - } else if let controller = segue.source as? PGPKeyArmorSettingTableViewController { - Defaults.pgpKeySource = "armor" - - SVProgressHUD.setDefaultMaskType(.black) - SVProgressHUD.setDefaultStyle(.light) - SVProgressHUD.show(withStatus: "FetchingPgpKey".localize()) - DispatchQueue.global(qos: .userInitiated).async { [unowned self] in - do { - try KeyFileManager.PublicPgp.importKey(from: controller.armorPublicKeyTextView.text ?? "") - try KeyFileManager.PrivatePgp.importKey(from: controller.armorPrivateKeyTextView.text ?? "") - try PGPAgent.shared.initKeys() - DispatchQueue.main.async { - self.setPGPKeyTableViewCellDetailText() - SVProgressHUD.showSuccess(withStatus: "Success".localize()) - SVProgressHUD.dismiss(withDelay: 1) - } - } catch { - DispatchQueue.main.async { - self.pgpKeyTableViewCell.detailTextLabel?.text = "NotSet".localize() - Utils.alert(title: "Error".localize(), message: error.localizedDescription, controller: self, completion: nil) - } - } - } + guard let sourceController = segue.source as? PGPKeyImporter else { + return } + savePGPKey(using: sourceController) } - private func saveImportedPGPKey() { - // load keys - Defaults.pgpKeySource = "file" + private func savePGPKey(using keyImporter: PGPKeyImporter) { + guard keyImporter.isReadyToUse() else { + return + } SVProgressHUD.setDefaultMaskType(.black) SVProgressHUD.setDefaultStyle(.light) SVProgressHUD.show(withStatus: "FetchingPgpKey".localize()) DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try KeyFileManager.PublicPgp.importKeyFromFileSharing() - try KeyFileManager.PrivatePgp.importKeyFromFileSharing() + try keyImporter.importKeys() try PGPAgent.shared.initKeys() DispatchQueue.main.async { self.setPGPKeyTableViewCellDetailText() - SVProgressHUD.showSuccess(withStatus: "Imported".localize()) + SVProgressHUD.showSuccess(withStatus: "Success".localize()) SVProgressHUD.dismiss(withDelay: 1) + keyImporter.doAfterImport() } } catch { DispatchQueue.main.async { @@ -108,10 +62,6 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele self.passwordRepositoryTableViewCell.detailTextLabel?.text = Defaults.gitURL.host } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return super.tableView(tableView, numberOfRowsInSection: section) - } - override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(SettingsTableViewController.actOnPasswordStoreErasedNotification), name: .passwordStoreErased, object: nil) @@ -182,67 +132,25 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele func showPGPKeyActionSheet() { let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - var urlActionTitle = "DownloadFromUrl".localize() - var armorActionTitle = "AsciiArmorEncryptedKey".localize() - var fileActionTitle = "ITunesFileSharing".localize() - - if Defaults.pgpKeySource == "url" { - urlActionTitle = "✓ \(urlActionTitle)" - } else if Defaults.pgpKeySource == "armor" { - armorActionTitle = "✓ \(armorActionTitle)" - } else if Defaults.pgpKeySource == "file" { - fileActionTitle = "✓ \(fileActionTitle)" - } - let urlAction = UIAlertAction(title: urlActionTitle, style: .default) { _ in + optionMenu.addAction(UIAlertAction(title: PGPKeyUrlTableViewController.menuLabel, style: .default) { _ in self.performSegue(withIdentifier: "setPGPKeyByURLSegue", sender: self) - } - let armorAction = UIAlertAction(title: armorActionTitle, style: .default) { _ in + }) + optionMenu.addAction(UIAlertAction(title: PGPKeyArmorSettingTableViewController.menuLabel, style: .default) { _ in self.performSegue(withIdentifier: "setPGPKeyByASCIISegue", sender: self) - } - let cancelAction = UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil) - optionMenu.addAction(urlAction) - optionMenu.addAction(armorAction) + }) - if KeyFileManager.PublicPgp.doesKeyFileExist() && KeyFileManager.PrivatePgp.doesKeyFileExist() { - fileActionTitle.append(" (\("Import".localize()))") - let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in - // passphrase related - let savePassphraseAlert = UIAlertController(title: "Passphrase".localize(), message: "WantToSavePassphrase?".localize(), preferredStyle: UIAlertController.Style.alert) - // no - savePassphraseAlert.addAction(UIAlertAction(title: "No".localize(), style: UIAlertAction.Style.default) { _ in - self.keychain.removeContent(for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = false - self.saveImportedPGPKey() - }) - // yes - savePassphraseAlert.addAction(UIAlertAction(title: "Yes".localize(), style: UIAlertAction.Style.destructive) {_ in - // ask for the passphrase - let alert = UIAlertController(title: "Passphrase".localize(), message: "FillInPgpPassphrase.".localize(), preferredStyle: UIAlertController.Style.alert) - alert.addAction(UIAlertAction(title: "Ok".localize(), style: UIAlertAction.Style.default, handler: {_ in - self.keychain.add(string: alert.textFields?.first?.text, for: Globals.pgpKeyPassphrase) - Defaults.isRememberPGPPassphraseOn = true - self.saveImportedPGPKey() - })) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = "" - textField.isSecureTextEntry = true - }) - self.present(alert, animated: true, completion: nil) - }) - self.present(savePassphraseAlert, animated: true, completion: nil) - } - optionMenu.addAction(fileAction) + if isReadyToUse() { + optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Import".localize()))", style: .default) { _ in + self.savePassphraseDialog() + }) } else { - fileActionTitle.append(" (\("Tips".localize()))") - let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in + optionMenu.addAction(UIAlertAction(title: "\(Self.menuLabel) (\("Tips".localize()))", style: .default) { _ in let title = "Tips".localize() let message = "PgpCopyPublicAndPrivateKeyToPass.".localize() Utils.alert(title: title, message: message, controller: self) - } - optionMenu.addAction(fileAction) + }) } - if Defaults.pgpKeySource != nil { let deleteAction = UIAlertAction(title: "RemovePgpKeys".localize(), style: .destructive) { _ in self.keychain.removeContent(for: PgpKey.PUBLIC.getKeychainKey()) @@ -252,7 +160,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele } optionMenu.addAction(deleteAction) } - optionMenu.addAction(cancelAction) + optionMenu.addAction(UIAlertAction(title: "Cancel".localize(), style: .cancel, handler: nil)) optionMenu.popoverPresentationController?.sourceView = pgpKeyTableViewCell optionMenu.popoverPresentationController?.sourceRect = pgpKeyTableViewCell.bounds self.present(optionMenu, animated: true, completion: nil) @@ -330,3 +238,28 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele self.present(setPasscodeLockAlert!, animated: true, completion: nil) } } + +extension SettingsTableViewController: PGPKeyImporter { + + static let keySource = PGPKeySource.itunes + static let label = "ITunesFileSharing".localize() + + func isReadyToUse() -> Bool { + return KeyFileManager.PublicPgp.doesKeyFileExist() && KeyFileManager.PrivatePgp.doesKeyFileExist() + } + + func importKeys() throws { + Defaults.pgpKeySource = Self.keySource + + try KeyFileManager.PublicPgp.importKeyFromFileSharing() + try KeyFileManager.PrivatePgp.importKeyFromFileSharing() + } + + func doAfterImport() { + + } + + func saveImportedKeys() { + self.savePGPKey(using: self) + } +} diff --git a/pass/de.lproj/Localizable.strings b/pass/de.lproj/Localizable.strings index 880dba7..514e7b9 100644 --- a/pass/de.lproj/Localizable.strings +++ b/pass/de.lproj/Localizable.strings @@ -65,7 +65,7 @@ "FileNotFoundError." = "Die Datei '%@' kann nicht gelesen werden."; "PasswordDuplicatedError." = "Passwort kann nicht hinzugefügt werden; es existiert bereits."; "GitResetError." = "Der zuletzt synchronisierte Commit kann nicht identifiziert werden."; -"WrongPasswordFilename." = "Schreiben der Passwort-Datei nicht möglich ."; +"WrongPasswordFilenameError." = "Schreiben der Passwort-Datei nicht möglich ."; "DecryptionError." = "Passwort kann nicht entschlüsselt werden."; "EncodingError." = "Schlüssel ist nicht in ASCII kodiert."; "UnknownError." = "Ein unbekannter Fehler ist aufgetreten."; diff --git a/passKit/Helpers/DefaultsKeys.swift b/passKit/Helpers/DefaultsKeys.swift index 6e0f13f..17b5ddb 100644 --- a/passKit/Helpers/DefaultsKeys.swift +++ b/passKit/Helpers/DefaultsKeys.swift @@ -11,6 +11,10 @@ import SwiftyUserDefaults public var Defaults = DefaultsAdapter(defaults: UserDefaults(suiteName: Globals.groupIdentifier)!, keyStore: DefaultsKeys()) +public enum PGPKeySource: String, DefaultsSerializable { + case url, armor, itunes +} + public enum GitAuthenticationMethod: String, DefaultsSerializable { case password, key } @@ -20,7 +24,7 @@ public enum GitSSHKeySource: String, DefaultsSerializable { } public extension DefaultsKeys { - var pgpKeySource: DefaultsKey { .init("pgpKeySource") } + var pgpKeySource: DefaultsKey { .init("pgpKeySource") } var pgpPublicKeyURL: DefaultsKey { .init("pgpPublicKeyURL") } var pgpPrivateKeyURL: DefaultsKey { .init("pgpPrivateKeyURL") }