Refactor GitCredential to simplify it and to add tests

This commit is contained in:
Danny Moesch 2020-08-23 01:15:23 +02:00 committed by Mingshen Sun
parent 56b7b24fce
commit 6044098278
11 changed files with 295 additions and 225 deletions

View file

@ -10,7 +10,7 @@ import passKit
import SVProgressHUD
import UIKit
class GitRepositorySettingsTableViewController: UITableViewController {
class GitRepositorySettingsTableViewController: UITableViewController, PasswordAlertPresenter {
// MARK: - View Outlet
@IBOutlet var gitURLTextField: UITextField!
@ -25,6 +25,14 @@ class GitRepositorySettingsTableViewController: UITableViewController {
private var sshLabel: UILabel?
private let passwordStore = PasswordStore.shared
private let keychain = AppKeychain.shared
private var gitCredential: GitCredential {
GitCredential.from(
authenticationMethod: Defaults.gitAuthenticationMethod,
userName: Defaults.gitUsername,
keyStore: keychain
)
}
private var gitAuthenticationMethod: GitAuthenticationMethod {
get { Defaults.gitAuthenticationMethod }
set {
@ -48,16 +56,6 @@ class GitRepositorySettingsTableViewController: UITableViewController {
set { Defaults.gitUsername = newValue }
}
private var gitCredential: GitCredential {
switch Defaults.gitAuthenticationMethod {
case .password:
return GitCredential(credential: .http(userName: Defaults.gitUsername))
case .key:
let privateKey: String = AppKeychain.shared.get(for: SshKey.PRIVATE.getKeychainKey()) ?? ""
return GitCredential(credential: .ssh(userName: Defaults.gitUsername, privateKey: privateKey))
}
}
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
@ -72,7 +70,7 @@ class GitRepositorySettingsTableViewController: UITableViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Grey out ssh option if ssh_key is not present.
sshLabel?.isEnabled = AppKeychain.shared.contains(key: SshKey.PRIVATE.getKeychainKey())
sshLabel?.isEnabled = keychain.contains(key: SshKey.PRIVATE.getKeychainKey())
updateAuthenticationMethodCheckView(for: gitAuthenticationMethod)
}
@ -97,7 +95,7 @@ class GitRepositorySettingsTableViewController: UITableViewController {
if cell == authPasswordCell {
gitAuthenticationMethod = .password
} else if cell == authSSHKeyCell {
if !AppKeychain.shared.contains(key: SshKey.PRIVATE.getKeychainKey()) {
if !keychain.contains(key: SshKey.PRIVATE.getKeychainKey()) {
Utils.alert(title: "CannotSelectSshKey".localize(), message: "PleaseSetupSshKeyFirst.".localize(), controller: self)
gitAuthenticationMethod = .password
} else {
@ -177,11 +175,12 @@ class GitRepositorySettingsTableViewController: UITableViewController {
SVProgressHUD.showProgress(progress, status: "CheckingOutBranch".localize(self.gitBranchName))
}
let options = self.gitCredential.getCredentialOptions(passwordProvider: self.present)
try self.passwordStore.cloneRepository(
remoteRepoURL: self.gitUrl,
credential: self.gitCredential,
branchName: self.gitBranchName,
requestCredentialPassword: self.requestCredentialPassword,
options: options,
transferProgressBlock: transferProgressBlock,
checkoutProgressBlock: checkoutProgressBlock
)
@ -301,10 +300,6 @@ class GitRepositorySettingsTableViewController: UITableViewController {
present(optionMenu, animated: true)
}
private func requestCredentialPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? {
requestGitCredentialPassword(credential: credential, lastPassword: lastPassword, controller: self)
}
private func updateAuthenticationMethodCheckView(for method: GitAuthenticationMethod) {
let passwordCheckView = authPasswordCell.viewWithTag(1001)
let sshKeyCheckView = authSSHKeyCell.viewWithTag(1001)

View file

@ -10,7 +10,7 @@ import passKit
import SVProgressHUD
import UIKit
class PasswordsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITabBarControllerDelegate, UISearchBarDelegate {
class PasswordsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITabBarControllerDelegate, UISearchBarDelegate, PasswordAlertPresenter {
// Arbitrary threshold to decide whether to show folders or not for only a few entries.
private static let hideSectionHeaderThreshold = 6
@ -19,6 +19,13 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
private var parentPasswordEntity: PasswordEntity?
private let passwordStore = PasswordStore.shared
private let keychain = AppKeychain.shared
private var gitCredential: GitCredential {
GitCredential.from(
authenticationMethod: Defaults.gitAuthenticationMethod,
userName: Defaults.gitUsername,
keyStore: keychain
)
}
private var tapTabBarTime: TimeInterval = 0
private var tapNavigationBarGestureRecognizer: UITapGestureRecognizer!
@ -30,16 +37,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
case unsynced
}
private var gitCredential: GitCredential {
switch Defaults.gitAuthenticationMethod {
case .password:
return GitCredential(credential: .http(userName: Defaults.gitUsername))
case .key:
let privateKey: String = AppKeychain.shared.get(for: SshKey.PRIVATE.getKeychainKey()) ?? ""
return GitCredential(credential: .ssh(userName: Defaults.gitUsername, privateKey: privateKey))
}
}
private lazy var searchController: UISearchController = {
let uiSearchController = UISearchController(searchResultsController: nil)
uiSearchController.searchResultsUpdater = self
@ -193,13 +190,15 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
do {
try self.passwordStore.pullRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword) { git_transfer_progress, _ in
let pullOptions = self.gitCredential.getCredentialOptions(passwordProvider: self.present)
try self.passwordStore.pullRepository(options: pullOptions) { git_transfer_progress, _ in
DispatchQueue.main.async {
SVProgressHUD.showProgress(Float(git_transfer_progress.pointee.received_objects) / Float(git_transfer_progress.pointee.total_objects), status: "PullingFromRemoteRepository".localize())
}
}
if self.passwordStore.numberOfLocalCommits > 0 {
try self.passwordStore.pushRepository(credential: self.gitCredential, requestCredentialPassword: self.requestCredentialPassword) { current, total, _, _ in
let pushOptions = self.gitCredential.getCredentialOptions(passwordProvider: self.present)
try self.passwordStore.pushRepository(options: pushOptions) { current, total, _, _ in
DispatchQueue.main.async {
SVProgressHUD.showProgress(Float(current) / Float(total), status: "PushingToRemoteRepository".localize())
}
@ -212,6 +211,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
self.syncControl.endRefreshing()
}
} catch {
self.gitCredential.delete()
DispatchQueue.main.async {
SVProgressHUD.dismiss()
self.syncControl.endRefreshing()
@ -699,10 +699,6 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
updateSearchResults(for: searchController)
return true
}
private func requestCredentialPassword(credential: GitCredential.Credential, lastPassword: String?) -> String? {
requestGitCredentialPassword(credential: credential, lastPassword: lastPassword, controller: self)
}
}
extension PasswordsViewController: UISearchResultsUpdating {