Combine key scanning logic in one class

This commit is contained in:
Danny Moesch 2020-08-26 21:29:05 +02:00 committed by Mingshen Sun
parent edd7398cd4
commit 078503f249
10 changed files with 405 additions and 112 deletions

View file

@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
116F7CC922E134FA003B3BAC /* Crypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 116F7CC822E134FA003B3BAC /* Crypto.framework */; };
116F7CCA22E134FA003B3BAC /* Crypto.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 116F7CC822E134FA003B3BAC /* Crypto.framework */; };
3005F35424B13C3E000519B5 /* ScannedPGPKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3005F35324B13C3E000519B5 /* ScannedPGPKey.swift */; };
300713C52219D54100F553AC /* AutoCellHeightUITableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 300713C42219D54100F553AC /* AutoCellHeightUITableViewController.swift */; };
301F6463216162550071A4CE /* AdditionField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6462216162550071A4CE /* AdditionField.swift */; };
301F6468216165290071A4CE /* ConstantsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F6467216165290071A4CE /* ConstantsTest.swift */; };
@ -54,6 +53,10 @@
306D970E24091CDD006C0E2E /* SwitchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306D970D24091CDD006C0E2E /* SwitchTableViewCell.swift */; };
306D971224091EE7006C0E2E /* SwitchTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 306D971124091EE7006C0E2E /* SwitchTableViewCell.xib */; };
3087574F2343E42A00B971A2 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3087574E2343E42A00B971A2 /* Colors.swift */; };
308800C324EDA5F600E87ED3 /* QRKeyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308800C224EDA5F600E87ED3 /* QRKeyScanner.swift */; };
308800C724EDC08D00E87ED3 /* ScannableKeyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308800C624EDC08D00E87ED3 /* ScannableKeyType.swift */; };
308800CF24F04E9900E87ED3 /* ScannableKeyTypeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308800CE24F04E9900E87ED3 /* ScannableKeyTypeTest.swift */; };
308800D124F0596300E87ED3 /* QRKeyScannerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308800D024F0596300E87ED3 /* QRKeyScannerTest.swift */; };
308C273A2279F9CB0016D0E2 /* SearchBarScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302202EE222F14E400555236 /* SearchBarScope.swift */; };
30A1D29C21AF451E00E2D1F7 /* PasswordGeneratorFlavorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A1D29B21AF451E00E2D1F7 /* PasswordGeneratorFlavorTest.swift */; };
30A1D2A221B2BC6F00E2D1F7 /* TokenBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A1D2A121B2BC6F00E2D1F7 /* TokenBuilder.swift */; };
@ -221,6 +224,13 @@
remoteGlobalIDString = A26700231EEC466A00176B8A;
remoteInfo = passExtension;
};
DC13B1531E8640810097803F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DC917BCB1E2E8231000FDF54 /* Project object */;
proxyType = 1;
remoteGlobalIDString = DC917BD21E2E8231000FDF54;
remoteInfo = pass;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -254,7 +264,6 @@
116F7CC822E134FA003B3BAC /* Crypto.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crypto.framework; path = go/dist/Crypto.framework; sourceTree = "<group>"; };
134DA5B66070BA56678688CF /* Pods_passKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_passKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
14E955B67C88672AA3A40BA0 /* Pods_passExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_passExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3005F35324B13C3E000519B5 /* ScannedPGPKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannedPGPKey.swift; sourceTree = "<group>"; };
300713C42219D54100F553AC /* AutoCellHeightUITableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCellHeightUITableViewController.swift; sourceTree = "<group>"; };
301F6462216162550071A4CE /* AdditionField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionField.swift; sourceTree = "<group>"; };
301F6467216165290071A4CE /* ConstantsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsTest.swift; sourceTree = "<group>"; };
@ -300,6 +309,10 @@
306D970D24091CDD006C0E2E /* SwitchTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchTableViewCell.swift; sourceTree = "<group>"; };
306D971124091EE7006C0E2E /* SwitchTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SwitchTableViewCell.xib; sourceTree = "<group>"; };
3087574E2343E42A00B971A2 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
308800C224EDA5F600E87ED3 /* QRKeyScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRKeyScanner.swift; sourceTree = "<group>"; };
308800C624EDC08D00E87ED3 /* ScannableKeyType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannableKeyType.swift; sourceTree = "<group>"; };
308800CE24F04E9900E87ED3 /* ScannableKeyTypeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannableKeyTypeTest.swift; sourceTree = "<group>"; };
308800D024F0596300E87ED3 /* QRKeyScannerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRKeyScannerTest.swift; sourceTree = "<group>"; };
30A1D29B21AF451E00E2D1F7 /* PasswordGeneratorFlavorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordGeneratorFlavorTest.swift; sourceTree = "<group>"; };
30A1D2A121B2BC6F00E2D1F7 /* TokenBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenBuilder.swift; sourceTree = "<group>"; };
30A1D2A521B2D46100E2D1F7 /* OTPType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OTPType.swift; sourceTree = "<group>"; };
@ -395,6 +408,7 @@
DC037CBD1E4ED4E100609409 /* TextViewTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewTableViewCell.swift; sourceTree = "<group>"; };
DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextViewTableViewCell.xib; sourceTree = "<group>"; };
DC1208571E35EBE60042942E /* ObjectiveGit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ObjectiveGit.framework; path = Carthage/Build/iOS/ObjectiveGit.framework; sourceTree = "<group>"; };
DC13B14E1E8640810097803F /* passTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = passTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DC13B1521E8640810097803F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AdvancedSettingsTableViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
DC3E64E51E656F11009A83DE /* CommitLogsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommitLogsTableViewController.swift; sourceTree = "<group>"; };
@ -486,6 +500,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DC13B14B1E8640810097803F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DC917BD01E2E8231000FDF54 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -504,7 +525,8 @@
3005F35224B13BF3000519B5 /* Models */ = {
isa = PBXGroup;
children = (
3005F35324B13C3E000519B5 /* ScannedPGPKey.swift */,
308800C224EDA5F600E87ED3 /* QRKeyScanner.swift */,
308800C624EDC08D00E87ED3 /* ScannableKeyType.swift */,
);
path = Models;
sourceTree = "<group>";
@ -554,6 +576,15 @@
path = Extensions;
sourceTree = "<group>";
};
308800CD24F04E6600E87ED3 /* Models */ = {
isa = PBXGroup;
children = (
308800D024F0596300E87ED3 /* QRKeyScannerTest.swift */,
308800CE24F04E9900E87ED3 /* ScannableKeyTypeTest.swift */,
);
path = Models;
sourceTree = "<group>";
};
30A69946240EED5E00B7D967 /* passShortcuts */ = {
isa = PBXGroup;
children = (
@ -785,6 +816,7 @@
DC13B14F1E8640810097803F /* passTests */ = {
isa = PBXGroup;
children = (
308800CD24F04E6600E87ED3 /* Models */,
DC13B1521E8640810097803F /* Info.plist */,
);
path = passTests;
@ -880,6 +912,7 @@
isa = PBXGroup;
children = (
DC917BD31E2E8231000FDF54 /* Pass.app */,
DC13B14E1E8640810097803F /* passTests.xctest */,
A26700241EEC466A00176B8A /* passExtension.appex */,
A26075781EEC6F34005DB03E /* passKit.framework */,
A26075801EEC6F34005DB03E /* passKitTests.xctest */,
@ -1039,6 +1072,24 @@
productReference = A26700241EEC466A00176B8A /* passExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
DC13B14D1E8640810097803F /* passTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DC13B1571E8640810097803F /* Build configuration list for PBXNativeTarget "passTests" */;
buildPhases = (
DC13B14A1E8640810097803F /* Sources */,
DC13B14B1E8640810097803F /* Frameworks */,
DC13B14C1E8640810097803F /* Resources */,
);
buildRules = (
);
dependencies = (
DC13B1541E8640810097803F /* PBXTargetDependency */,
);
name = passTests;
productName = passTests;
productReference = DC13B14E1E8640810097803F /* passTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
DC917BD21E2E8231000FDF54 /* pass */ = {
isa = PBXNativeTarget;
buildConfigurationList = DC917BE51E2E8231000FDF54 /* Build configuration list for PBXNativeTarget "pass" */;
@ -1121,6 +1172,13 @@
};
};
};
DC13B14D1E8640810097803F = {
CreatedOnToolsVersion = 8.3;
DevelopmentTeam = 4WDM8E95VU;
LastSwiftMigration = 1020;
ProvisioningStyle = Automatic;
TestTargetID = DC917BD21E2E8231000FDF54;
};
DC917BD21E2E8231000FDF54 = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 4WDM8E95VU;
@ -1155,6 +1213,7 @@
projectRoot = "";
targets = (
DC917BD21E2E8231000FDF54 /* pass */,
DC13B14D1E8640810097803F /* passTests */,
A26700231EEC466A00176B8A /* passExtension */,
A26075771EEC6F34005DB03E /* passKit */,
A260757F1EEC6F34005DB03E /* passKitTests */,
@ -1214,6 +1273,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DC13B14C1E8640810097803F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DC917BD11E2E8231000FDF54 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1527,6 +1593,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DC13B14A1E8640810097803F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
308800D124F0596300E87ED3 /* QRKeyScannerTest.swift in Sources */,
308800CF24F04E9900E87ED3 /* ScannableKeyTypeTest.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DC917BCF1E2E8231000FDF54 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1545,11 +1620,12 @@
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */,
DC5F385B1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift in Sources */,
DCAAF7451E2FA66800AB94BC /* SettingsTableViewController.swift in Sources */,
3005F35424B13C3E000519B5 /* ScannedPGPKey.swift in Sources */,
DCFB77A71E502DF9008DE471 /* EditPasswordTableViewController.swift in Sources */,
DCA0499A1E335CC800522E8F /* GitRepositorySettingsTableViewController.swift in Sources */,
DCDDEAB31E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift in Sources */,
A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */,
308800C724EDC08D00E87ED3 /* ScannableKeyType.swift in Sources */,
308800C324EDA5F600E87ED3 /* QRKeyScanner.swift in Sources */,
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */,
30C25DD821F4834D00BB27BB /* UICodeHighlightingLabel.swift in Sources */,
DC962CDF1E4B62C10033B5D8 /* AboutTableViewController.swift in Sources */,
@ -1616,6 +1692,11 @@
target = A26700231EEC466A00176B8A /* passExtension */;
targetProxy = A267002C1EEC466A00176B8A /* PBXContainerItemProxy */;
};
DC13B1541E8640810097803F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DC917BD21E2E8231000FDF54 /* pass */;
targetProxy = DC13B1531E8640810097803F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -1847,6 +1928,25 @@
};
name = Beta;
};
9A1EF0AD24C4EB280074FEAC /* Beta */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
DEVELOPMENT_TEAM = 4WDM8E95VU;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = passTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passTests";
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Pass.app/Pass";
};
name = Beta;
};
9A1EF0AE24C4EB280074FEAC /* Beta */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C4C702DBCBA2374D32295603 /* Pods-passExtension.beta.xcconfig */;
@ -2248,6 +2348,44 @@
};
name = Release;
};
DC13B1551E8640810097803F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
DEVELOPMENT_TEAM = 4WDM8E95VU;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = passTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passTests";
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Pass.app/Pass";
};
name = Debug;
};
DC13B1561E8640810097803F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
DEVELOPMENT_TEAM = 4WDM8E95VU;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = passTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER).passTests";
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Pass.app/Pass";
};
name = Release;
};
DC917BE31E2E8231000FDF54 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -2508,6 +2646,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DC13B1571E8640810097803F /* Build configuration list for PBXNativeTarget "passTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DC13B1551E8640810097803F /* Debug */,
DC13B1561E8640810097803F /* Release */,
9A1EF0AD24C4EB280074FEAC /* Beta */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DC917BCE1E2E8231000FDF54 /* Build configuration list for PBXProject "pass" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -15,10 +15,10 @@ class PGPKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
@IBOutlet var scanPublicKeyCell: UITableViewCell!
@IBOutlet var scanPrivateKeyCell: UITableViewCell!
var armorPublicKey: String?
var armorPrivateKey: String?
private var armorPublicKey: String?
private var armorPrivateKey: String?
var scanned = ScannedPGPKey()
private var scanner = QRKeyScanner(keyType: .pgpPublic)
override func viewDidLoad() {
super.viewDidLoad()
@ -50,9 +50,9 @@ class PGPKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == scanPublicKeyCell {
scanned.reset(keytype: ScannedPGPKey.KeyType.publicKey)
scanner = QRKeyScanner(keyType: .pgpPublic)
} else if selectedCell == scanPrivateKeyCell {
scanned.reset(keytype: ScannedPGPKey.KeyType.privateKey)
scanner = QRKeyScanner(keyType: .pgpPrivate)
}
performSegue(withIdentifier: "showPGPScannerSegue", sender: self)
tableView.deselectRow(at: indexPath, animated: true)
@ -60,19 +60,21 @@ class PGPKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
return scanned.addSegment(segment: line)
func checkScannedOutput(line: String) -> (accepted: Bool, message: String) {
scanner.add(segment: line).unrolled
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line _: String) {
let key = scanned.segments.joined()
switch scanned.keyType {
case .publicKey:
let key = scanner.scannedKey
switch scanner.keyType {
case .pgpPublic:
armorPublicKeyTextView.text += key
case .privateKey:
case .pgpPrivate:
armorPrivateKeyTextView.text += key
default:
return
}
}

View file

@ -416,11 +416,11 @@ extension PasswordEditorTableViewController: PasswordSettingSliderTableViewCellD
// MARK: - QRScannerControllerDelegate
extension PasswordEditorTableViewController: QRScannerControllerDelegate {
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
func checkScannedOutput(line: String) -> (accepted: Bool, message: String) {
if let url = URL(string: line), Token(url: url) != nil {
return (accept: true, message: "ValidTokenUrl".localize())
return (true, "ValidTokenUrl".localize())
}
return (accept: false, message: "InvalidTokenUrl".localize())
return (false, "InvalidTokenUrl".localize())
}
func handleScannedOutput(line: String) {

View file

@ -13,7 +13,7 @@ import SVProgressHUD
import UIKit
protocol QRScannerControllerDelegate: AnyObject {
func checkScannedOutput(line: String) -> (accept: Bool, message: String)
func checkScannedOutput(line: String) -> (accepted: Bool, message: String)
func handleScannedOutput(line: String)
}
@ -107,13 +107,13 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
scannerOutput.text = "NoStringValue".localize()
return
}
guard let (accept, message) = delegate?.checkScannedOutput(line: scanned) else {
guard let (accepted, message) = delegate?.checkScannedOutput(line: scanned) else {
// no delegate, show the scanned result
scannerOutput.text = scanned
return
}
scannerOutput.text = message
guard accept else {
guard accepted else {
return
}
captureSession?.stopRunning()

View file

@ -13,42 +13,10 @@ class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
@IBOutlet var armorPrivateKeyTextView: UITextView!
@IBOutlet var scanPrivateKeyCell: UITableViewCell!
var gitSSHPrivateKeyPassphrase: String?
var armorPrivateKey: String?
private var gitSSHPrivateKeyPassphrase: String?
private var armorPrivateKey: String?
class ScannedSSHKey {
var segments = [String]()
var message = ""
func reset() {
segments.removeAll()
message = "LookingForStartingFrame.".localize()
}
func addSegment(segment: String) -> (accept: Bool, message: String) {
// Skip duplicated segments.
guard segment != segments.last else {
return (accept: false, message: message)
}
// Check whether we have found the first block.
guard !segments.isEmpty || segment.contains("-----BEGIN") else {
return (accept: false, message: message)
}
// Update the list of scanned segment and return.
segments.append(segment)
if segment.range(of: "-----END.*KEY-----", options: .regularExpression, range: nil, locale: nil) != nil {
message = "Done".localize()
return (accept: true, message: message)
} else {
message = "ScannedQrCodes(%d)".localize(segments.count)
return (accept: false, message: message)
}
}
}
var scanned = ScannedSSHKey()
private var scanner = QRKeyScanner(keyType: .sshPrivate)
override func viewDidLoad() {
super.viewDidLoad()
@ -76,7 +44,7 @@ class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
if selectedCell == scanPrivateKeyCell {
scanned.reset()
scanner = QRKeyScanner(keyType: .sshPrivate)
performSegue(withIdentifier: "showSSHScannerSegue", sender: self)
}
tableView.deselectRow(at: indexPath, animated: true)
@ -84,14 +52,14 @@ class SSHKeyArmorImportTableViewController: AutoCellHeightUITableViewController,
// MARK: - QRScannerControllerDelegate Methods
func checkScannedOutput(line: String) -> (accept: Bool, message: String) {
return scanned.addSegment(segment: line)
func checkScannedOutput(line: String) -> (accepted: Bool, message: String) {
scanner.add(segment: line).unrolled
}
// MARK: - QRScannerControllerDelegate Methods
func handleScannedOutput(line _: String) {
armorPrivateKeyTextView.text = scanned.segments.joined()
armorPrivateKeyTextView.text = scanner.scannedKey
}
override func prepare(for segue: UIStoryboardSegue, sender _: Any?) {

View file

@ -0,0 +1,73 @@
//
// QRKeyScanner.swift
// pass
//
// Created by Danny Moesch on 19.08.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
struct QRKeyScanner {
enum Result: Equatable {
case lookingForStart
case wrongKeyType(ScannableKeyType)
case completed
case scanned(Int)
var message: String {
switch self {
case .lookingForStart:
return "LookingForStartingFrame.".localize()
case let .wrongKeyType(keyType):
return "Scan\(keyType.visibility)Key.".localize()
case .completed:
return "Done".localize()
case let .scanned(count):
return "ScannedQrCodes(%d)".localize(count)
}
}
var unrolled: (accepted: Bool, message: String) {
if self == .completed {
return (true, message)
}
return (false, message)
}
}
private var segments = [String]()
private var previousResult = Result.lookingForStart
let keyType: ScannableKeyType
init(keyType: ScannableKeyType) {
self.keyType = keyType
}
var scannedKey: String {
segments.joined()
}
mutating func add(segment: String) -> Result {
// Skip duplicated segments.
guard segment != segments.last else {
return previousResult
}
// Check whether we have found the first block.
guard !segments.isEmpty || segment.contains(keyType.headerStart) else {
// Check whether we are scanning the wrong key type.
if let counterKeyType = keyType.counterType, segment.contains(counterKeyType.headerStart) {
previousResult = .wrongKeyType(counterKeyType)
}
return previousResult
}
// Update the list of scanned segments and return.
segments.append(segment)
if segment.starts(with: keyType.footerStart), segment.hasSuffix(keyType.footerEnd) {
return .completed
}
previousResult = .scanned(segments.count)
return previousResult
}
}

View file

@ -0,0 +1,60 @@
//
// ScannableKeyType.swift
// pass
//
// Created by Danny Moesch on 19.08.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
enum ScannableKeyType {
case pgpPublic
case pgpPrivate
case sshPrivate
var visibility: String {
switch self {
case .pgpPublic:
return "Public"
case .pgpPrivate, .sshPrivate:
return "Private"
}
}
var headerStart: String {
switch self {
case .pgpPublic, .pgpPrivate:
return "-----BEGIN PGP \(visibility.uppercased()) KEY BLOCK-----"
case .sshPrivate:
return "-----BEGIN"
}
}
var footerStart: String {
switch self {
case .pgpPublic, .pgpPrivate:
return "-----END PGP \(visibility.uppercased())"
case .sshPrivate:
return "-----END"
}
}
var footerEnd: String {
switch self {
case .pgpPublic, .pgpPrivate:
return "KEY BLOCK-----"
case .sshPrivate:
return "KEY-----"
}
}
var counterType: Self? {
switch self {
case .pgpPublic:
return .pgpPrivate
case .pgpPrivate:
return .pgpPublic
case .sshPrivate:
return nil
}
}
}

View file

@ -1,52 +0,0 @@
//
// ScannedPGPKey.swift
// pass
//
// Created by Danny Moesch on 05.07.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
class ScannedPGPKey {
enum KeyType {
case publicKey, privateKey
}
var keyType = KeyType.publicKey
var segments = [String]()
var message = ""
func reset(keytype: KeyType) {
keyType = keytype
segments.removeAll()
message = "LookingForStartingFrame.".localize()
}
func addSegment(segment: String) -> (accept: Bool, message: String) {
let keyTypeStr = keyType == .publicKey ? "Public" : "Private"
let theOtherKeyTypeStr = keyType == .publicKey ? "Private" : "Public"
// Skip duplicated segments.
guard segment != segments.last else {
return (accept: false, message: message)
}
// Check whether we have found the first block.
guard !segments.isEmpty || segment.contains("-----BEGIN PGP \(keyTypeStr.uppercased()) KEY BLOCK-----") else {
// Check whether we are scanning the wrong key type.
if segment.contains("-----BEGIN PGP \(theOtherKeyTypeStr.uppercased()) KEY BLOCK-----") {
message = "Scan\(keyTypeStr)Key.".localize()
}
return (accept: false, message: message)
}
// Update the list of scanned segment and return.
segments.append(segment)
if segment.contains("-----END PGP \(keyTypeStr.uppercased()) KEY BLOCK-----") {
message = "Done".localize()
return (accept: true, message: message)
} else {
message = "ScannedQrCodes(%d)".localize(segments.count)
return (accept: false, message: message)
}
}
}

View file

@ -0,0 +1,51 @@
//
// QRKeyScannerTest.swift
// passTests
//
// Created by Danny Moesch on 21.08.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
import XCTest
@testable import Pass
class QRKeyScannerTest: XCTestCase {
let header = "-----BEGIN PGP PUBLIC KEY BLOCK-----"
let body = "key body"
let footer = "-----END PGP PUBLIC KEY BLOCK-----"
let privateHeader = "-----BEGIN PGP PRIVATE KEY BLOCK-----"
var scanner = QRKeyScanner(keyType: .pgpPublic)
func testAddHeaderTwice() {
XCTAssertEqual(scanner.add(segment: header), .scanned(1))
XCTAssertEqual(scanner.add(segment: header), .scanned(1))
XCTAssertEqual(scanner.scannedKey, header)
}
func testAddBodyTwice() {
XCTAssertEqual(scanner.add(segment: header), .scanned(1))
XCTAssertEqual(scanner.add(segment: body), .scanned(2))
XCTAssertEqual(scanner.add(segment: body), .scanned(2))
XCTAssertEqual(scanner.scannedKey, header + body)
}
func testAddCompleteBlock() {
XCTAssertEqual(scanner.add(segment: header), .scanned(1))
XCTAssertEqual(scanner.add(segment: footer), .completed)
XCTAssertEqual(scanner.scannedKey, header + footer)
}
func testCounterKeyType() {
XCTAssertEqual(scanner.add(segment: privateHeader), .wrongKeyType(.pgpPrivate))
XCTAssertEqual(scanner.add(segment: privateHeader), .wrongKeyType(.pgpPrivate))
XCTAssertTrue(scanner.scannedKey.isEmpty)
}
func testUnknownKeyType() {
XCTAssertEqual(scanner.add(segment: body), .lookingForStart)
XCTAssertEqual(scanner.add(segment: body), .lookingForStart)
XCTAssertTrue(scanner.scannedKey.isEmpty)
}
}

View file

@ -0,0 +1,43 @@
//
// ScannableKeyTypeTest.swift
// passTests
//
// Created by Danny Moesch on 21.08.20.
// Copyright © 2020 Bob Sun. All rights reserved.
//
import XCTest
@testable import Pass
class ScannableKeyTypeTest: XCTestCase {
func testPGPPublicKey() {
let type = ScannableKeyType.pgpPublic
XCTAssertEqual(type.visibility, "Public")
XCTAssertEqual(type.headerStart, "-----BEGIN PGP PUBLIC KEY BLOCK-----")
XCTAssertEqual(type.footerStart, "-----END PGP PUBLIC")
XCTAssertEqual(type.footerEnd, "KEY BLOCK-----")
XCTAssertEqual(type.counterType, .pgpPrivate)
}
func testPGPPrivateKey() {
let type = ScannableKeyType.pgpPrivate
XCTAssertEqual(type.visibility, "Private")
XCTAssertEqual(type.headerStart, "-----BEGIN PGP PRIVATE KEY BLOCK-----")
XCTAssertEqual(type.footerStart, "-----END PGP PRIVATE")
XCTAssertEqual(type.footerEnd, "KEY BLOCK-----")
XCTAssertEqual(type.counterType, .pgpPublic)
}
func testSSHPrivateKey() {
let type = ScannableKeyType.sshPrivate
XCTAssertEqual(type.visibility, "Private")
XCTAssertEqual(type.headerStart, "-----BEGIN")
XCTAssertEqual(type.footerStart, "-----END")
XCTAssertEqual(type.footerEnd, "KEY-----")
XCTAssertNil(type.counterType)
}
}