do not search too far for .gpg-id + lots of tests for that

This commit is contained in:
Lysann Tranvouez 2026-03-12 22:44:42 +01:00
parent 5c416bfb21
commit cd6dd43dae
2 changed files with 177 additions and 22 deletions

View file

@ -411,8 +411,7 @@ public class PasswordStore {
return [keyID]
}
if Defaults.isEnableGPGIDOn {
let encryptedDataPath = password.fileURL(in: storeURL)
return findGPGIDs(from: encryptedDataPath)
return findGPGIDs(underPath: password.path)
}
return []
}()
@ -430,6 +429,37 @@ public class PasswordStore {
AppKeychain.shared.removeContent(for: SSHKey.PRIVATE.getKeychainKey())
gitSSHPrivateKeyPassphrase = nil
}
func findGPGIDs(underPath relativePath: String) -> [String] {
guard let gpgIDFileURL = findGPGIDFile(atPath: relativePath) else {
return []
}
let allKeysSeparatedByNewline = (try? String(contentsOf: gpgIDFileURL)) ?? ""
return allKeysSeparatedByNewline
.split(separator: "\n")
.map { String($0).trimmed }
.filter { !$0.isEmpty }
}
func findGPGIDFile(atPath relativePath: String) -> URL? {
// Walk up the directory hierarchy, but never escape the store root
let storeRoot = storeURL.absoluteURL.resolvingSymlinksInPath()
var current = storeRoot.appendingPathComponent(relativePath).resolvingSymlinksInPath()
while current.path.hasPrefix(storeRoot.path) {
let candidate = current.appendingPathComponent(".gpg-id")
var isDir: ObjCBool = false
if FileManager.default.fileExists(atPath: candidate.path, isDirectory: &isDir), !isDir.boolValue {
return candidate.standardizedFileURL
}
let parent = current.deletingLastPathComponent().resolvingSymlinksInPath()
if parent.path == current.path {
break
}
current = parent
}
return nil
}
}
extension PasswordStore {
@ -462,18 +492,3 @@ extension PasswordStore {
return try gitRepository.commit(signature: gitSignatureForNow, message: message)
}
}
func findGPGIDs(from url: URL) -> [String] {
var path = url
while !FileManager.default.fileExists(atPath: path.appendingPathComponent(".gpg-id").path),
path.path != "file:///" {
path = path.deletingLastPathComponent()
}
path = path.appendingPathComponent(".gpg-id")
let allKeysSeparatedByNewline = (try? String(contentsOf: path)) ?? ""
return allKeysSeparatedByNewline
.split(separator: "\n")
.map { String($0).trimmed }
.filter { !$0.isEmpty }
}