Provide the 'remember git credential passphrases' option

This commit is contained in:
Yishi Lin 2017-10-08 21:37:58 +08:00
parent c57ae4f88e
commit d0bad8660b
11 changed files with 97 additions and 44 deletions

View file

@ -35,7 +35,8 @@ public extension DefaultsKeys {
static let isHideUnknownOn = DefaultsKey<Bool>("isHideUnknownOn")
static let isHideOTPOn = DefaultsKey<Bool>("isHideOTPOn")
static let isRememberPassphraseOn = DefaultsKey<Bool>("isRememberPassphraseOn")
static let isRememberPGPPassphraseOn = DefaultsKey<Bool>("isRememberPGPPassphraseOn")
static let isRememberGitCredentialPassphraseOn = DefaultsKey<Bool>("isRememberGitCredentialPassphraseOn")
static let isShowFolderOn = DefaultsKey<Bool>("isShowFolderOn")
static let passwordGeneratorFlavor = DefaultsKey<String>("passwordGeneratorFlavor")

View file

@ -26,38 +26,39 @@ public struct GitCredential {
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):
var newPassword = self.passwordStore.gitPassword
if newPassword == nil || attempts != 0 {
var lastPassword = self.passwordStore.gitPassword
if lastPassword == nil || attempts != 0 {
if let requestedPassword = requestGitPassword(self.credential, lastPassword) {
newPassword = requestedPassword
self.passwordStore.gitPassword = newPassword
if SharedDefaults[.isRememberGitCredentialPassphraseOn] {
self.passwordStore.gitPassword = requestedPassword
}
lastPassword = requestedPassword
} else {
return nil
}
}
attempts += 1
lastPassword = newPassword
credential = try? GTCredential(userName: userName, password: newPassword!)
credential = try? GTCredential(userName: userName, password: lastPassword!)
case let .ssh(userName, privateKeyFile):
// remarks: in fact, attempts > 1 never happens even with the wrong passphrase
var newPassword = self.passwordStore.gitSSHPrivateKeyPassphrase
if newPassword == nil || attempts != 0 {
var lastPassword = self.passwordStore.gitSSHPrivateKeyPassphrase
if lastPassword == nil || attempts != 0 {
if let requestedPassword = requestGitPassword(self.credential, lastPassword) {
newPassword = requestedPassword
self.passwordStore.gitSSHPrivateKeyPassphrase = newPassword
if SharedDefaults[.isRememberGitCredentialPassphraseOn] {
self.passwordStore.gitSSHPrivateKeyPassphrase = requestedPassword
}
lastPassword = requestedPassword
} else {
return nil
}
}
attempts += 1
lastPassword = newPassword
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: newPassword!)
credential = try? GTCredential(userName: userName, publicKeyURL: nil, privateKeyURL: privateKeyFile, passphrase: lastPassword!)
}
return credential
}
@ -66,9 +67,9 @@ public struct GitCredential {
public func delete() {
switch credential {
case .http:
Utils.removeKeychain(name: "gitPassword")
self.passwordStore.gitPassword = nil
case .ssh:
Utils.removeKeychain(name: "gitSSHKeyPassphrase")
self.passwordStore.gitSSHPrivateKeyPassphrase = nil
}
}
}

View file

@ -120,6 +120,7 @@ public class PasswordStore {
print(Globals.documentPathLegacy)
print(Globals.libraryPathLegacy)
migrateIfNeeded()
backwardCompatibility()
do {
if fm.fileExists(atPath: storeURL.path) {
@ -166,6 +167,13 @@ public class PasswordStore {
updatePasswordEntityCoreData()
}
private func backwardCompatibility() {
// For the newly-introduced isRememberGitCredentialPassphraseOn (20171008)
if (self.gitPassword != nil || self.gitSSHPrivateKeyPassphrase != nil) && SharedDefaults[.isRememberGitCredentialPassphraseOn] == false {
SharedDefaults[.isRememberGitCredentialPassphraseOn] = true
}
}
enum SSHKeyType {
case `public`, secret
}
@ -328,7 +336,6 @@ public class PasswordStore {
let remote = try GTRemote(name: "origin", in: storeRepository)
try storeRepository.pull(storeRepository.currentBranch(), from: remote, withOptions: options, progress: transferProgressBlock)
} catch {
credential.delete()
throw(error)
}
DispatchQueue.main.async {
@ -581,7 +588,6 @@ public class PasswordStore {
try storeRepository.push(masterBranch, to: remote, withOptions: options, progress: transferProgressBlock)
}
} catch {
credential.delete()
throw(error)
}
}
@ -865,7 +871,7 @@ public class PasswordStore {
Utils.removeFileIfExists(atPath: Globals.gitSSHPrivateKeyPath)
Defaults.remove(.gitSSHPrivateKeyArmor)
Defaults.remove(.gitSSHPrivateKeyURL)
Utils.removeKeychain(name: ".gitSSHPrivateKeyPassphrase")
self.gitSSHPrivateKeyPassphrase = nil
}
public func gitSSHKeyExists(inFileSharing: Bool = false) -> Bool {