diff --git a/Cartfile b/Cartfile index b79f135..2d8a890 100644 --- a/Cartfile +++ b/Cartfile @@ -1,5 +1,5 @@ github "SVProgressHUD/SVProgressHUD" github "radex/SwiftyUserDefaults" -github "libgit2/objective-git" -github "mssun/SwiftPasscodeLock" "master" +github "mssun/objective-git" "master" +github "zahlz/SwiftPasscodeLock" "master" github "bitserf/FavIcon" diff --git a/pass/Base.lproj/Main.storyboard b/pass/Base.lproj/Main.storyboard index 3ade99c..2e89a67 100644 --- a/pass/Base.lproj/Main.storyboard +++ b/pass/Base.lproj/Main.storyboard @@ -329,42 +329,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -407,7 +377,7 @@ - + @@ -415,8 +385,8 @@ - + @@ -452,7 +422,7 @@ - + @@ -472,7 +442,7 @@ - + diff --git a/pass/Controllers/GitServerSettingTableViewController.swift b/pass/Controllers/GitServerSettingTableViewController.swift index 3d50945..2ae349b 100644 --- a/pass/Controllers/GitServerSettingTableViewController.swift +++ b/pass/Controllers/GitServerSettingTableViewController.swift @@ -13,9 +13,11 @@ class GitServerSettingTableViewController: UITableViewController { @IBOutlet weak var gitRepositoryURLTextField: UITextField! @IBOutlet weak var usernameTextField: UITextField! - @IBOutlet weak var passwordTextField: UITextField! +// @IBOutlet weak var passwordTextField: UITextField! @IBOutlet weak var authenticationTableViewCell: UITableViewCell! +// var password: String? + var authenticationMethod = Defaults[.gitRepositoryAuthenticationMethod] @@ -25,7 +27,7 @@ class GitServerSettingTableViewController: UITableViewController { gitRepositoryURLTextField.text = url.absoluteString } usernameTextField.text = Defaults[.gitRepositoryUsername] - passwordTextField.text = Defaults[.gitRepositoryPassword] +// passwordTextField.text = Defaults[.gitRepositoryPassword] authenticationTableViewCell.detailTextLabel?.text = authenticationMethod } @@ -68,7 +70,28 @@ class GitServerSettingTableViewController: UITableViewController { return true } - @IBAction func save(segue: UIStoryboardSegue) { + @IBAction func save(_ sender: Any) { + if authenticationMethod == "Password" { + let alert = UIAlertController(title: "Password", message: "Please fill in the password of your Git account.", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + Defaults[.gitRepositoryPassword] = alert.textFields?.first?.text + if self.shouldPerformSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) { + self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) + } + })) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = Defaults[.gitRepositoryPassword] + textField.isSecureTextEntry = true + }) + self.present(alert, animated: true, completion: nil) + } else { + if self.shouldPerformSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) { + self.performSegue(withIdentifier: "saveGitServerSettingSegue", sender: self) + } + } + } + + @IBAction func saveAuthMethod(segue: UIStoryboardSegue) { if let controller = segue.source as? UITableViewController { if controller.tableView.indexPathForSelectedRow == IndexPath(row: 0, section:0) { authenticationMethod = "Password" diff --git a/pass/Controllers/PasswordRepositorySettingsTableViewController.swift b/pass/Controllers/PasswordRepositorySettingsTableViewController.swift index 08caec2..fd7c5fa 100644 --- a/pass/Controllers/PasswordRepositorySettingsTableViewController.swift +++ b/pass/Controllers/PasswordRepositorySettingsTableViewController.swift @@ -43,21 +43,26 @@ class PasswordRepositorySettingsTableViewController: BasicStaticTableViewControl if let controller = segue.source as? GitServerSettingTableViewController { let gitRepostiroyURL = controller.gitRepositoryURLTextField.text! let username = controller.usernameTextField.text! - let password = controller.passwordTextField.text! + let password = Defaults[.gitRepositoryPassword] let auth = controller.authenticationMethod - if Defaults[.gitRepositoryURL] == nil || gitRepostiroyURL != Defaults[.gitRepositoryURL]!.absoluteString { + if Defaults[.gitRepositoryURL] == nil || + Defaults[.gitRepositoryURL]!.absoluteString != gitRepostiroyURL || + auth != Defaults[.gitRepositoryAuthenticationMethod] || + username != Defaults[.gitRepositoryUsername] || + password != Defaults[.gitRepositoryPassword] { + SVProgressHUD.setDefaultMaskType(.black) SVProgressHUD.setDefaultStyle(.light) SVProgressHUD.show(withStatus: "Prepare Repository") var gitCredential: GitCredential if auth == "Password" { - gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, password: password)) + gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, password: password!)) } else { gitCredential = GitCredential(credential: GitCredential.Credential.ssh(userName: username, password: Defaults[.gitRepositorySSHPrivateKeyPassphrase]!, publicKeyFile: Globals.sshPublicKeyURL, privateKeyFile: Globals.sshPrivateKeyURL)) } - - DispatchQueue.global(qos: .userInitiated).async { + let dispatchQueue = DispatchQueue.global(qos: .userInitiated) + dispatchQueue.async { do { try PasswordStore.shared.cloneRepository(remoteRepoURL: URL(string: gitRepostiroyURL)!, credential: gitCredential, @@ -79,6 +84,7 @@ class PasswordRepositorySettingsTableViewController: BasicStaticTableViewControl Defaults[.gitRepositoryUsername] = username Defaults[.gitRepositoryPassword] = password Defaults[.gitRepositoryAuthenticationMethod] = auth + Defaults[.gitRepositoryPasswordAttempts] = 0 SVProgressHUD.showSuccess(withStatus: "Done") SVProgressHUD.dismiss(withDelay: 1) } diff --git a/pass/Helpers/DefaultsKeys.swift b/pass/Helpers/DefaultsKeys.swift index da35918..4f0253f 100644 --- a/pass/Helpers/DefaultsKeys.swift +++ b/pass/Helpers/DefaultsKeys.swift @@ -28,6 +28,7 @@ extension DefaultsKeys { static let gitRepositoryAuthenticationMethod = DefaultsKey("gitRepositoryAuthenticationMethod") static let gitRepositoryUsername = DefaultsKey("gitRepositoryUsername") static let gitRepositoryPassword = DefaultsKey("gitRepositoryPassword") + static let gitRepositoryPasswordAttempts = DefaultsKey("gitRepositoryPasswordAttempts") static let gitRepositorySSHPublicKeyURL = DefaultsKey("gitRepositorySSHPublicKeyURL") static let gitRepositorySSHPrivateKeyURL = DefaultsKey("gitRepositorySSHPrivateKeyURL") static let gitRepositorySSHPrivateKeyPassphrase = DefaultsKey("gitRepositorySSHPrivateKeyPassphrase") diff --git a/pass/Models/PasswordStore.swift b/pass/Models/PasswordStore.swift index 90a490c..05e9e7c 100644 --- a/pass/Models/PasswordStore.swift +++ b/pass/Models/PasswordStore.swift @@ -12,6 +12,7 @@ import CoreData import UIKit import SwiftyUserDefaults import ObjectiveGit +import SVProgressHUD struct GitCredential { @@ -23,15 +24,53 @@ struct GitCredential { var credential: Credential func credentialProvider() throws -> GTCredentialProvider { - return GTCredentialProvider { (_, _, _) -> (GTCredential) in - let credential: GTCredential? + return GTCredentialProvider { (_, _, _) -> (GTCredential?) in + var credential: GTCredential? = nil switch self.credential { case let .http(userName, password): - credential = try? GTCredential(userName: userName, password: password) + print(Defaults[.gitRepositoryPasswordAttempts]) + var newPassword: String = password + if Defaults[.gitRepositoryPasswordAttempts] != 0 { + let sem = DispatchSemaphore(value: 0) + DispatchQueue.main.async { + SVProgressHUD.dismiss() + if var topController = UIApplication.shared.keyWindow?.rootViewController { + while let presentedViewController = topController.presentedViewController { + topController = presentedViewController + } + let alert = UIAlertController(title: "Password", message: "Please fill in the password of your Git account.", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + newPassword = alert.textFields!.first!.text! + Defaults[.gitRepositoryPassword] = newPassword + sem.signal() + })) + if Defaults[.gitRepositoryPasswordAttempts] == 3 { + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in + Defaults[.gitRepositoryPasswordAttempts] = -1 + sem.signal() + }) + } + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = Defaults[.gitRepositoryPassword] + textField.isSecureTextEntry = true + }) + topController.present(alert, animated: true, completion: nil) + } + } + let _ = sem.wait(timeout: DispatchTime.distantFuture) + } + if Defaults[.gitRepositoryPasswordAttempts] == -1 { + Defaults[.gitRepositoryPasswordAttempts] = 0 + return nil + } + print("usernmae: \(userName)") + print("password: \(newPassword)") + Defaults[.gitRepositoryPasswordAttempts] += 1 + credential = try? GTCredential(userName: userName, password: newPassword) case let .ssh(userName, password, publicKeyFile, privateKeyFile): credential = try? GTCredential(userName: userName, publicKeyURL: publicKeyFile, privateKeyURL: privateKeyFile, passphrase: password) } - return credential ?? GTCredential() + return credential } } } @@ -270,7 +309,7 @@ class PasswordStore { let newTree = addEntryToGTTree(fileData: fileData, filename: filename) let headReference = try storeRepository!.headReference() let commitEnum = try GTEnumerator(repository: storeRepository!) - try commitEnum.pushSHA(headReference.targetOID.sha) + try commitEnum.pushSHA(headReference.targetOID.sha!) let parent = commitEnum.nextObject() as! GTCommit progressBlock(0.5) let commit = try storeRepository!.createCommit(with: newTree, message: message, parents: [parent], updatingReferenceNamed: headReference.name) @@ -287,7 +326,7 @@ class PasswordStore { let newTree = removeEntryFromGTTree(filename: filename) let headReference = try storeRepository!.headReference() let commitEnum = try GTEnumerator(repository: storeRepository!) - try commitEnum.pushSHA(headReference.targetOID.sha) + try commitEnum.pushSHA(headReference.targetOID.sha!) let parent = commitEnum.nextObject() as! GTCommit progressBlock(0.5) let commit = try storeRepository!.createCommit(with: newTree, message: message, parents: [parent], updatingReferenceNamed: headReference.name)