use std::sync::Arc;
use auths_core::signing::StorageSigner;
use auths_core::storage::keychain::KeyAlias;
use auths_id::keri::parse_did_keri;
use auths_id::keri::types::Prefix;
use auths_oidc_port::{JwtValidator, OidcValidationConfig};
use chrono::{DateTime, Utc};
use super::error::FederationError;
use super::oidc::{OidcAttestationRequest, verify_oidc_attestation};
use super::types::{AttestationContent, IdpAttestation};
use crate::context::AuthsContext;
pub fn anchor_attestation(
ctx: &AuthsContext,
subject_prefix: &Prefix,
subject_alias: &KeyAlias,
content: &AttestationContent,
now: DateTime<Utc>,
) -> Result<IdpAttestation, FederationError> {
let storage_signer = StorageSigner::new(Arc::clone(&ctx.key_storage));
let mut batch = auths_id::storage::registry::backend::AtomicWriteBatch::new();
let (_said, ixn) = auths_id::keri::anchor_and_persist_via_backend(
ctx.registry.as_ref(),
&storage_signer,
subject_alias,
ctx.passphrase_provider.as_ref(),
subject_prefix,
content,
&mut batch,
&ctx.witness_params(),
now,
)
.map_err(|e| FederationError::AnchorFailed(e.to_string()))?;
Ok(IdpAttestation {
content: content.clone(),
anchored_at_seq: ixn.s.value(),
})
}
#[allow(clippy::too_many_arguments)]
pub async fn attest_oidc(
ctx: &AuthsContext,
validator: &dyn JwtValidator,
config: &OidcValidationConfig,
token: &str,
request: &OidcAttestationRequest,
subject_alias: &KeyAlias,
now: DateTime<Utc>,
) -> Result<IdpAttestation, FederationError> {
let content = verify_oidc_attestation(validator, config, token, request, now).await?;
let subject_prefix = parse_did_keri(content.subject.as_str())
.map_err(|e| FederationError::InvalidSubject(e.to_string()))?;
anchor_attestation(ctx, &subject_prefix, subject_alias, &content, now)
}