mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-09-16 09:20:56 +00:00
WIP
This commit is contained in:
parent
9299bf343f
commit
c8d90ba455
@ -4,7 +4,7 @@ import OSLog
|
||||
/// Manages storage and lookup for OpenSSH certificates.
|
||||
public actor OpenSSHCertificateHandler: Sendable {
|
||||
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory())
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.homeDirectory)
|
||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "OpenSSHCertificateHandler")
|
||||
private let writer = OpenSSHPublicKeyWriter()
|
||||
private var keyBlobsAndNames: [AnySecret: (Data, Data)] = [:]
|
||||
|
@ -5,12 +5,12 @@ import OSLog
|
||||
public final class PublicKeyFileStoreController: Sendable {
|
||||
|
||||
private let logger = Logger(subsystem: "com.maxgoedjen.secretive.secretagent", category: "PublicKeyFileStoreController")
|
||||
private let directory: String
|
||||
private let directory: URL
|
||||
private let keyWriter = OpenSSHPublicKeyWriter()
|
||||
|
||||
/// Initializes a PublicKeyFileStoreController.
|
||||
public init(homeDirectory: String) {
|
||||
directory = homeDirectory.appending("/PublicKeys")
|
||||
public init(homeDirectory: URL) {
|
||||
directory = homeDirectory.appending(component: "PublicKeys")
|
||||
}
|
||||
|
||||
/// Writes out the keys specified to disk.
|
||||
@ -20,7 +20,7 @@ public final class PublicKeyFileStoreController: Sendable {
|
||||
logger.log("Writing public keys to disk")
|
||||
if clear {
|
||||
let validPaths = Set(secrets.map { publicKeyPath(for: $0) }).union(Set(secrets.map { sshCertificatePath(for: $0) }))
|
||||
let contentsOfDirectory = (try? FileManager.default.contentsOfDirectory(atPath: directory)) ?? []
|
||||
let contentsOfDirectory = (try? FileManager.default.contentsOfDirectory(atPath: directory.path())) ?? []
|
||||
let fullPathContents = contentsOfDirectory.map { "\(directory)/\($0)" }
|
||||
|
||||
let untracked = Set(fullPathContents)
|
||||
@ -29,7 +29,7 @@ public final class PublicKeyFileStoreController: Sendable {
|
||||
try? FileManager.default.removeItem(at: URL(fileURLWithPath: path))
|
||||
}
|
||||
}
|
||||
try? FileManager.default.createDirectory(at: URL(fileURLWithPath: directory), withIntermediateDirectories: false, attributes: nil)
|
||||
try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: false, attributes: nil)
|
||||
for secret in secrets {
|
||||
let path = publicKeyPath(for: secret)
|
||||
let data = Data(keyWriter.openSSHString(secret: secret).utf8)
|
||||
@ -44,14 +44,14 @@ public final class PublicKeyFileStoreController: Sendable {
|
||||
/// - Warning: This method returning a path does not imply that a key has been written to disk already. This method only describes where it will be written to.
|
||||
public func publicKeyPath<SecretType: Secret>(for secret: SecretType) -> String {
|
||||
let minimalHex = keyWriter.openSSHMD5Fingerprint(secret: secret).replacingOccurrences(of: ":", with: "")
|
||||
return directory.appending("/").appending("\(minimalHex).pub")
|
||||
return directory.appending(component: "\(minimalHex).pub").path()
|
||||
}
|
||||
|
||||
/// Short-circuit check to ship enumerating a bunch of paths if there's nothing in the cert directory.
|
||||
public var hasAnyCertificates: Bool {
|
||||
do {
|
||||
return try FileManager.default
|
||||
.contentsOfDirectory(atPath: directory)
|
||||
.contentsOfDirectory(atPath: directory.path())
|
||||
.filter { $0.hasSuffix("-cert.pub") }
|
||||
.isEmpty == false
|
||||
} catch {
|
||||
@ -65,7 +65,7 @@ public final class PublicKeyFileStoreController: Sendable {
|
||||
/// - Warning: This method returning a path does not imply that a key has a SSH certificates. This method only describes where it will be.
|
||||
public func sshCertificatePath<SecretType: Secret>(for secret: SecretType) -> String {
|
||||
let minimalHex = keyWriter.openSSHMD5Fingerprint(secret: secret).replacingOccurrences(of: ":", with: "")
|
||||
return directory.appending("/").appending("\(minimalHex)-cert.pub")
|
||||
return directory.appending(component: "\(minimalHex)-cert.pub").path()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}()
|
||||
private let updater = Updater(checkOnLaunch: true)
|
||||
private let notifier = Notifier()
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory())
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.homeDirectory)
|
||||
private lazy var agent: Agent = {
|
||||
Agent(storeList: storeList, witness: notifier)
|
||||
}()
|
||||
|
@ -71,11 +71,13 @@ struct IntegrationsView: View {
|
||||
case .gettingStarted:
|
||||
Text("TBD")
|
||||
case .tool:
|
||||
Section(selectedInstruction.tool) {
|
||||
ConfigurationItemView(title: "Configuration File", value: selectedInstruction.configPath, action: .revealInFinder( selectedInstruction.configPath))
|
||||
ConfigurationItemView(title: "Add This:", action: .copy(selectedInstruction.configText)) {
|
||||
ForEach(selectedInstruction.steps) { stepGroup in
|
||||
Section {
|
||||
ConfigurationItemView(title: "Configuration File", value: stepGroup.path, action: .revealInFinder(stepGroup.path))
|
||||
ForEach(stepGroup.steps, id: \.self) { step in
|
||||
ConfigurationItemView(title: "Add This:", action: .copy(step)) {
|
||||
HStack {
|
||||
Text(selectedInstruction.configText)
|
||||
Text(step)
|
||||
.padding(8)
|
||||
.font(.system(.subheadline, design: .monospaced))
|
||||
Spacer()
|
||||
@ -88,6 +90,8 @@ struct IntegrationsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let url = selectedInstruction.website {
|
||||
Section {
|
||||
Link(destination: url) {
|
||||
@ -140,27 +144,39 @@ struct ConfigurationGroup: Identifiable {
|
||||
var instructions: [ConfigurationFileInstructions] = []
|
||||
}
|
||||
|
||||
struct ConfigurationFileInstructions: Identifiable, Hashable {
|
||||
struct ConfigurationFileInstructions: Hashable, Identifiable {
|
||||
|
||||
struct StepGroup: Hashable, Identifiable {
|
||||
let path: String
|
||||
let steps: [String]
|
||||
var id: String { path }
|
||||
}
|
||||
|
||||
var id: ID
|
||||
var tool: String
|
||||
var configPath: String
|
||||
var configText: String
|
||||
var steps: [StepGroup]
|
||||
var website: URL?
|
||||
var note: String?
|
||||
|
||||
init(tool: String, configPath: String, configText: String, website: URL? = nil) {
|
||||
init(tool: String, configPath: String, configText: String, website: URL? = nil, note: String? = nil) {
|
||||
self.id = .tool(tool)
|
||||
self.tool = tool
|
||||
self.configPath = configPath
|
||||
self.configText = configText
|
||||
self.steps = [StepGroup(path: configPath, steps: [configText])]
|
||||
self.website = website
|
||||
self.note = note
|
||||
}
|
||||
|
||||
init(tool: String, steps: [StepGroup], website: URL? = nil, note: String? = nil) {
|
||||
self.id = .tool(tool)
|
||||
self.tool = tool
|
||||
self.steps = steps
|
||||
self.website = website
|
||||
}
|
||||
|
||||
init(_ name: LocalizedStringResource, id: ID) {
|
||||
self.id = id
|
||||
tool = String(localized: name)
|
||||
configPath = ""
|
||||
configText = ""
|
||||
self.steps = []
|
||||
}
|
||||
|
||||
enum ID: Identifiable, Hashable {
|
||||
|
@ -6,7 +6,7 @@ struct SecretDetailView<SecretType: Secret>: View {
|
||||
let secret: SecretType
|
||||
|
||||
private let keyWriter = OpenSSHPublicKeyWriter()
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.agentHomePath)
|
||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.agentHomeURL)
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
@ -39,8 +39,8 @@ struct SecretDetailView<SecretType: Secret>: View {
|
||||
|
||||
extension URL {
|
||||
|
||||
static var agentHomePath: String {
|
||||
URL.homeDirectory.path().replacingOccurrences(of: Bundle.hostBundleID, with: Bundle.agentBundleID)
|
||||
static var agentHomeURL: URL {
|
||||
URL(fileURLWithPath: URL.homeDirectory.path().replacingOccurrences(of: Bundle.hostBundleID, with: Bundle.agentBundleID))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -141,7 +141,6 @@ extension SetupView {
|
||||
|
||||
}
|
||||
|
||||
|
||||
#Preview {
|
||||
SetupView(setupComplete: .constant(false))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user