use tracing::debug;
use ockam_core::compat::boxed::Box;
use ockam_core::{async_trait, Address, Result};
use crate::models::CredentialAndPurposeKey;
use crate::utils::now;
use crate::{CredentialRetriever, IdentityError, RemoteCredentialRetriever};
#[async_trait]
impl CredentialRetriever for RemoteCredentialRetriever {
async fn initialize(&self) -> Result<()> {
self.initialize_impl().await
}
async fn retrieve(&self) -> Result<CredentialAndPurposeKey> {
debug!(
"Requested credential for: {} from: {}",
self.subject, self.issuer_info.issuer
);
let last_presented_credential = match self.last_presented_credential.read().unwrap().clone()
{
Some(last_presented_credential) => last_presented_credential,
None => return Err(IdentityError::NoCredential)?,
};
let now = now()?;
if last_presented_credential.expires_at > now + self.timing_options.clock_skew_gap {
debug!(
"The last presented credential is still valid, with attributes {:?}",
last_presented_credential
.credential
.get_credential_data()?
.subject_attributes
);
return Ok(last_presented_credential.credential);
}
Err(IdentityError::NoCredential)?
}
fn subscribe(&self, address: &Address) -> Result<()> {
let mut subscribers = self.subscribers.write().unwrap();
if subscribers.contains(address) {
return Err(IdentityError::AddressAlreadySubscribedForThatCredentialRetriever)?;
}
subscribers.push(address.clone());
Ok(())
}
fn unsubscribe(&self, address: &Address) -> Result<()> {
let mut subscribers = self.subscribers.write().unwrap();
if let Some(i) = subscribers.iter().position(|x| x == address) {
subscribers.remove(i);
Ok(())
} else {
Err(IdentityError::AddressIsNotSubscribedForThatCredentialRetriever)?
}
}
}