use chrono::{DateTime, Utc};
use pgp::{
packet::{Signature, SignatureType, SubpacketData, SubpacketType, UserId},
types::SignedUser,
};
use rpgpie::certificate::Checked;
use wot_network::{Certificate, Identity, Regex};
pub(crate) fn regexes_from(sig: &Signature) -> Vec<Regex> {
let Some(config) = sig.config() else {
return vec![];
};
config
.hashed_subpackets
.iter()
.filter(|sp| sp.typ() == SubpacketType::RegularExpression)
.map(|sp| &sp.data)
.map(|d| {
let SubpacketData::RegularExpression(regex) = &d else {
unreachable!()
};
regex
})
.filter_map(|r| String::from_utf8(r.to_vec()).ok())
.filter_map(|mut s| {
if s.ends_with(char::from(0)) {
s.truncate(s.len() - 1);
Some(s)
} else {
None
}
})
.map(Regex::new)
.collect()
}
pub(crate) fn user_id_valid(user: &SignedUser, reference_time: &DateTime<Utc>) -> bool {
!user
.signatures
.iter()
.filter(|s| match s.created() {
None => false,
Some(created) => created <= reference_time,
})
.any(|s| s.typ() == Some(SignatureType::CertRevocation))
}
pub(crate) fn pick_latest<'a>(sigs: &[&'a Signature]) -> &'a Signature {
let mut latest = *sigs.first().unwrap();
for s in sigs {
if s.created() > latest.created() {
latest = s;
}
}
latest
}
pub(crate) fn to_certificate(checked: &Checked) -> Certificate {
let fp = checked.fingerprint();
let hex_fp = hex::encode(fp.as_bytes());
hex_fp.into()
}
pub(crate) fn to_identity(id: &UserId) -> Option<Identity> {
String::from_utf8(id.id().to_vec()).ok().map(Into::into)
}