Use custom deserialization

This commit is contained in:
Daniel Saxton 2025-03-07 21:47:48 -06:00
parent c22f1f0a24
commit 62c2aa547b

View file

@ -5,32 +5,54 @@ use std::net::IpAddr;
use std::str::FromStr; use std::str::FromStr;
#[derive(Deserialize, Default)] #[derive(Deserialize, Default)]
pub struct Blacklist { pub struct BlacklistConfig {
pub pubkeys: Option<Vec<String>>, pub pubkeys: Option<Vec<String>>,
pub ips: Option<Vec<String>>, pub ips: Option<Vec<String>>,
pub cidrs: Option<Vec<String>>, pub cidrs: Option<Vec<String>>,
} }
impl Blacklist { #[derive(Default)]
fn is_ip_blocked(&self, ip: &str) -> bool { pub struct Blacklist {
if let Some(cidrs) = &self.cidrs { pubkeys: Option<Vec<String>>,
for cidr in cidrs { ips: Option<Vec<String>>,
if let Ok(network) = IpNetwork::from_str(cidr) { cidrs: Option<Vec<IpNetwork>>,
if let Ok(addr) = IpAddr::from_str(ip) {
if network.contains(addr) {
return true;
}
}
} }
impl<'de> Deserialize<'de> for Blacklist {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let config = BlacklistConfig::deserialize(deserializer)?;
Ok(Blacklist {
pubkeys: config.pubkeys,
ips: config.ips,
cidrs: config.cidrs.map(|cidrs| {
cidrs
.into_iter()
.filter_map(|s| IpNetwork::from_str(&s).ok())
.collect()
}),
})
} }
} }
impl Blacklist {
fn is_ip_blocked(&self, ip: &str) -> bool {
if let Some(ips) = &self.ips { if let Some(ips) = &self.ips {
if ips.contains(&ip.to_string()) { if ips.contains(&ip.to_string()) {
return true; return true;
} }
} }
if let Ok(addr) = IpAddr::from_str(ip) {
if let Some(cidrs) = &self.cidrs {
if cidrs.iter().any(|network| network.contains(addr)) {
return true;
}
}
}
false false
} }
} }