Refactor logic of requesting git/ssh password callback
This commit is contained in:
parent
a12847e887
commit
b35d79031d
2 changed files with 49 additions and 75 deletions
|
|
@ -112,7 +112,7 @@ class SettingsTableViewController: UITableViewController {
|
||||||
SVProgressHUD.show(withStatus: "Prepare Repository")
|
SVProgressHUD.show(withStatus: "Prepare Repository")
|
||||||
var gitCredential: GitCredential
|
var gitCredential: GitCredential
|
||||||
if auth == "Password" {
|
if auth == "Password" {
|
||||||
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, password: password!))
|
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: username, password: password!, requestGitPassword: requestGitPassword))
|
||||||
} else {
|
} else {
|
||||||
gitCredential = GitCredential(
|
gitCredential = GitCredential(
|
||||||
credential: GitCredential.Credential.ssh(
|
credential: GitCredential.Credential.ssh(
|
||||||
|
|
@ -120,7 +120,7 @@ class SettingsTableViewController: UITableViewController {
|
||||||
password: Utils.getPasswordFromKeychain(name: "gitSSHPrivateKeyPassphrase") ?? "",
|
password: Utils.getPasswordFromKeychain(name: "gitSSHPrivateKeyPassphrase") ?? "",
|
||||||
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
||||||
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
||||||
passwordNotSetCallback: self.requestSshKeyPassword
|
requestSSHKeyPassword: self.requestGitPassword
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -204,31 +204,32 @@ class SettingsTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestSshKeyPassword() -> String {
|
private func requestGitPassword(message: String) -> String? {
|
||||||
let sem = DispatchSemaphore(value: 0)
|
let sem = DispatchSemaphore(value: 0)
|
||||||
var newPassword = ""
|
var password: String?
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
SVProgressHUD.dismiss()
|
SVProgressHUD.dismiss()
|
||||||
let alert = UIAlertController(title: "Password", message: "Please fill in the password of your SSH key.", preferredStyle: UIAlertControllerStyle.alert)
|
let alert = UIAlertController(title: "Password", message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||||
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
|
||||||
newPassword = alert.textFields!.first!.text!
|
|
||||||
sem.signal()
|
|
||||||
}))
|
|
||||||
|
|
||||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
||||||
textField.text = self.passwordStore.gitPassword
|
textField.text = self.passwordStore.gitPassword
|
||||||
textField.isSecureTextEntry = true
|
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)
|
self.present(alert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = sem.wait(timeout: DispatchTime.distantFuture)
|
let _ = sem.wait(timeout: .distantFuture)
|
||||||
return newPassword
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
func actOnPasswordStoreErasedNotification() {
|
func actOnPasswordStoreErasedNotification() {
|
||||||
setPGPKeyTableViewCellDetailText()
|
setPGPKeyTableViewCellDetailText()
|
||||||
setPasswordRepositoryTableViewCellDetailText()
|
setPasswordRepositoryTableViewCellDetailText()
|
||||||
|
|
|
||||||
|
|
@ -14,76 +14,48 @@ import ObjectiveGit
|
||||||
import SVProgressHUD
|
import SVProgressHUD
|
||||||
|
|
||||||
struct GitCredential {
|
struct GitCredential {
|
||||||
|
var credential: Credential
|
||||||
|
|
||||||
enum Credential {
|
enum Credential {
|
||||||
case http(userName: String, password: String)
|
case http(userName: String, password: String, requestGitPassword: ((_ message: String) -> String?)?)
|
||||||
case ssh(userName: String, password: String, publicKeyFile: URL, privateKeyFile: URL, passwordNotSetCallback: (() -> String)? )
|
case ssh(userName: String, password: String, publicKeyFile: URL, privateKeyFile: URL, requestSSHKeyPassword: ((_ message: String) -> String?)? )
|
||||||
|
}
|
||||||
|
|
||||||
|
init(credential: Credential) {
|
||||||
|
self.credential = credential
|
||||||
|
Defaults[.gitPasswordAttempts] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var credential: Credential
|
|
||||||
|
|
||||||
func credentialProvider() throws -> GTCredentialProvider {
|
func credentialProvider() throws -> GTCredentialProvider {
|
||||||
return GTCredentialProvider { (_, _, _) -> (GTCredential?) in
|
return GTCredentialProvider { (_, _, _) -> (GTCredential?) in
|
||||||
var credential: GTCredential? = nil
|
var credential: GTCredential? = nil
|
||||||
|
|
||||||
switch self.credential {
|
switch self.credential {
|
||||||
case let .http(userName, password):
|
case let .http(userName, password, requestGitPassword):
|
||||||
print(Defaults[.gitPasswordAttempts])
|
var newPassword = password
|
||||||
var newPassword: String = password
|
|
||||||
if Defaults[.gitPasswordAttempts] != 0 {
|
if Defaults[.gitPasswordAttempts] != 0 {
|
||||||
let sem = DispatchSemaphore(value: 0)
|
if let requestGitPasswordCallback = requestGitPassword,
|
||||||
DispatchQueue.main.async {
|
let requestedPassword = requestGitPasswordCallback("Please fill in the password of your Git account.") {
|
||||||
SVProgressHUD.dismiss()
|
newPassword = requestedPassword
|
||||||
if var topController = UIApplication.shared.keyWindow?.rootViewController {
|
} else {
|
||||||
while let presentedViewController = topController.presentedViewController {
|
return nil
|
||||||
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!
|
|
||||||
PasswordStore.shared.gitPassword = newPassword
|
|
||||||
sem.signal()
|
|
||||||
}))
|
|
||||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
|
|
||||||
Defaults[.gitPasswordAttempts] = -1
|
|
||||||
sem.signal()
|
|
||||||
})
|
|
||||||
alert.addTextField(configurationHandler: {(textField: UITextField!) in
|
|
||||||
textField.text = PasswordStore.shared.gitPassword
|
|
||||||
textField.isSecureTextEntry = true
|
|
||||||
})
|
|
||||||
topController.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let _ = sem.wait(timeout: DispatchTime.distantFuture)
|
|
||||||
}
|
|
||||||
if Defaults[.gitPasswordAttempts] == -1 {
|
|
||||||
Defaults[.gitPasswordAttempts] = 0
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
Defaults[.gitPasswordAttempts] += 1
|
Defaults[.gitPasswordAttempts] += 1
|
||||||
PasswordStore.shared.gitPassword = newPassword
|
|
||||||
credential = try? GTCredential(userName: userName, password: newPassword)
|
credential = try? GTCredential(userName: userName, password: newPassword)
|
||||||
case let .ssh(userName, password, publicKeyFile, privateKeyFile, passwordNotSetCallback):
|
case let .ssh(userName, password, publicKeyFile, privateKeyFile, requestSSHKeyPassword):
|
||||||
|
var newPassword = password
|
||||||
var newPassword:String? = password
|
if Defaults[.gitPasswordAttempts] != 0 {
|
||||||
|
if let requestSSHKeyPasswordCallback = requestSSHKeyPassword,
|
||||||
// Check if the private key is encrypted
|
let requestedPassword = requestSSHKeyPasswordCallback("Please fill in the password of your SSH key.") {
|
||||||
let encrypted = try? String(contentsOf: privateKeyFile).contains("ENCRYPTED")
|
newPassword = requestedPassword
|
||||||
|
} else {
|
||||||
// Request password if not already set
|
return nil
|
||||||
if encrypted == nil && password == "" {
|
|
||||||
newPassword = passwordNotSetCallback!()
|
}
|
||||||
}
|
}
|
||||||
|
Defaults[.gitPasswordAttempts] += 1
|
||||||
// Save password for the future
|
|
||||||
Utils.addPasswordToKeychain(name: "gitSSHPrivateKeyPassphrase", password: newPassword!)
|
|
||||||
|
|
||||||
// nil is expected in case of empty password
|
|
||||||
if newPassword == "" {
|
|
||||||
newPassword = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
credential = try? GTCredential(userName: userName, publicKeyURL: publicKeyFile, privateKeyURL: privateKeyFile, passphrase: newPassword)
|
credential = try? GTCredential(userName: userName, publicKeyURL: publicKeyFile, privateKeyURL: privateKeyFile, passphrase: newPassword)
|
||||||
}
|
}
|
||||||
return credential
|
return credential
|
||||||
|
|
@ -184,7 +156,8 @@ class PasswordStore {
|
||||||
|
|
||||||
public func initGitCredential() {
|
public func initGitCredential() {
|
||||||
if Defaults[.gitAuthenticationMethod] == "Password" {
|
if Defaults[.gitAuthenticationMethod] == "Password" {
|
||||||
gitCredential = GitCredential(credential: GitCredential.Credential.http(userName: Defaults[.gitUsername] ?? "", password: Utils.getPasswordFromKeychain(name: "gitPassword") ?? ""))
|
let httpCredential = GitCredential.Credential.http(userName: Defaults[.gitUsername] ?? "", password: Utils.getPasswordFromKeychain(name: "gitPassword") ?? "", requestGitPassword: nil)
|
||||||
|
gitCredential = GitCredential(credential: httpCredential)
|
||||||
} else if Defaults[.gitAuthenticationMethod] == "SSH Key"{
|
} else if Defaults[.gitAuthenticationMethod] == "SSH Key"{
|
||||||
gitCredential = GitCredential(
|
gitCredential = GitCredential(
|
||||||
credential: GitCredential.Credential.ssh(
|
credential: GitCredential.Credential.ssh(
|
||||||
|
|
@ -192,7 +165,7 @@ class PasswordStore {
|
||||||
password: gitSSHPrivateKeyPassphrase ?? "",
|
password: gitSSHPrivateKeyPassphrase ?? "",
|
||||||
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
publicKeyFile: Globals.gitSSHPublicKeyURL,
|
||||||
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
privateKeyFile: Globals.gitSSHPrivateKeyURL,
|
||||||
passwordNotSetCallback: nil
|
requestSSHKeyPassword: nil
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue