···1+-- Add up migration script here
2+3+CREATE TABLE denylist (
4+ subject TEXT NOT NULL,
5+ reason TEXT NOT NULL,
6+ updated_at DATETIME NOT NULL DEFAULT (datetime('now')),
7+ PRIMARY KEY (subject)
8+);
9+
+24-1
src/consumer.rs
···16use crate::storage;
17use crate::storage::consumer_control_get;
18use crate::storage::consumer_control_insert;
019use crate::storage::feed_content_update;
20use crate::storage::feed_content_upsert;
21use crate::storage::StoragePool;
···178 }
179 let event_value = event_value.unwrap();
180181- for feed_matcher in self.feed_matchers.0.iter() {
000182 if let Some(Match(op, aturi)) = feed_matcher.matches(&event_value) {
183 tracing::debug!(feed_id = ?feed_matcher.feed, "matched event");
0000000184 let feed_content = storage::model::FeedContent{
185 feed_id: feed_matcher.feed.clone(),
186 uri: aturi,
···206207 Ok(())
208 }
000000000000209}
210211pub(crate) mod model {
···16use crate::storage;
17use crate::storage::consumer_control_get;
18use crate::storage::consumer_control_insert;
19+use crate::storage::denylist_exists;
20use crate::storage::feed_content_update;
21use crate::storage::feed_content_upsert;
22use crate::storage::StoragePool;
···179 }
180 let event_value = event_value.unwrap();
181182+ // Assumption: Performing a query for each event will cost more in the
183+ // long-term than evaluating each event against all matchers and if there's a
184+ // match, then checking both the event DID and the AT-URI DID.
185+ 'matchers_loop: for feed_matcher in self.feed_matchers.0.iter() {
186 if let Some(Match(op, aturi)) = feed_matcher.matches(&event_value) {
187 tracing::debug!(feed_id = ?feed_matcher.feed, "matched event");
188+189+ let aturi_did = did_from_aturi(&aturi);
190+ let dids = vec![event.did.as_str(), aturi_did.as_str()];
191+ if denylist_exists(&self.pool, &dids).await? {
192+ break 'matchers_loop;
193+ }
194+195 let feed_content = storage::model::FeedContent{
196 feed_id: feed_matcher.feed.clone(),
197 uri: aturi,
···217218 Ok(())
219 }
220+}
221+222+fn did_from_aturi(aturi: &str) -> String {
223+ let aturi_len = aturi.len();
224+ if aturi_len < 6 {
225+ return "".to_string();
226+ }
227+ let collection_start = aturi[5..]
228+ .find("/")
229+ .map(|value| value + 5)
230+ .unwrap_or(aturi_len);
231+ aturi[5..collection_start].to_string()
232}
233234pub(crate) mod model {