mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
Restructure handling code to ensure EVENT always gets an OK reply (except for early errors)
This commit is contained in:
parent
775f15e864
commit
a1c81acd8f
12
src/error.rs
12
src/error.rs
@ -25,6 +25,9 @@ pub enum ChorusError {
|
|||||||
// Auth failure
|
// Auth failure
|
||||||
AuthFailure,
|
AuthFailure,
|
||||||
|
|
||||||
|
// Auth required
|
||||||
|
AuthRequired,
|
||||||
|
|
||||||
// Bad event id
|
// Bad event id
|
||||||
BadEventId,
|
BadEventId,
|
||||||
|
|
||||||
@ -52,6 +55,9 @@ pub enum ChorusError {
|
|||||||
// End of Input
|
// End of Input
|
||||||
EndOfInput,
|
EndOfInput,
|
||||||
|
|
||||||
|
// Event is Invalid
|
||||||
|
EventIsInvalid(String),
|
||||||
|
|
||||||
// Http
|
// Http
|
||||||
Http(hyper::http::Error),
|
Http(hyper::http::Error),
|
||||||
|
|
||||||
@ -88,6 +94,9 @@ pub enum ChorusError {
|
|||||||
// No private key
|
// No private key
|
||||||
NoPrivateKey,
|
NoPrivateKey,
|
||||||
|
|
||||||
|
// Restricted
|
||||||
|
Restricted,
|
||||||
|
|
||||||
// Rustls
|
// Rustls
|
||||||
Rustls(tokio_rustls::rustls::Error),
|
Rustls(tokio_rustls::rustls::Error),
|
||||||
|
|
||||||
@ -114,6 +123,7 @@ impl std::fmt::Display for ChorusError {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ChorusError::AuthFailure => write!(f, "AUTH failure"),
|
ChorusError::AuthFailure => write!(f, "AUTH failure"),
|
||||||
|
ChorusError::AuthRequired => write!(f, "AUTH required"),
|
||||||
ChorusError::BadEventId => write!(f, "Bad event id, does not match hash"),
|
ChorusError::BadEventId => write!(f, "Bad event id, does not match hash"),
|
||||||
ChorusError::BadHexInput => write!(f, "Bad hex input"),
|
ChorusError::BadHexInput => write!(f, "Bad hex input"),
|
||||||
ChorusError::BufferTooSmall => write!(f, "Output buffer too small"),
|
ChorusError::BufferTooSmall => write!(f, "Output buffer too small"),
|
||||||
@ -123,6 +133,7 @@ impl std::fmt::Display for ChorusError {
|
|||||||
ChorusError::Crypto(e) => write!(f, "{e}"),
|
ChorusError::Crypto(e) => write!(f, "{e}"),
|
||||||
ChorusError::Duplicate => write!(f, "Duplicate"),
|
ChorusError::Duplicate => write!(f, "Duplicate"),
|
||||||
ChorusError::EndOfInput => write!(f, "End of input"),
|
ChorusError::EndOfInput => write!(f, "End of input"),
|
||||||
|
ChorusError::EventIsInvalid(s) => write!(f, "Event is invalid: {s}"),
|
||||||
ChorusError::Http(e) => write!(f, "{e}"),
|
ChorusError::Http(e) => write!(f, "{e}"),
|
||||||
ChorusError::Hyper(e) => write!(f, "{e}"),
|
ChorusError::Hyper(e) => write!(f, "{e}"),
|
||||||
ChorusError::Io(e) => write!(f, "{e}"),
|
ChorusError::Io(e) => write!(f, "{e}"),
|
||||||
@ -147,6 +158,7 @@ impl std::fmt::Display for ChorusError {
|
|||||||
),
|
),
|
||||||
ChorusError::Lmdb(e) => write!(f, "{e}"),
|
ChorusError::Lmdb(e) => write!(f, "{e}"),
|
||||||
ChorusError::NoPrivateKey => write!(f, "Private Key Not Found"),
|
ChorusError::NoPrivateKey => write!(f, "Private Key Not Found"),
|
||||||
|
ChorusError::Restricted => write!(f, "Restricted"),
|
||||||
ChorusError::Rustls(e) => write!(f, "{e}"),
|
ChorusError::Rustls(e) => write!(f, "{e}"),
|
||||||
ChorusError::Tungstenite(e) => write!(f, "{e}"),
|
ChorusError::Tungstenite(e) => write!(f, "{e}"),
|
||||||
ChorusError::Scraper => write!(f, "Filter is underspecified. Scrapers are not allowed"),
|
ChorusError::Scraper => write!(f, "Filter is underspecified. Scrapers are not allowed"),
|
||||||
|
|||||||
77
src/nostr.rs
77
src/nostr.rs
@ -115,6 +115,8 @@ impl WebSocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn event(&mut self, msg: String, mut inpos: usize) -> Result<(), Error> {
|
pub async fn event(&mut self, msg: String, mut inpos: usize) -> Result<(), Error> {
|
||||||
|
const PERSONAL_MSG: &str = "this personal relay only accepts events related to its users";
|
||||||
|
|
||||||
let input = msg.as_bytes();
|
let input = msg.as_bytes();
|
||||||
|
|
||||||
eat_whitespace(input, &mut inpos);
|
eat_whitespace(input, &mut inpos);
|
||||||
@ -123,54 +125,61 @@ impl WebSocketService {
|
|||||||
|
|
||||||
// Read the event into the session buffer
|
// Read the event into the session buffer
|
||||||
let (_incount, event) = Event::from_json(&input[inpos..], &mut self.buffer)?;
|
let (_incount, event) = Event::from_json(&input[inpos..], &mut self.buffer)?;
|
||||||
|
let id = event.id();
|
||||||
|
|
||||||
|
let reply = match self.event_inner().await {
|
||||||
|
Ok(()) => NostrReply::Ok(id, true, NostrReplyPrefix::None, "".to_string()),
|
||||||
|
Err(e) => match e.inner {
|
||||||
|
ChorusError::AuthRequired => NostrReply::Ok(
|
||||||
|
id,
|
||||||
|
false,
|
||||||
|
NostrReplyPrefix::AuthRequired,
|
||||||
|
PERSONAL_MSG.to_owned(),
|
||||||
|
),
|
||||||
|
ChorusError::Duplicate => {
|
||||||
|
NostrReply::Ok(id, false, NostrReplyPrefix::Duplicate, "".to_string())
|
||||||
|
}
|
||||||
|
ChorusError::EventIsInvalid(why) => {
|
||||||
|
NostrReply::Ok(id, false, NostrReplyPrefix::Invalid, why)
|
||||||
|
}
|
||||||
|
ChorusError::Restricted => NostrReply::Ok(
|
||||||
|
id,
|
||||||
|
false,
|
||||||
|
NostrReplyPrefix::Restricted,
|
||||||
|
PERSONAL_MSG.to_owned(),
|
||||||
|
),
|
||||||
|
_ => NostrReply::Ok(id, false, NostrReplyPrefix::Error, format!("{}", e)),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
self.websocket.send(Message::text(reply.as_json())).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_inner(&mut self) -> Result<(), Error> {
|
||||||
|
// Delineate the event back out of the session buffer
|
||||||
|
let event = Event::delineate(&self.buffer)?;
|
||||||
|
|
||||||
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() {
|
||||||
let reply = NostrReply::Ok(
|
return Err(ChorusError::EventIsInvalid(format!("{}", e)).into());
|
||||||
event.id(),
|
|
||||||
false,
|
|
||||||
NostrReplyPrefix::Invalid,
|
|
||||||
format!("{}", e),
|
|
||||||
);
|
|
||||||
self.websocket.send(Message::text(reply.as_json())).await?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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_event(&event, self.user).await? {
|
if !screen_event(&event, self.user).await? {
|
||||||
let prefix = if self.user.is_some() {
|
if self.user.is_some() {
|
||||||
NostrReplyPrefix::Restricted
|
return Err(ChorusError::Restricted.into());
|
||||||
} else {
|
} else {
|
||||||
NostrReplyPrefix::AuthRequired
|
return Err(ChorusError::AuthRequired.into());
|
||||||
};
|
}
|
||||||
let reply = NostrReply::Ok(
|
|
||||||
event.id(),
|
|
||||||
false,
|
|
||||||
prefix,
|
|
||||||
"this personal relay only accepts events related to its users".to_owned(),
|
|
||||||
);
|
|
||||||
self.websocket.send(Message::text(reply.as_json())).await?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store and index the event
|
// Store and index the event
|
||||||
let reply = match GLOBALS.store.get().unwrap().store_event(&event) {
|
let offset = GLOBALS.store.get().unwrap().store_event(&event)?;
|
||||||
Ok(offset) => {
|
GLOBALS.new_events.send(offset)?; // advertise the new event
|
||||||
GLOBALS.new_events.send(offset)?; // advertise the new event
|
|
||||||
NostrReply::Ok(event.id(), true, NostrReplyPrefix::None, "".to_owned())
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
if matches!(e.inner, ChorusError::Duplicate) {
|
|
||||||
NostrReply::Ok(event.id(), true, NostrReplyPrefix::Duplicate, "".to_owned())
|
|
||||||
} else {
|
|
||||||
NostrReply::Ok(event.id(), false, NostrReplyPrefix::Error, format!("{e}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.websocket.send(Message::text(reply.as_json())).await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user