From 7f6900b7cdf6a667e6b8ab7b89f73ec2e5c760df Mon Sep 17 00:00:00 2001 From: Yishi Lin Date: Tue, 13 Jun 2017 13:19:18 +0800 Subject: [PATCH] Fix some "linking against dylib" warning - Move requestGitPassword to view controllers - Move Utils.alert out of passKit, because SVProgressHUD is there --- pass.xcodeproj/project.pbxproj | 4 ++ .../GitServerSettingTableViewController.swift | 39 +++++++++++++-- .../Controllers/PasswordsViewController.swift | 43 ++++++++++++++-- pass/Helpers/UtilsExtension.swift | 20 ++++++++ passKit/Helpers/Utils.swift | 9 ---- passKit/Models/GitCredential.swift | 50 +++---------------- passKit/Models/PasswordStore.swift | 12 ++--- 7 files changed, 112 insertions(+), 65 deletions(-) create mode 100644 pass/Helpers/UtilsExtension.swift diff --git a/pass.xcodeproj/project.pbxproj b/pass.xcodeproj/project.pbxproj index 54eb204..78d3021 100644 --- a/pass.xcodeproj/project.pbxproj +++ b/pass.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ A2A61C161EEF90CB00CFE063 /* ObjectiveGit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1208571E35EBE60042942E /* ObjectiveGit.framework */; }; A2A61C171EEF90CB00CFE063 /* OneTimePassword.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA671DE1E7A73B100D3ABE1 /* OneTimePassword.framework */; }; A2A61C1A1EEF90CB00CFE063 /* SwiftyUserDefaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCA049951E3357E000522E8F /* SwiftyUserDefaults.framework */; }; + A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A61C1F1EEFABAD00CFE063 /* UtilsExtension.swift */; }; A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */; }; A2F4E2141EED800F0011986E /* GitCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2101EED800F0011986E /* GitCredential.swift */; }; A2F4E2151EED800F0011986E /* Password.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2F4E2111EED800F0011986E /* Password.swift */; }; @@ -187,6 +188,7 @@ A2802BF81E70813A00879216 /* SliderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SliderTableViewCell.xib; sourceTree = ""; }; A2A61C0C1EEF8DFE00CFE063 /* libPods-passextension.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passextension.a"; path = "../../Library/Developer/Xcode/DerivedData/pass-fwlmfsjroyvbfhdyqmglrwfhvjli/Build/Products/Debug-iphonesimulator/libPods-passextension.a"; sourceTree = ""; }; A2A61C101EEF8E3500CFE063 /* libPods-passKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-passKit.a"; path = "Pods/../build/Debug-iphoneos/libPods-passKit.a"; sourceTree = ""; }; + A2A61C1F1EEFABAD00CFE063 /* UtilsExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilsExtension.swift; sourceTree = ""; }; A2A7813E1E97DBD9001311F5 /* QRScannerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerController.swift; sourceTree = ""; }; A2BC54C71EEE5669001FAFBD /* Objective-CBridgingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Objective-CBridgingHeader.h"; sourceTree = ""; }; A2F4E2101EED800F0011986E /* GitCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GitCredential.swift; path = Models/GitCredential.swift; sourceTree = ""; }; @@ -430,6 +432,7 @@ isa = PBXGroup; children = ( A2BC54C71EEE5669001FAFBD /* Objective-CBridgingHeader.h */, + A2A61C1F1EEFABAD00CFE063 /* UtilsExtension.swift */, ); path = Helpers; sourceTree = ""; @@ -942,6 +945,7 @@ files = ( DC037CBF1E4ED4E100609409 /* TextViewTableViewCell.swift in Sources */, DCC441541E916382008A90C4 /* GitSSHKeyArmorSettingTableViewController.swift in Sources */, + A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */, DC8963C01E38EEB900828B09 /* SSHKeySettingTableViewController.swift in Sources */, DC193FFA1E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift in Sources */, DCFB77AB1E503729008DE471 /* ContentTableViewCell.swift in Sources */, diff --git a/pass/Controllers/GitServerSettingTableViewController.swift b/pass/Controllers/GitServerSettingTableViewController.swift index 58c46b2..681bb42 100644 --- a/pass/Controllers/GitServerSettingTableViewController.swift +++ b/pass/Controllers/GitServerSettingTableViewController.swift @@ -84,13 +84,12 @@ class GitServerSettingTableViewController: UITableViewController { SVProgressHUD.show(withStatus: "Prepare Repository") var gitCredential: GitCredential if auth == "Password" { - gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, controller: self)) + gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username)) } else { gitCredential = GitCredential( credential: GitCredential.Credential.ssh( userName: username, - privateKeyFile: Globals.gitSSHPrivateKeyURL, - controller: self + privateKeyFile: Globals.gitSSHPrivateKeyURL ) ) } @@ -99,6 +98,7 @@ class GitServerSettingTableViewController: UITableViewController { do { try self.passwordStore.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!, credential: gitCredential, + requestGitPassword: self.requestGitPassword, transferProgressBlock: { (git_transfer_progress, stop) in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Clone Remote Repository") @@ -215,4 +215,37 @@ class GitServerSettingTableViewController: UITableViewController { optionMenu.popoverPresentationController?.sourceRect = authSSHKeyCell.bounds self.present(optionMenu, animated: true, completion: nil) } + + private func requestGitPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? { + let sem = DispatchSemaphore(value: 0) + var password: String? + var message = "" + switch credential { + case .http: + message = "Please fill in the password of your Git account." + case .ssh: + message = "Please fill in the password of your SSH key." + } + + DispatchQueue.main.async { + SVProgressHUD.dismiss() + let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = lastPassword ?? "" + textField.isSecureTextEntry = true + }) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + password = alert.textFields!.first!.text + sem.signal() + })) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in + password = nil + sem.signal() + }) + self.present(alert, animated: true, completion: nil) + } + + let _ = sem.wait(timeout: .distantFuture) + return password + } } diff --git a/pass/Controllers/PasswordsViewController.swift b/pass/Controllers/PasswordsViewController.swift index 148cabf..2bae84b 100644 --- a/pass/Controllers/PasswordsViewController.swift +++ b/pass/Controllers/PasswordsViewController.swift @@ -139,25 +139,24 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV let numberOfLocalCommits = self.passwordStore.numberOfLocalCommits() var gitCredential: GitCredential if SharedDefaults[.gitAuthenticationMethod] == "Password" { - gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: SharedDefaults[.gitUsername]!, controller: self)) + gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: SharedDefaults[.gitUsername]!)) } else { gitCredential = GitCredential( credential: GitCredential.Credential.ssh( userName: SharedDefaults[.gitUsername]!, - privateKeyFile: Globals.gitSSHPrivateKeyURL, - controller: self + privateKeyFile: Globals.gitSSHPrivateKeyURL ) ) } DispatchQueue.global(qos: .userInitiated).async { [unowned self] in do { - try self.passwordStore.pullRepository(credential: gitCredential, transferProgressBlock: {(git_transfer_progress, stop) in + try self.passwordStore.pullRepository(credential: gitCredential, requestGitPassword: self.requestGitPassword(credential:lastPassword:), transferProgressBlock: {(git_transfer_progress, stop) in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects)/Float(git_transfer_progress.pointee.total_objects), status: "Pull Remote Repository") } }) if numberOfLocalCommits > 0 { - try self.passwordStore.pushRepository(credential: gitCredential, transferProgressBlock: {(current, total, bytes, stop) in + try self.passwordStore.pushRepository(credential: gitCredential, requestGitPassword: self.requestGitPassword(credential:lastPassword:), transferProgressBlock: {(current, total, bytes, stop) in DispatchQueue.main.async { SVProgressHUD.showProgress(Float(current)/Float(total), status: "Push Remote Repository") } @@ -550,6 +549,40 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV searchController.searchBar.selectedScopeButtonIndex = 0 updateSearchResults(for: searchController) } + + private func requestGitPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? { + let sem = DispatchSemaphore(value: 0) + var password: String? + var message = "" + switch credential { + case .http: + message = "Please fill in the password of your Git account." + case .ssh: + message = "Please fill in the password of your SSH key." + } + + DispatchQueue.main.async { + SVProgressHUD.dismiss() + let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = lastPassword ?? "" + textField.isSecureTextEntry = true + }) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + password = alert.textFields!.first!.text + sem.signal() + })) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in + password = nil + sem.signal() + }) + self.present(alert, animated: true, completion: nil) + } + + let _ = sem.wait(timeout: .distantFuture) + return password + } + } extension PasswordsViewController: UISearchResultsUpdating { diff --git a/pass/Helpers/UtilsExtension.swift b/pass/Helpers/UtilsExtension.swift new file mode 100644 index 0000000..418d41e --- /dev/null +++ b/pass/Helpers/UtilsExtension.swift @@ -0,0 +1,20 @@ +// +// UtilsExtension.swift +// pass +// +// Created by Yishi Lin on 13/6/17. +// Copyright © 2017年 Bob Sun. All rights reserved. +// + +import Foundation +import SVProgressHUD +import passKit + +extension Utils { + static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) { + SVProgressHUD.dismiss() + let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: handler)) + controller.present(alert, animated: true, completion: completion) + } +} diff --git a/passKit/Helpers/Utils.swift b/passKit/Helpers/Utils.swift index 60ed403..9959d1e 100644 --- a/passKit/Helpers/Utils.swift +++ b/passKit/Helpers/Utils.swift @@ -9,8 +9,6 @@ import Foundation import SwiftyUserDefaults import KeychainAccess -import UIKit -import SVProgressHUD public class Utils { public static func removeFileIfExists(atPath path: String) { @@ -64,13 +62,6 @@ public class Utils { return randomString } - public static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) { - SVProgressHUD.dismiss() - let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) - alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: handler)) - controller.present(alert, animated: true, completion: completion) - } - public static func getPasswordFromKeychain(name: String) -> String? { let keychain = Keychain(service: Globals.bundleIdentifier) do { diff --git a/passKit/Models/GitCredential.swift b/passKit/Models/GitCredential.swift index 13e07b4..3595527 100644 --- a/passKit/Models/GitCredential.swift +++ b/passKit/Models/GitCredential.swift @@ -10,31 +10,30 @@ import Foundation import UIKit import SwiftyUserDefaults import ObjectiveGit -import SVProgressHUD public struct GitCredential { - public var credential: Credential + private var credential: Credential public enum Credential { - case http(userName: String, controller: UIViewController) - case ssh(userName: String, privateKeyFile: URL, controller: UIViewController) + case http(userName: String) + case ssh(userName: String, privateKeyFile: URL) } public init(credential: Credential) { self.credential = credential } - public func credentialProvider() throws -> GTCredentialProvider { + public func credentialProvider(requestGitPassword: @escaping (Credential, String?) -> String?) throws -> GTCredentialProvider { var attempts = 0 var lastPassword: String? = nil return GTCredentialProvider { (_, _, _) -> (GTCredential?) in var credential: GTCredential? = nil switch self.credential { - case let .http(userName, controller): + case let .http(userName): var newPassword = Utils.getPasswordFromKeychain(name: "gitPassword") if newPassword == nil || attempts != 0 { - if let requestedPassword = self.requestGitPassword(controller, lastPassword) { + if let requestedPassword = requestGitPassword(self.credential, lastPassword) { newPassword = requestedPassword Utils.addPasswordToKeychain(name: "gitPassword", password: newPassword) } else { @@ -44,10 +43,10 @@ public struct GitCredential { attempts += 1 lastPassword = newPassword credential = try? GTCredential(userName: userName, password: newPassword!) - case let .ssh(userName, privateKeyFile, controller): + case let .ssh(userName, privateKeyFile): var newPassword = Utils.getPasswordFromKeychain(name: "gitSSHKeyPassphrase") if newPassword == nil || attempts != 0 { - if let requestedPassword = self.requestGitPassword(controller, lastPassword) { + if let requestedPassword = requestGitPassword(self.credential, lastPassword) { newPassword = requestedPassword Utils.addPasswordToKeychain(name: "gitSSHKeyPassphrase", password: newPassword) } else { @@ -71,38 +70,5 @@ public struct GitCredential { Utils.removeKeychain(name: "gitSSHKeyPassphrase") } } - - private func requestGitPassword(_ controller: UIViewController, _ lastPassword: String?) -> String? { - let sem = DispatchSemaphore(value: 0) - var password: String? - var message = "" - switch credential { - case .http: - message = "Please fill in the password of your Git account." - case .ssh: - message = "Please fill in the password of your SSH key." - } - - DispatchQueue.main.async { - SVProgressHUD.dismiss() - let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = lastPassword ?? "" - textField.isSecureTextEntry = true - }) - alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in - password = alert.textFields!.first!.text - sem.signal() - })) - alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in - password = nil - sem.signal() - }) - controller.present(alert, animated: true, completion: nil) - } - - let _ = sem.wait(timeout: .distantFuture) - return password - } } diff --git a/passKit/Models/PasswordStore.swift b/passKit/Models/PasswordStore.swift index 19360c7..751c014 100644 --- a/passKit/Models/PasswordStore.swift +++ b/passKit/Models/PasswordStore.swift @@ -11,7 +11,6 @@ import CoreData import UIKit import SwiftyUserDefaults import ObjectiveGit -import SVProgressHUD import ObjectivePGP public class PasswordStore { @@ -262,12 +261,13 @@ public class PasswordStore { public func cloneRepository(remoteRepoURL: URL, credential: GitCredential, + requestGitPassword: @escaping (GitCredential.Credential, String?) -> String?, transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void, checkoutProgressBlock: @escaping (String?, UInt, UInt) -> Void) throws { Utils.removeFileIfExists(at: storeURL) Utils.removeFileIfExists(at: tempStoreURL) do { - let credentialProvider = try credential.credentialProvider() + let credentialProvider = try credential.credentialProvider(requestGitPassword: requestGitPassword) let options = [GTRepositoryCloneOptionsCredentialProvider: credentialProvider] storeRepository = try GTRepository.clone(from: remoteRepoURL, toWorkingDirectory: tempStoreURL, options: options, transferProgressBlock:transferProgressBlock) if fm.fileExists(atPath: storeURL.path) { @@ -287,12 +287,12 @@ public class PasswordStore { } } - public func pullRepository(credential: GitCredential, transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void) throws { + public func pullRepository(credential: GitCredential, requestGitPassword: @escaping (GitCredential.Credential, String?) -> String?, transferProgressBlock: @escaping (UnsafePointer, UnsafeMutablePointer) -> Void) throws { guard let storeRepository = storeRepository else { throw AppError.RepositoryNotSetError } do { - let credentialProvider = try credential.credentialProvider() + let credentialProvider = try credential.credentialProvider(requestGitPassword: requestGitPassword) let options = [GTRepositoryRemoteOptionsCredentialProvider: credentialProvider] let remote = try GTRemote(name: "origin", in: storeRepository) try storeRepository.pull(storeRepository.currentBranch(), from: remote, withOptions: options, progress: transferProgressBlock) @@ -538,12 +538,12 @@ public class PasswordStore { return branches.first } - public func pushRepository(credential: GitCredential, transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer) -> Void) throws { + public func pushRepository(credential: GitCredential, requestGitPassword: @escaping (GitCredential.Credential, String?) -> String?, transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer) -> Void) throws { guard let storeRepository = storeRepository else { throw AppError.RepositoryNotSetError } do { - let credentialProvider = try credential.credentialProvider() + let credentialProvider = try credential.credentialProvider(requestGitPassword: requestGitPassword) let options = [GTRepositoryRemoteOptionsCredentialProvider: credentialProvider] if let masterBranch = try getLocalBranch(withName: "master") { let remote = try GTRemote(name: "origin", in: storeRepository)