initial commit
This commit is contained in:
commit
24a1c0dfc2
15 changed files with 509 additions and 0 deletions
5
src/filters/mod.rs
Normal file
5
src/filters/mod.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
mod rate_limit;
|
||||
mod whitelist;
|
||||
|
||||
pub use rate_limit::RateLimit;
|
||||
pub use whitelist::Whitelist;
|
||||
54
src/filters/rate_limit.rs
Normal file
54
src/filters/rate_limit.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use crate::{Action, InputMessage, NoteFilter, OutputMessage};
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub struct RateInfo {
|
||||
pub last_note: Instant,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default)]
|
||||
pub struct RateLimit {
|
||||
pub notes_per_second: u64,
|
||||
pub whitelist: Option<Vec<String>>,
|
||||
|
||||
#[serde(skip)]
|
||||
pub sources: HashMap<String, RateInfo>,
|
||||
}
|
||||
|
||||
impl NoteFilter for RateLimit {
|
||||
fn filter_note(&mut self, msg: &InputMessage) -> OutputMessage {
|
||||
if let Some(whitelist) = &self.whitelist {
|
||||
if whitelist.contains(&msg.source_info) {
|
||||
return OutputMessage::new(msg.event.id.clone(), Action::Accept, None);
|
||||
}
|
||||
}
|
||||
|
||||
if self.sources.contains_key(&msg.source_info) {
|
||||
let now = Instant::now();
|
||||
let entry = self.sources.get_mut(&msg.source_info).expect("impossiburu");
|
||||
if now - entry.last_note < Duration::from_secs(self.notes_per_second) {
|
||||
return OutputMessage::new(
|
||||
msg.event.id.clone(),
|
||||
Action::Reject,
|
||||
Some("rate-limited: you are noting too fast".to_string()),
|
||||
);
|
||||
} else {
|
||||
entry.last_note = Instant::now();
|
||||
return OutputMessage::new(msg.event.id.clone(), Action::Accept, None);
|
||||
}
|
||||
} else {
|
||||
self.sources.insert(
|
||||
msg.source_info.to_owned(),
|
||||
RateInfo {
|
||||
last_note: Instant::now(),
|
||||
},
|
||||
);
|
||||
return OutputMessage::new(msg.event.id.clone(), Action::Accept, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"ratelimit"
|
||||
}
|
||||
}
|
||||
26
src/filters/whitelist.rs
Normal file
26
src/filters/whitelist.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use crate::{Action, InputMessage, NoteFilter, OutputMessage};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Whitelist {
|
||||
pub pubkeys: Vec<String>,
|
||||
pub ips: Vec<String>,
|
||||
}
|
||||
|
||||
impl NoteFilter for Whitelist {
|
||||
fn filter_note(&mut self, msg: &InputMessage) -> OutputMessage {
|
||||
if self.pubkeys.contains(&msg.event.pubkey) || self.ips.contains(&msg.source_info) {
|
||||
OutputMessage::new(msg.event.id.clone(), Action::Accept, None)
|
||||
} else {
|
||||
OutputMessage::new(
|
||||
msg.event.id.clone(),
|
||||
Action::Reject,
|
||||
Some("blocked: pubkey not on the whitelist".to_string()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"whitelist"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue