secretive/Sources/Packages/Sources/SecretKit/Erasers/AnySecretStore.swift

88 lines
3.1 KiB
Swift
Raw Normal View History

2020-03-09 03:08:27 +00:00
import Foundation
2020-03-09 03:44:15 +00:00
import Combine
2020-03-09 03:08:27 +00:00
/// Type eraser for SecretStore.
2020-03-09 03:08:27 +00:00
public class AnySecretStore: SecretStore {
let base: Any
2020-05-16 06:19:00 +00:00
private let _isAvailable: () -> Bool
private let _id: () -> UUID
private let _name: () -> String
private let _secrets: () -> [AnySecret]
private let _sign: (Data, AnySecret, SigningRequestProvenance) throws -> Data
private let _existingPersistedAuthenticationContext: (AnySecret) -> PersistedAuthenticationContext?
private let _persistAuthentication: (AnySecret, TimeInterval) throws -> Void
2020-05-16 06:19:00 +00:00
private var sink: AnyCancellable?
2020-03-09 03:08:27 +00:00
public init<SecretStoreType>(_ secretStore: SecretStoreType) where SecretStoreType: SecretStore {
base = secretStore
_isAvailable = { secretStore.isAvailable }
_name = { secretStore.name }
_id = { secretStore.id }
_secrets = { secretStore.secrets.map { AnySecret($0) } }
_sign = { try secretStore.sign(data: $0, with: $1.base as! SecretStoreType.SecretType, for: $2) }
_existingPersistedAuthenticationContext = { secretStore.existingPersistedAuthenticationContext(secret: $0.base as! SecretStoreType.SecretType) }
_persistAuthentication = { try secretStore.persistAuthentication(secret: $0.base as! SecretStoreType.SecretType, forDuration: $1) }
2020-03-09 03:44:15 +00:00
sink = secretStore.objectWillChange.sink { _ in
self.objectWillChange.send()
}
2020-03-09 03:08:27 +00:00
}
public var isAvailable: Bool {
return _isAvailable()
}
public var id: UUID {
return _id()
}
public var name: String {
return _name()
}
public var secrets: [AnySecret] {
return _secrets()
}
public func sign(data: Data, with secret: AnySecret, for provenance: SigningRequestProvenance) throws -> Data {
try _sign(data, secret, provenance)
2020-03-09 03:08:27 +00:00
}
public func existingPersistedAuthenticationContext(secret: AnySecret) -> PersistedAuthenticationContext? {
_existingPersistedAuthenticationContext(secret)
}
public func persistAuthentication(secret: AnySecret, forDuration duration: TimeInterval) throws {
try _persistAuthentication(secret, duration)
}
2020-03-09 03:08:27 +00:00
}
public class AnySecretStoreModifiable: AnySecretStore, SecretStoreModifiable {
2020-05-16 06:19:00 +00:00
private let _create: (String, Bool) throws -> Void
private let _delete: (AnySecret) throws -> Void
private let _update: (AnySecret, String) throws -> Void
2020-03-09 03:08:27 +00:00
public init<SecretStoreType>(modifiable secretStore: SecretStoreType) where SecretStoreType: SecretStoreModifiable {
_create = { try secretStore.create(name: $0, requiresAuthentication: $1) }
_delete = { try secretStore.delete(secret: $0.base as! SecretStoreType.SecretType) }
_update = { try secretStore.update(secret: $0.base as! SecretStoreType.SecretType, name: $1) }
2020-03-09 03:08:27 +00:00
super.init(secretStore)
}
public func create(name: String, requiresAuthentication: Bool) throws {
try _create(name, requiresAuthentication)
}
public func delete(secret: AnySecret) throws {
try _delete(secret)
}
public func update(secret: AnySecret, name: String) throws {
try _update(secret, name)
}
2020-03-09 03:08:27 +00:00
}