use crate::crypto::{
KeyMatchStrength,
verifier::{JwsVerifier, KeyMatch, VerifyError},
};
#[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> {
type Error = V::Error;
fn key_match(&self, key_match: &KeyMatch<'_>) -> Option<KeyMatchStrength> {
self.inner.key_match(key_match)
}
async fn verify(
&self,
input: &[u8],
signature: &[u8],
key_match: &KeyMatch<'_>,
) -> Result<(), VerifyError<Self::Error>> {
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
}
async fn try_refresh(&self) -> bool {
self.inner.try_refresh().await
}
}