mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
EventFlags for easier decision making
This commit is contained in:
parent
04e6947ffb
commit
f79185770b
@ -306,13 +306,6 @@ struct WebSocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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> {
|
async fn handle_websocket_stream(&mut self) -> Result<(), Error> {
|
||||||
// Subscribe to the shutting down channel
|
// Subscribe to the shutting down channel
|
||||||
let mut shutting_down = GLOBALS.shutting_down.subscribe();
|
let mut shutting_down = GLOBALS.shutting_down.subscribe();
|
||||||
|
|||||||
131
src/nostr.rs
131
src/nostr.rs
@ -3,7 +3,7 @@ use crate::globals::GLOBALS;
|
|||||||
use crate::reply::{NostrReply, NostrReplyPrefix};
|
use crate::reply::{NostrReply, NostrReplyPrefix};
|
||||||
use crate::types::parse::json_escape::json_unescape;
|
use crate::types::parse::json_escape::json_unescape;
|
||||||
use crate::types::parse::json_parse::*;
|
use crate::types::parse::json_parse::*;
|
||||||
use crate::types::{Event, Filter, Kind, OwnedFilter, Time};
|
use crate::types::{Event, Filter, Kind, OwnedFilter, Pubkey, Time};
|
||||||
use crate::WebSocketService;
|
use crate::WebSocketService;
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use hyper_tungstenite::tungstenite::Message;
|
use hyper_tungstenite::tungstenite::Message;
|
||||||
@ -80,7 +80,8 @@ impl WebSocketService {
|
|||||||
filters.push(OwnedFilter(filterbytes));
|
filters.push(OwnedFilter(filterbytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
let authorized_user = self.authorized_user().await;
|
let user = self.user;
|
||||||
|
let authorized_user = authorized_user(&user).await;
|
||||||
|
|
||||||
// NOTE on private events (DMs, GiftWraps)
|
// NOTE on private events (DMs, GiftWraps)
|
||||||
// Most relays check if you are seeking them, and of which pubkey, and if you are
|
// Most relays check if you are seeking them, and of which pubkey, and if you are
|
||||||
@ -101,45 +102,8 @@ impl WebSocketService {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.find_events(filter.as_filter()?)?;
|
.find_events(filter.as_filter()?)?;
|
||||||
for event in filter_events.drain(..) {
|
for event in filter_events.drain(..) {
|
||||||
let authored_by_an_authorized_user = GLOBALS
|
let event_flags = event_flags(&event, &user).await;
|
||||||
.config
|
if screen_outgoing_event(&event, event_flags, authorized_user) {
|
||||||
.read()
|
|
||||||
.await
|
|
||||||
.user_keys
|
|
||||||
.contains(&event.pubkey());
|
|
||||||
|
|
||||||
let authored_by_requester = match self.user {
|
|
||||||
None => false,
|
|
||||||
Some(pk) => event.pubkey() == pk,
|
|
||||||
};
|
|
||||||
|
|
||||||
let user_is_tagged = match self.user {
|
|
||||||
None => false,
|
|
||||||
Some(pk) => {
|
|
||||||
let mut user_is_tagged = false;
|
|
||||||
for mut tag in event.tags()?.iter() {
|
|
||||||
if let Some(b"p") = tag.next() {
|
|
||||||
if let Some(value) = tag.next() {
|
|
||||||
let mut bytes: [u8; 64] = [0; 64];
|
|
||||||
pk.write_hex(&mut bytes).unwrap();
|
|
||||||
if value == bytes {
|
|
||||||
user_is_tagged = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
user_is_tagged
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if screen_outgoing_event(
|
|
||||||
&event,
|
|
||||||
authorized_user,
|
|
||||||
authored_by_an_authorized_user,
|
|
||||||
authored_by_requester,
|
|
||||||
user_is_tagged
|
|
||||||
) {
|
|
||||||
events.push(event);
|
events.push(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,11 +180,14 @@ impl WebSocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn event_inner(&mut self) -> Result<(), Error> {
|
async fn event_inner(&mut self) -> Result<(), Error> {
|
||||||
let authorized_user = self.authorized_user().await;
|
let user = self.user;
|
||||||
|
let authorized_user = authorized_user(&user).await;
|
||||||
|
|
||||||
// Delineate the event back out of the session buffer
|
// Delineate the event back out of the session buffer
|
||||||
let event = Event::delineate(&self.buffer)?;
|
let event = Event::delineate(&self.buffer)?;
|
||||||
|
|
||||||
|
let event_flags = event_flags(&event, &user).await;
|
||||||
|
|
||||||
if GLOBALS.config.read().await.verify_events {
|
if GLOBALS.config.read().await.verify_events {
|
||||||
// Verify the event is valid (id is hash, signature is valid)
|
// Verify the event is valid (id is hash, signature is valid)
|
||||||
if let Err(e) = event.verify() {
|
if let Err(e) = event.verify() {
|
||||||
@ -229,7 +196,7 @@ impl WebSocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Screen the event to see if we are willing to accept it
|
// Screen the event to see if we are willing to accept it
|
||||||
if !screen_incoming_event(&event, authorized_user).await? {
|
if !screen_incoming_event(&event, event_flags, authorized_user).await? {
|
||||||
if self.user.is_some() {
|
if self.user.is_some() {
|
||||||
return Err(ChorusError::Restricted.into());
|
return Err(ChorusError::Restricted.into());
|
||||||
} else {
|
} else {
|
||||||
@ -362,7 +329,11 @@ impl WebSocketService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn screen_incoming_event(event: &Event<'_>, authorized_user: bool) -> Result<bool, Error> {
|
async fn screen_incoming_event(
|
||||||
|
event: &Event<'_>,
|
||||||
|
_event_flags: EventFlags,
|
||||||
|
authorized_user: bool,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
// Accept anything from authenticated authorized users
|
// Accept anything from authenticated authorized users
|
||||||
if authorized_user {
|
if authorized_user {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
@ -407,10 +378,8 @@ async fn screen_incoming_event(event: &Event<'_>, authorized_user: bool) -> Resu
|
|||||||
|
|
||||||
fn screen_outgoing_event(
|
fn screen_outgoing_event(
|
||||||
event: &Event<'_>,
|
event: &Event<'_>,
|
||||||
|
event_flags: EventFlags,
|
||||||
authorized_user: bool,
|
authorized_user: bool,
|
||||||
authored_by_an_authorized_user: bool,
|
|
||||||
authored_by_requester: bool,
|
|
||||||
user_is_tagged: bool,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Allow Relay Lists
|
// Allow Relay Lists
|
||||||
if event.kind() == Kind(10002) {
|
if event.kind() == Kind(10002) {
|
||||||
@ -425,13 +394,7 @@ fn screen_outgoing_event(
|
|||||||
// Forbid if it is a private event (DM or GiftWrap) and theey are neither the recipient
|
// Forbid if it is a private event (DM or GiftWrap) and theey are neither the recipient
|
||||||
// nor the author
|
// nor the author
|
||||||
if event.kind() == Kind(4) || event.kind() == Kind(1059) {
|
if event.kind() == Kind(4) || event.kind() == Kind(1059) {
|
||||||
if authored_by_requester {
|
return event_flags.tags_current_user || event_flags.author_is_current_user;
|
||||||
return true;
|
|
||||||
} else if user_is_tagged {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow if an authorized_user is asking
|
// Allow if an authorized_user is asking
|
||||||
@ -440,10 +403,68 @@ fn screen_outgoing_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Everybody can see events from our authorized users
|
// Everybody can see events from our authorized users
|
||||||
if authored_by_an_authorized_user {
|
if event_flags.author_is_an_authorized_user {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow the rest
|
// Do not allow the rest
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn authorized_user(user: &Option<Pubkey>) -> bool {
|
||||||
|
match user {
|
||||||
|
None => false,
|
||||||
|
Some(pk) => GLOBALS.config.read().await.user_keys.contains(pk),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EventFlags {
|
||||||
|
pub author_is_an_authorized_user: bool,
|
||||||
|
pub author_is_current_user: bool,
|
||||||
|
pub tags_an_authorized_user: bool,
|
||||||
|
pub tags_current_user: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_flags(event: &Event<'_>, user: &Option<Pubkey>) -> EventFlags {
|
||||||
|
let author_is_an_authorized_user = GLOBALS
|
||||||
|
.config
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.user_keys
|
||||||
|
.contains(&event.pubkey());
|
||||||
|
|
||||||
|
let author_is_current_user = match user {
|
||||||
|
None => false,
|
||||||
|
Some(pk) => event.pubkey() == *pk,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tags_an_authorized_user = false;
|
||||||
|
let mut tags_current_user = false;
|
||||||
|
|
||||||
|
if let Ok(tags) = event.tags() {
|
||||||
|
for mut tag in tags.iter() {
|
||||||
|
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 GLOBALS.config.read().await.user_keys.contains(&tagged_pk) {
|
||||||
|
tags_an_authorized_user = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EventFlags {
|
||||||
|
author_is_an_authorized_user,
|
||||||
|
author_is_current_user,
|
||||||
|
tags_an_authorized_user,
|
||||||
|
tags_current_user,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user