commit c85f9cbc3df487ed9ec00c0bbee5a8b0f89d3f77
parent f08e805673ccaf1aee0f9b00cc4a92dbf8bdead1
Author: William Casarin <jb55@jb55.com>
Date: Tue, 9 Jul 2024 11:05:21 -0700
filter: add kind blacklist filter
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
5 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
@@ -14,15 +14,22 @@ You can add any new filter you want by implementing the `NoteFilter` trait and r
The `pipeline` config specifies the order in which filters are run. When the first `reject` or `shadowReject` action is hit, then the pipeline stops and returns the rejection error.
```toml
-pipeline = ["protected_events", "whitelist", "ratelimit"]
+pipeline = ["protected_events", "kinds", "whitelist", "ratelimit"]
[filters.ratelimit]
posts_per_minute = 8
whitelist = ["127.0.0.1"]
[filters.whitelist]
-pubkeys = ["32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"]
-ips = ["127.0.0.1", "127.0.0.2"]
+pubkeys = ["16c21558762108afc34e4ff19e4ed51d9a48f79e0c34531efc423d21ab435e93"]
+ips = ["127.0.0.1"]
+
+[filters.kinds]
+kinds = [30065, 1064]
+
+[filters.kinds.messages]
+30065 = "blocked: files on nostr is dumb"
+1064 = "blocked: files on nostr is dumb"
[filters.protected_events]
```
@@ -57,6 +64,27 @@ The whitelist filter only allows notes to pass if it matches a particular pubkey
Either criteria can match
+### Kinds
+
+* name: `kinds`
+
+A filter that blacklists certain kinds
+
+- `kinds`: a list of kind integers to block
+
+- `kinds.messages` *optional*: a map of kinds to message to deliver when the kind is blocked
+
+Example:
+
+```toml
+[filters.kinds]
+kinds = [30065, 1064]
+
+[filters.kinds.messages]
+30065 = "blocked: files on nostr is dumb"
+1064 = "blocked: files on nostr is dumb"
+```
+
### Protected Events
See [nip70]
diff --git a/noteguard.toml b/noteguard.toml
@@ -1,5 +1,5 @@
-pipeline = ["protected_events", "whitelist", "ratelimit"]
+pipeline = ["protected_events", "kinds", "whitelist", "ratelimit"]
[filters.ratelimit]
posts_per_minute = 8
@@ -9,4 +9,13 @@ whitelist = ["127.0.0.1"]
pubkeys = ["16c21558762108afc34e4ff19e4ed51d9a48f79e0c34531efc423d21ab435e93"]
ips = ["127.0.0.1"]
+[filters.kinds]
+kinds = [30065, 1064, 34550, 4550]
+
+[filters.kinds.messages]
+30065 = "blocked: files on nostr is dumb"
+1064 = "blocked: files on nostr is dumb"
+34550 = "blocked: please use a dedicated relay for moderated communities"
+4550 = "blocked: please use a dedicated relay for moderated communities"
+
[filters.protected_events]
diff --git a/src/filters/kinds.rs b/src/filters/kinds.rs
@@ -0,0 +1,29 @@
+use crate::{Action, InputMessage, NoteFilter, OutputMessage};
+use serde::Deserialize;
+use std::collections::HashMap;
+
+#[derive(Deserialize, Default)]
+pub struct Kinds {
+ kinds: Vec<i64>,
+ messages: Option<HashMap<String, String>>,
+}
+
+impl NoteFilter for Kinds {
+ fn filter_note(&mut self, input: &InputMessage) -> OutputMessage {
+ let kind = input.event.kind;
+ if self.kinds.contains(&kind) {
+ let msg = self
+ .messages
+ .as_ref()
+ .and_then(|msgs| msgs.get(&kind.to_string()).cloned())
+ .unwrap_or_else(|| "blocked: note kind is not allowed here".to_string());
+ OutputMessage::new(input.event.id.clone(), Action::Reject, Some(msg))
+ } else {
+ OutputMessage::new(input.event.id.clone(), Action::Accept, None)
+ }
+ }
+
+ fn name(&self) -> &'static str {
+ "kinds"
+ }
+}
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
@@ -1,7 +1,9 @@
+mod kinds;
mod protected_events;
mod ratelimit;
mod whitelist;
+pub use kinds::Kinds;
pub use protected_events::ProtectedEvents;
pub use ratelimit::RateLimit;
pub use whitelist::Whitelist;
diff --git a/src/main.rs b/src/main.rs
@@ -1,4 +1,4 @@
-use noteguard::filters::{ProtectedEvents, RateLimit, Whitelist};
+use noteguard::filters::{Kinds, ProtectedEvents, RateLimit, Whitelist};
use noteguard::{Action, InputMessage, NoteFilter, OutputMessage};
use serde::de::DeserializeOwned;
use serde::Deserialize;
@@ -43,6 +43,7 @@ impl Noteguard {
self.register_filter::<RateLimit>();
self.register_filter::<Whitelist>();
self.register_filter::<ProtectedEvents>();
+ self.register_filter::<Kinds>();
}
/// Run the loaded filters. You must call `load_config` before calling this, otherwise