PasswordStore: allow to pass in a specific PGPAgent implementation (for testing)
This commit is contained in:
parent
77f85ccdd1
commit
e3de11f71c
3 changed files with 15 additions and 10 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
public class PGPAgent {
|
public class PGPAgent {
|
||||||
public static let shared = PGPAgent()
|
public static let shared = PGPAgent()
|
||||||
|
|
||||||
private let keyStore: KeyStore
|
let keyStore: KeyStore
|
||||||
private var pgpInterface: PGPInterface?
|
private var pgpInterface: PGPInterface?
|
||||||
private var latestDecryptStatus = true
|
private var latestDecryptStatus = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public class PasswordStore {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public var storeURL: URL
|
public var storeURL: URL
|
||||||
|
private let pgpAgent: PGPAgent
|
||||||
|
|
||||||
public var gitRepository: GitRepository?
|
public var gitRepository: GitRepository?
|
||||||
|
|
||||||
|
|
@ -84,8 +85,9 @@ public class PasswordStore {
|
||||||
gitRepository?.numberOfCommits()
|
gitRepository?.numberOfCommits()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(url: URL = Globals.repositoryURL) {
|
init(url: URL = Globals.repositoryURL, pgpAgent: PGPAgent = .shared) {
|
||||||
self.storeURL = url
|
self.storeURL = url
|
||||||
|
self.pgpAgent = pgpAgent
|
||||||
|
|
||||||
// Migration
|
// Migration
|
||||||
importExistingKeysIntoKeychain()
|
importExistingKeysIntoKeychain()
|
||||||
|
|
@ -359,14 +361,14 @@ public class PasswordStore {
|
||||||
eraseStoreData()
|
eraseStoreData()
|
||||||
|
|
||||||
// Delete PGP key, SSH key and other secrets from the keychain.
|
// Delete PGP key, SSH key and other secrets from the keychain.
|
||||||
AppKeychain.shared.removeAllContent()
|
pgpAgent.keyStore.removeAllContent()
|
||||||
|
|
||||||
// Delete default settings.
|
// Delete default settings.
|
||||||
Defaults.removeAll()
|
Defaults.removeAll()
|
||||||
|
|
||||||
// Delete cache explicitly.
|
// Delete cache explicitly.
|
||||||
PasscodeLock.shared.delete()
|
PasscodeLock.shared.delete()
|
||||||
PGPAgent.shared.uninitKeys()
|
pgpAgent.uninitKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the number of discarded commits
|
// return the number of discarded commits
|
||||||
|
|
@ -395,7 +397,7 @@ public class PasswordStore {
|
||||||
public func decrypt(passwordEntity: PasswordEntity, keyID: String? = nil, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Password {
|
public func decrypt(passwordEntity: PasswordEntity, keyID: String? = nil, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Password {
|
||||||
let url = passwordEntity.fileURL(in: storeURL)
|
let url = passwordEntity.fileURL(in: storeURL)
|
||||||
let encryptedData = try Data(contentsOf: url)
|
let encryptedData = try Data(contentsOf: url)
|
||||||
let data: Data? = try PGPAgent.shared.decrypt(encryptedData: encryptedData, keyID: keyID, requestPGPKeyPassphrase: requestPGPKeyPassphrase)
|
let data: Data? = try pgpAgent.decrypt(encryptedData: encryptedData, keyID: keyID, requestPGPKeyPassphrase: requestPGPKeyPassphrase)
|
||||||
guard let decryptedData = data else {
|
guard let decryptedData = data else {
|
||||||
throw AppError.decryption
|
throw AppError.decryption
|
||||||
}
|
}
|
||||||
|
|
@ -415,9 +417,9 @@ public class PasswordStore {
|
||||||
return []
|
return []
|
||||||
}()
|
}()
|
||||||
if !keyIDs.isEmpty {
|
if !keyIDs.isEmpty {
|
||||||
return try PGPAgent.shared.encrypt(plainData: password.plainData, keyIDs: keyIDs)
|
return try pgpAgent.encrypt(plainData: password.plainData, keyIDs: keyIDs)
|
||||||
}
|
}
|
||||||
return try PGPAgent.shared.encryptWithAllKeys(plainData: password.plainData)
|
return try pgpAgent.encryptWithAllKeys(plainData: password.plainData)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func removeGitSSHKeys() {
|
public func removeGitSSHKeys() {
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,18 @@ import XCTest
|
||||||
final class PasswordStoreTest: XCTestCase {
|
final class PasswordStoreTest: XCTestCase {
|
||||||
private let localRepoURL: URL = Globals.sharedContainerURL.appendingPathComponent("Library/password-store-test/")
|
private let localRepoURL: URL = Globals.sharedContainerURL.appendingPathComponent("Library/password-store-test/")
|
||||||
|
|
||||||
|
private var pgpAgent: PGPAgent! = nil
|
||||||
private var passwordStore: PasswordStore! = nil
|
private var passwordStore: PasswordStore! = nil
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
passwordStore = PasswordStore(url: localRepoURL)
|
pgpAgent = PGPAgent()
|
||||||
|
passwordStore = PasswordStore(url: localRepoURL, pgpAgent: pgpAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
passwordStore.erase()
|
passwordStore.erase()
|
||||||
passwordStore = nil
|
passwordStore = nil
|
||||||
|
pgpAgent = nil
|
||||||
|
|
||||||
Defaults.removeAll()
|
Defaults.removeAll()
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +81,7 @@ final class PasswordStoreTest: XCTestCase {
|
||||||
XCTAssertTrue(AppKeychain.shared.contains(key: PGPKey.PUBLIC.getKeychainKey()))
|
XCTAssertTrue(AppKeychain.shared.contains(key: PGPKey.PUBLIC.getKeychainKey()))
|
||||||
XCTAssertEqual(Defaults.gitSignatureName, "Test User")
|
XCTAssertEqual(Defaults.gitSignatureName, "Test User")
|
||||||
XCTAssertTrue(PasscodeLock.shared.hasPasscode)
|
XCTAssertTrue(PasscodeLock.shared.hasPasscode)
|
||||||
XCTAssertTrue(PGPAgent.shared.isInitialized())
|
XCTAssertTrue(pgpAgent.isInitialized())
|
||||||
|
|
||||||
expectation(forNotification: .passwordStoreUpdated, object: nil)
|
expectation(forNotification: .passwordStoreUpdated, object: nil)
|
||||||
expectation(forNotification: .passwordStoreErased, object: nil)
|
expectation(forNotification: .passwordStoreErased, object: nil)
|
||||||
|
|
@ -88,7 +91,7 @@ final class PasswordStoreTest: XCTestCase {
|
||||||
XCTAssertFalse(AppKeychain.shared.contains(key: PGPKey.PUBLIC.getKeychainKey()))
|
XCTAssertFalse(AppKeychain.shared.contains(key: PGPKey.PUBLIC.getKeychainKey()))
|
||||||
XCTAssertFalse(Defaults.hasKey(\.gitSignatureName))
|
XCTAssertFalse(Defaults.hasKey(\.gitSignatureName))
|
||||||
XCTAssertFalse(PasscodeLock.shared.hasPasscode)
|
XCTAssertFalse(PasscodeLock.shared.hasPasscode)
|
||||||
XCTAssertFalse(PGPAgent.shared.isInitialized())
|
XCTAssertFalse(pgpAgent.isInitialized())
|
||||||
waitForExpectations(timeout: 1, handler: nil)
|
waitForExpectations(timeout: 1, handler: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue