diff --git a/noteguard.toml b/noteguard.toml index 467693c..7b13cd8 100644 --- a/noteguard.toml +++ b/noteguard.toml @@ -1,4 +1,3 @@ - pipeline = ["protected_events", "kinds", "content", "whitelist", "ratelimit"] [filters.ratelimit] diff --git a/src/filters/blacklist.rs b/src/filters/blacklist.rs new file mode 100644 index 0000000..e72fb2e --- /dev/null +++ b/src/filters/blacklist.rs @@ -0,0 +1,39 @@ +use crate::{Action, InputMessage, NoteFilter, OutputMessage}; +use serde::Deserialize; + +#[derive(Deserialize, Default)] +pub struct Blacklist { + pub pubkeys: Option>, + pub ips: Option>, +} + +impl NoteFilter for Blacklist { + fn filter_note(&mut self, msg: &InputMessage) -> OutputMessage { + let reject_message = "blocked: pubkey/ip is blacklisted".to_string(); + if let Some(pubkeys) = &self.pubkeys { + if pubkeys.contains(&msg.event.pubkey) { + return OutputMessage::new( + msg.event.id.clone(), + Action::Reject, + Some(reject_message), + ); + } + } + + if let Some(ips) = &self.ips { + if ips.contains(&msg.source_info) { + return OutputMessage::new( + msg.event.id.clone(), + Action::Reject, + Some(reject_message), + ); + } + } + + OutputMessage::new(msg.event.id.clone(), Action::Accept, None) + } + + fn name(&self) -> &'static str { + "blacklist" + } +} diff --git a/src/filters/mod.rs b/src/filters/mod.rs index 0fa5611..da41573 100644 --- a/src/filters/mod.rs +++ b/src/filters/mod.rs @@ -1,3 +1,4 @@ +mod blacklist; mod content; mod kinds; mod protected_events; @@ -7,6 +8,7 @@ mod whitelist; #[cfg(feature = "forwarder")] mod forwarder; +pub use blacklist::Blacklist; pub use content::Content; pub use kinds::Kinds; pub use protected_events::ProtectedEvents; diff --git a/src/main.rs b/src/main.rs index 19cb307..16b1d2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use noteguard::filters::{Content, Kinds, ProtectedEvents, RateLimit, Whitelist}; +use noteguard::filters::{Blacklist, Content, Kinds, ProtectedEvents, RateLimit, Whitelist}; #[cfg(feature = "forwarder")] use noteguard::filters::Forwarder; @@ -47,6 +47,7 @@ impl Noteguard { fn register_builtin_filters(&mut self) { self.register_filter::(); self.register_filter::(); + self.register_filter::(); self.register_filter::(); self.register_filter::(); self.register_filter::(); @@ -217,6 +218,7 @@ mod tests { let noteguard = Noteguard::new(); assert!(noteguard.registered_filters.contains_key("ratelimit")); assert!(noteguard.registered_filters.contains_key("whitelist")); + assert!(noteguard.registered_filters.contains_key("blacklist")); assert!(noteguard .registered_filters .contains_key("protected_events")); @@ -315,6 +317,56 @@ mod tests { assert_eq!(output_message.action, Action::Reject); } + #[test] + fn test_blacklist_reject() { + let mut noteguard = Noteguard::new(); + + let config: Config = toml::from_str( + r#" + pipeline = ["blacklist"] + [filters.blacklist] + pubkeys = ["mock_pubkey"] + "#, + ) + .expect("Failed to parse config"); + + noteguard + .load_config(&config) + .expect("Failed to load config"); + + let input_message = create_mock_input_message("test_event_3", "new"); + let output_message = noteguard.run(input_message); + + assert_eq!(output_message.action, Action::Reject); + assert_eq!( + output_message.msg.expect("Failed to get message"), + "blocked: pubkey/ip is blacklisted".to_string() + ); + } + + #[test] + fn test_blacklist_accept() { + let mut noteguard = Noteguard::new(); + + let config: Config = toml::from_str( + r#" + pipeline = ["blacklist"] + [filters.blacklist] + pubkeys = ["not_blacklisted"] + "#, + ) + .expect("Failed to parse config"); + + noteguard + .load_config(&config) + .expect("Failed to load config"); + + let input_message = create_mock_input_message("test_event_4", "new"); + let output_message = noteguard.run(input_message); + + assert_eq!(output_message.action, Action::Accept); + } + #[test] fn test_deserialize_input_message() { let input_json = r#"