From b4db819ef8daa583a165aed01eb3d70d98e37fc8 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 1 Jul 2025 01:42:38 -0400 Subject: Prevent sending messages to deleted channels. I've opted to make it clear in the error message which scenario - deleted vs. non-existant - a channel falls into. This isn't particularly consistent with the rest of the API, so we might need to review this decision later, but it's at least relatively harmless if it's mistaken. (Formally, they're both 404s, so clients that go by error code won't notice.) --- src/message/app.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/message/app.rs') diff --git a/src/message/app.rs b/src/message/app.rs index 3c74628..9792c8f 100644 --- a/src/message/app.rs +++ b/src/message/app.rs @@ -29,13 +29,17 @@ impl<'a> Messages<'a> { sent_at: &DateTime, body: &Body, ) -> Result { + let to_not_found = || SendError::ChannelNotFound(channel.clone()); + let to_deleted = || SendError::ChannelDeleted(channel.clone()); + let mut tx = self.db.begin().await?; - let channel = tx - .channels() - .by_id(channel) - .await - .not_found(|| SendError::ChannelNotFound(channel.clone()))?; + let channel = tx.channels().by_id(channel).await.not_found(to_not_found)?; + + // Ordering: don't bother allocating a sequence number before we know the channel might + // exist. let sent = tx.sequence().next(sent_at).await?; + let channel = channel.as_of(sent).ok_or_else(to_deleted)?; + let message = tx.messages().create(&channel, sender, &sent, body).await?; tx.commit().await?; @@ -126,6 +130,8 @@ impl<'a> Messages<'a> { pub enum SendError { #[error("channel {0} not found")] ChannelNotFound(channel::Id), + #[error("channel {0} deleted")] + ChannelDeleted(channel::Id), #[error(transparent)] Database(#[from] sqlx::Error), #[error(transparent)] -- cgit v1.2.3