diff --git a/src/lib.rs b/src/lib.rs index a69c977..110e1d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -220,7 +220,7 @@ async fn websocket_thread(peer: HashedPeer, websocket: HyperWebsocket, origin: S last_message: Instant::now(), burst_tokens: GLOBALS.config.read().throttling_burst, challenge: TextNonce::new().into_string(), - user: None, + authed_as: Vec::new(), error_punishment: 0.0, replied: false, negentropy_sub: None, @@ -356,7 +356,7 @@ struct WebSocketService { pub last_message: Instant, pub burst_tokens: usize, pub challenge: String, - pub user: Option, + pub authed_as: Vec, pub error_punishment: f32, pub replied: bool, pub negentropy_sub: Option, @@ -473,8 +473,8 @@ impl WebSocketService { .unwrap() .get_event_by_offset(new_event_offset)?; - let event_flags = nostr::event_flags(event, &self.user); - let authorized_user = self.user.map(is_authorized_user).unwrap_or(false); + let event_flags = nostr::event_flags(event, self.authed_as.as_slice()); + let authorized_user = self.authed_as.iter().any(|u| is_authorized_user(*u)); 'subs: for (subid, filters) in self.subscriptions.iter() { for filter in filters.iter() { diff --git a/src/nostr.rs b/src/nostr.rs index 48c31c8..4cf335d 100644 --- a/src/nostr.rs +++ b/src/nostr.rs @@ -124,10 +124,9 @@ impl WebSocketService { return Err(ChorusError::TooManySubscriptions.into()); } - let user = self.user; - let authorized_user = self.user.map(crate::is_authorized_user).unwrap_or(false); + let authorized_user = self.authed_as.iter().any(|u| crate::is_authorized_user(*u)); - if user.is_none() { + if self.authed_as.is_empty() { for filter in filters.iter() { // If any DM kinds were requested, complain. // But if NO kinds were requested, we will just silently not return DMs (elsewhere) @@ -163,7 +162,7 @@ impl WebSocketService { for filter in filters.iter() { let screen = |event: &Event| -> ScreenResult { - let event_flags = event_flags(event, &user); + let event_flags = event_flags(event, self.authed_as.as_slice()); screen_outgoing_event(event, &event_flags, authorized_user) }; let (filter_events, was_redacted) = { @@ -317,13 +316,12 @@ impl WebSocketService { } async fn event_inner(&mut self) -> Result<(), Error> { - let user = self.user; - let authorized_user = self.user.map(crate::is_authorized_user).unwrap_or(false); + let authorized_user = self.authed_as.iter().any(|u| crate::is_authorized_user(*u)); // Delineate the event back out of the session buffer let event = unsafe { Event::delineate(&self.buffer)? }; - let event_flags = event_flags(event, &user); + let event_flags = event_flags(event, self.authed_as.as_slice()); if GLOBALS.config.read().verify_events { // Verify the event is valid (id is hash, signature is valid) @@ -347,10 +345,10 @@ impl WebSocketService { // Screen the event to see if we are willing to accept it if !screen_incoming_event(event, event_flags, authorized_user).await? { - if self.user.is_some() { - return Err(ChorusError::Restricted.into()); - } else { + if self.authed_as.is_empty() { return Err(ChorusError::AuthRequired.into()); + } else { + return Err(ChorusError::Restricted.into()); } } @@ -463,7 +461,7 @@ impl WebSocketService { } // They are now authenticated - self.user = Some(event.pubkey()); + self.authed_as.push(event.pubkey()); Ok(()) } @@ -542,13 +540,12 @@ impl WebSocketService { return Ok(()); } - let user = self.user; - let authorized_user = self.user.map(crate::is_authorized_user).unwrap_or(false); + let authorized_user = self.authed_as.iter().any(|u| crate::is_authorized_user(*u)); // Find all matching events let mut events: Vec<&Event> = Vec::new(); let screen = |event: &Event| -> ScreenResult { - let event_flags = event_flags(event, &user); + let event_flags = event_flags(event, self.authed_as.as_slice()); screen_outgoing_event(event, &event_flags, authorized_user) }; let (filter_events, _redacted) = { @@ -871,13 +868,10 @@ pub struct EventFlags { pub tags_current_user: bool, } -pub fn event_flags(event: &Event, user: &Option) -> EventFlags { +pub fn event_flags(event: &Event, authed_as: &[Pubkey]) -> EventFlags { let author_is_an_authorized_user = crate::is_authorized_user(event.pubkey()); - let author_is_current_user = match user { - None => false, - Some(pk) => event.pubkey() == *pk, - }; + let author_is_current_user = authed_as.iter().any(|u| *u == event.pubkey()); let mut tags_an_authorized_user = false; let mut tags_current_user = false; @@ -887,10 +881,8 @@ pub fn event_flags(event: &Event, user: &Option) -> EventFlags { if let Some(b"p") = tag.next() { if let Some(value) = tag.next() { if let Ok(tagged_pk) = Pubkey::read_hex(value) { - if let Some(current_user) = user { - if *current_user == tagged_pk { - tags_current_user = true; - } + if authed_as.contains(&tagged_pk) { + tags_current_user = true; } if crate::is_authorized_user(tagged_pk) {