From 4d53c123ee9465cdace4823a6e2b19c27dcfeecd Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Sun, 18 Feb 2024 13:16:21 +1300 Subject: [PATCH] Screen outgoing events --- src/main.rs | 7 +++++ src/nostr.rs | 77 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 84dbf0e..1035741 100644 --- a/src/main.rs +++ b/src/main.rs @@ -227,6 +227,13 @@ struct WebSocketService { } impl WebSocketService { + async fn authorized_user(&mut self) -> bool { + match self.user { + None => false, + Some(pk) => GLOBALS.config.read().await.user_keys.contains(&pk), + } + } + async fn handle_websocket_stream(&mut self) -> Result<(), Error> { // Subscribe to the new_events broadcast channel let mut new_events = GLOBALS.new_events.subscribe(); diff --git a/src/nostr.rs b/src/nostr.rs index 6601abf..3cc8ba0 100644 --- a/src/nostr.rs +++ b/src/nostr.rs @@ -3,7 +3,7 @@ use crate::globals::GLOBALS; use crate::reply::{NostrReply, NostrReplyPrefix}; use crate::types::parse::json_escape::json_unescape; use crate::types::parse::json_parse::*; -use crate::types::{Event, Filter, Kind, OwnedFilter, Pubkey, Time}; +use crate::types::{Event, Filter, Kind, OwnedFilter, Time}; use crate::WebSocketService; use futures::SinkExt; use hyper_tungstenite::tungstenite::Message; @@ -80,16 +80,33 @@ impl WebSocketService { filters.push(OwnedFilter(filterbytes)); } + let authorized_user = self.authorized_user().await; + // Serve events matching subscription { let mut events: Vec = Vec::new(); for filter in filters.iter() { - let filter_events = GLOBALS + let mut filter_events = GLOBALS .store .get() .unwrap() .find_events(filter.as_filter()?)?; - events.extend(filter_events) + for event in filter_events.drain(..) { + let authored_by_an_authorized_user = GLOBALS + .config + .read() + .await + .user_keys + .contains(&event.pubkey()); + + if screen_outgoing_event( + &event, + authorized_user, + authored_by_an_authorized_user, + ) { + events.push(event); + } + } } // sort @@ -157,6 +174,8 @@ impl WebSocketService { } async fn event_inner(&mut self) -> Result<(), Error> { + let authorized_user = self.authorized_user().await; + // Delineate the event back out of the session buffer let event = Event::delineate(&self.buffer)?; @@ -168,7 +187,7 @@ impl WebSocketService { } // Screen the event to see if we are willing to accept it - if !screen_event(&event, self.user).await? { + if !screen_incoming_event(&event, authorized_user).await? { if self.user.is_some() { return Err(ChorusError::Restricted.into()); } else { @@ -301,12 +320,22 @@ impl WebSocketService { } } -async fn screen_event(event: &Event<'_>, user: Option) -> Result { +async fn screen_incoming_event(event: &Event<'_>, authorized_user: bool) -> Result { + // Accept anything from authenticated authorized users + if authorized_user { + return Ok(true); + } + // Accept relay lists from anybody if event.kind() == Kind(10002) { return Ok(true); } + // Allow if event kind ephemeral + if event.kind().is_ephemeral() { + return Ok(true); + } + // If the author is one of our users, always accept it if GLOBALS .config @@ -331,14 +360,34 @@ async fn screen_event(event: &Event<'_>, user: Option) -> Result, + authorized_user: bool, + authored_by_an_authorized_user: bool, +) -> bool { + // Allow if authorized_user is asking + if authorized_user { + return true; + } + + // Everybody can see events from our authorized users + if authored_by_an_authorized_user { + return true; + } + + // Allow Relay Lists + if event.kind() == Kind(10002) { + return true; + } + + // Allow if event kind ephemeral + if event.kind().is_ephemeral() { + return true; + } + + // Do not allow the rest + false +}