This commit is contained in:
Max Goedjen
2024-08-26 13:56:49 -07:00
parent 56a662a9dd
commit 74a516f6fd
8 changed files with 78 additions and 66 deletions

View File

@@ -5,7 +5,7 @@ import SecretKit
import AppKit
/// The `Agent` is an implementation of an SSH agent. It manages coordination and access between a socket, traces requests, notifies witnesses and passes requests to stores.
public actor Agent {
@MainActor public final class Agent {
private let storeList: SecretStoreList
private let witness: SigningWitness?

View File

@@ -2,13 +2,13 @@ import Foundation
import Combine
/// Type eraser for SecretStore.
public class AnySecretStore: SecretStore {
@MainActor public class AnySecretStore: SecretStore {
let base: Any
private let _isAvailable: () -> Bool
private let _id: () -> UUID
private let _name: () -> String
private let _secrets: () -> [AnySecret]
private let _secrets: @MainActor () -> [AnySecret]
private let _sign: (Data, AnySecret, SigningRequestProvenance) throws -> Data
private let _verify: (Data, Data, AnySecret) throws -> Bool
private let _existingPersistedAuthenticationContext: (AnySecret) -> PersistedAuthenticationContext?
@@ -22,7 +22,7 @@ public class AnySecretStore: SecretStore {
_isAvailable = { secretStore.isAvailable }
_name = { secretStore.name }
_id = { secretStore.id }
_secrets = { secretStore.secrets.map { AnySecret($0) } }
_secrets = { @MainActor in secretStore.secrets.map { AnySecret($0) } }
_sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType, for: $2) }
_verify = { try secretStore.verify(signature: $0, for: $1, with: $2.base as! SecretStoreType.SecretType) }
_existingPersistedAuthenticationContext = { secretStore.existingPersistedAuthenticationContext(secret: $0.base as! SecretStoreType.SecretType) }
@@ -37,8 +37,10 @@ public class AnySecretStore: SecretStore {
return _isAvailable()
}
public var id: UUID {
return _id()
nonisolated public var id: UUID {
// return _id()
// FIXME: THIS
UUID()
}
public var name: String {
@@ -71,7 +73,7 @@ public class AnySecretStore: SecretStore {
}
public final class AnySecretStoreModifiable: AnySecretStore, SecretStoreModifiable {
@MainActor public final class AnySecretStoreModifiable: AnySecretStore, SecretStoreModifiable {
private let _create: (String, Bool) throws -> Void
private let _delete: (AnySecret) throws -> Void

View File

@@ -2,7 +2,7 @@ import Foundation
import Combine
/// A "Store Store," which holds a list of type-erased stores.
public final class SecretStoreList: ObservableObject {
@MainActor public final class SecretStoreList: ObservableObject {
/// The Stores managed by the SecretStoreList.
@Published public var stores: [AnySecretStore] = []

View File

@@ -2,7 +2,7 @@ import Foundation
import Combine
/// Manages access to Secrets, and performs signature operations on data using those Secrets.
public protocol SecretStore: ObservableObject, Identifiable {
@MainActor public protocol SecretStore: ObservableObject, Identifiable, Sendable {
associatedtype SecretType: Secret

View File

@@ -8,7 +8,7 @@ import SecretKit
extension SecureEnclave {
/// An implementation of Store backed by the Secure Enclave.
public final class Store: SecretStoreModifiable, Sendable {
@MainActor public final class Store: SecretStoreModifiable, Sendable {
public var isAvailable: Bool {
// For some reason, as of build time, CryptoKit.SecureEnclave.isAvailable always returns false
@@ -28,8 +28,11 @@ extension SecureEnclave {
/// Initializes a Store.
public init() {
DistributedNotificationCenter.default().addObserver(forName: .secretStoreUpdated, object: nil, queue: .main) { _ in
self.reloadSecretsInternal(notifyAgent: false)
DistributedNotificationCenter.default().addObserver(forName: .secretStoreUpdated, object: nil, queue: .main) { _ in
// We've explicitly specified main queue as an argument.
MainActor.assumeIsolated {
self.reloadSecretsInternal(notifyAgent: false)
}
}
loadSecrets()
}