use crate::{
crypto::{
KeyMatchStrength,
verifier::{JwsVerifier, KeyMatch, VerifyError},
},
platform::MaybeSendBoxFuture,
};
#[derive(Debug)]
pub struct MetricsJwsVerifier<V> {
inner: V,
name: String,
}
#[bon::bon]
impl<V> MetricsJwsVerifier<V> {
#[builder]
pub fn new(inner: V, #[builder(into)] name: String) -> Self {
Self { inner, name }
}
}
impl<V> MetricsJwsVerifier<V> {
pub fn inner(&self) -> &V {
&self.inner
}
pub fn into_inner(self) -> V {
self.inner
}
}
impl<V: JwsVerifier> JwsVerifier for MetricsJwsVerifier<V> {
fn key_match(&self, key_match: &KeyMatch<'_>) -> Option<KeyMatchStrength> {
self.inner.key_match(key_match)
}
fn verify<'a>(
&'a self,
input: &'a [u8],
signature: &'a [u8],
key_match: &'a KeyMatch<'a>,
) -> MaybeSendBoxFuture<'a, Result<(), VerifyError>> {
Box::pin(async move {
let alg = key_match.alg.to_owned();
let result = self.inner.verify(input, signature, key_match).await;
let outcome = match &result {
Ok(()) => "success",
Err(VerifyError::NoMatchingKey) => "no_matching_key",
Err(VerifyError::AmbiguousKeyMatch) => "ambiguous_key",
Err(VerifyError::SignatureMismatch) => "signature_mismatch",
Err(VerifyError::Other { .. }) => "error",
};
::metrics::counter!(
"huskarl.jws.verify",
"name" => self.name.clone(),
"alg" => alg,
"outcome" => outcome,
)
.increment(1);
result
})
}
fn try_refresh(&self) -> MaybeSendBoxFuture<'_, bool> {
Box::pin(async move {
let refreshed = self.inner.try_refresh().await;
let outcome = if refreshed {
"refreshed"
} else {
"not_refreshed"
};
::metrics::counter!(
"huskarl.jws.refresh",
"name" => self.name.clone(),
"outcome" => outcome,
)
.increment(1);
refreshed
})
}
}