use std::sync::Arc;
use auths_core::ports::clock::ClockProvider;
use auths_core::ports::id::{SystemUuidProvider, UuidProvider};
use auths_core::signing::PassphraseProvider;
use auths_core::storage::keychain::KeyStorage;
use auths_id::attestation::export::AttestationSink;
use auths_id::ports::registry::RegistryBackend;
use auths_id::storage::attestation::AttestationSource;
use auths_id::storage::identity::IdentityStorage;
use crate::ports::agent::{AgentSigningPort, NoopAgentProvider};
pub use auths_telemetry::EventSink;
struct NoopSink;
impl EventSink for NoopSink {
fn emit(&self, _payload: &str) {}
fn flush(&self) {}
}
struct NoopPassphraseProvider;
impl PassphraseProvider for NoopPassphraseProvider {
fn get_passphrase(
&self,
_prompt: &str,
) -> Result<zeroize::Zeroizing<String>, auths_core::AgentError> {
Err(auths_core::AgentError::SigningFailed(
"no passphrase provider configured — call .passphrase_provider(...) on AuthsContextBuilder".into(),
))
}
}
pub struct AuthsContext {
pub registry: Arc<dyn RegistryBackend + Send + Sync>,
pub key_storage: Arc<dyn KeyStorage + Send + Sync>,
pub clock: Arc<dyn ClockProvider + Send + Sync>,
pub event_sink: Arc<dyn EventSink>,
pub identity_storage: Arc<dyn IdentityStorage + Send + Sync>,
pub attestation_sink: Arc<dyn AttestationSink + Send + Sync>,
pub attestation_source: Arc<dyn AttestationSource + Send + Sync>,
pub passphrase_provider: Arc<dyn PassphraseProvider + Send + Sync>,
pub uuid_provider: Arc<dyn UuidProvider + Send + Sync>,
pub agent_signing: Arc<dyn AgentSigningPort + Send + Sync>,
pub witness_config: Option<auths_id::witness_config::WitnessConfig>,
pub repo_path: Option<std::path::PathBuf>,
}
impl AuthsContext {
pub fn witness_params(&self) -> auths_id::witness_config::WitnessParams<'_> {
match (&self.witness_config, &self.repo_path) {
(Some(config), Some(path)) => auths_id::witness_config::WitnessParams::Enabled {
config,
repo_path: path,
},
_ => auths_id::witness_config::WitnessParams::Disabled,
}
}
}
impl AuthsContext {
pub fn builder() -> AuthsContextBuilder<Missing, Missing, Missing, Missing, Missing, Missing> {
AuthsContextBuilder {
registry: Missing,
key_storage: Missing,
clock: Missing,
identity_storage: Missing,
attestation_sink: Missing,
attestation_source: Missing,
event_sink: None,
passphrase_provider: None,
uuid_provider: None,
agent_signing: None,
witness_config: None,
repo_path: None,
}
}
}
pub struct Missing;
pub struct Set<T>(T);
pub struct AuthsContextBuilder<R, K, C, IS, AS, ASrc> {
registry: R,
key_storage: K,
clock: C,
identity_storage: IS,
attestation_sink: AS,
attestation_source: ASrc,
event_sink: Option<Arc<dyn EventSink>>,
passphrase_provider: Option<Arc<dyn PassphraseProvider + Send + Sync>>,
uuid_provider: Option<Arc<dyn UuidProvider + Send + Sync>>,
agent_signing: Option<Arc<dyn AgentSigningPort + Send + Sync>>,
witness_config: Option<auths_id::witness_config::WitnessConfig>,
repo_path: Option<std::path::PathBuf>,
}
impl<K, C, IS, AS, ASrc> AuthsContextBuilder<Missing, K, C, IS, AS, ASrc> {
pub fn registry(
self,
registry: Arc<dyn RegistryBackend + Send + Sync>,
) -> AuthsContextBuilder<Set<Arc<dyn RegistryBackend + Send + Sync>>, K, C, IS, AS, ASrc> {
AuthsContextBuilder {
registry: Set(registry),
key_storage: self.key_storage,
clock: self.clock,
identity_storage: self.identity_storage,
attestation_sink: self.attestation_sink,
attestation_source: self.attestation_source,
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, C, IS, AS, ASrc> AuthsContextBuilder<R, Missing, C, IS, AS, ASrc> {
pub fn key_storage(
self,
key_storage: Arc<dyn KeyStorage + Send + Sync>,
) -> AuthsContextBuilder<R, Set<Arc<dyn KeyStorage + Send + Sync>>, C, IS, AS, ASrc> {
AuthsContextBuilder {
registry: self.registry,
key_storage: Set(key_storage),
clock: self.clock,
identity_storage: self.identity_storage,
attestation_sink: self.attestation_sink,
attestation_source: self.attestation_source,
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, K, IS, AS, ASrc> AuthsContextBuilder<R, K, Missing, IS, AS, ASrc> {
pub fn clock(
self,
clock: Arc<dyn ClockProvider + Send + Sync>,
) -> AuthsContextBuilder<R, K, Set<Arc<dyn ClockProvider + Send + Sync>>, IS, AS, ASrc> {
AuthsContextBuilder {
registry: self.registry,
key_storage: self.key_storage,
clock: Set(clock),
identity_storage: self.identity_storage,
attestation_sink: self.attestation_sink,
attestation_source: self.attestation_source,
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, K, C, AS, ASrc> AuthsContextBuilder<R, K, C, Missing, AS, ASrc> {
pub fn identity_storage(
self,
storage: Arc<dyn IdentityStorage + Send + Sync>,
) -> AuthsContextBuilder<R, K, C, Set<Arc<dyn IdentityStorage + Send + Sync>>, AS, ASrc> {
AuthsContextBuilder {
registry: self.registry,
key_storage: self.key_storage,
clock: self.clock,
identity_storage: Set(storage),
attestation_sink: self.attestation_sink,
attestation_source: self.attestation_source,
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, K, C, IS, ASrc> AuthsContextBuilder<R, K, C, IS, Missing, ASrc> {
pub fn attestation_sink(
self,
sink: Arc<dyn AttestationSink + Send + Sync>,
) -> AuthsContextBuilder<R, K, C, IS, Set<Arc<dyn AttestationSink + Send + Sync>>, ASrc> {
AuthsContextBuilder {
registry: self.registry,
key_storage: self.key_storage,
clock: self.clock,
identity_storage: self.identity_storage,
attestation_sink: Set(sink),
attestation_source: self.attestation_source,
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, K, C, IS, AS> AuthsContextBuilder<R, K, C, IS, AS, Missing> {
pub fn attestation_source(
self,
source: Arc<dyn AttestationSource + Send + Sync>,
) -> AuthsContextBuilder<R, K, C, IS, AS, Set<Arc<dyn AttestationSource + Send + Sync>>> {
AuthsContextBuilder {
registry: self.registry,
key_storage: self.key_storage,
clock: self.clock,
identity_storage: self.identity_storage,
attestation_sink: self.attestation_sink,
attestation_source: Set(source),
event_sink: self.event_sink,
passphrase_provider: self.passphrase_provider,
uuid_provider: self.uuid_provider,
agent_signing: self.agent_signing,
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}
impl<R, K, C, IS, AS, ASrc> AuthsContextBuilder<R, K, C, IS, AS, ASrc> {
pub fn event_sink(mut self, sink: Arc<dyn EventSink>) -> Self {
self.event_sink = Some(sink);
self
}
pub fn passphrase_provider(
mut self,
provider: Arc<dyn PassphraseProvider + Send + Sync>,
) -> Self {
self.passphrase_provider = Some(provider);
self
}
pub fn uuid_provider(mut self, provider: Arc<dyn UuidProvider + Send + Sync>) -> Self {
self.uuid_provider = Some(provider);
self
}
pub fn agent_signing(mut self, provider: Arc<dyn AgentSigningPort + Send + Sync>) -> Self {
self.agent_signing = Some(provider);
self
}
pub fn witness_config(mut self, config: auths_id::witness_config::WitnessConfig) -> Self {
self.witness_config = Some(config);
self
}
pub fn repo_path(mut self, path: std::path::PathBuf) -> Self {
self.repo_path = Some(path);
self
}
}
impl
AuthsContextBuilder<
Set<Arc<dyn RegistryBackend + Send + Sync>>,
Set<Arc<dyn KeyStorage + Send + Sync>>,
Set<Arc<dyn ClockProvider + Send + Sync>>,
Set<Arc<dyn IdentityStorage + Send + Sync>>,
Set<Arc<dyn AttestationSink + Send + Sync>>,
Set<Arc<dyn AttestationSource + Send + Sync>>,
>
{
pub fn build(self) -> AuthsContext {
AuthsContext {
registry: self.registry.0,
key_storage: self.key_storage.0,
clock: self.clock.0,
identity_storage: self.identity_storage.0,
attestation_sink: self.attestation_sink.0,
attestation_source: self.attestation_source.0,
event_sink: self.event_sink.unwrap_or_else(|| Arc::new(NoopSink)),
passphrase_provider: self
.passphrase_provider
.unwrap_or_else(|| Arc::new(NoopPassphraseProvider)),
uuid_provider: self
.uuid_provider
.unwrap_or_else(|| Arc::new(SystemUuidProvider)),
agent_signing: self
.agent_signing
.unwrap_or_else(|| Arc::new(NoopAgentProvider)),
witness_config: self.witness_config,
repo_path: self.repo_path,
}
}
}