Skip to content
Snippets Groups Projects
Commit c6ba72d9 authored by insert's avatar insert
Browse files

Add message sending.

parent c401663c
Branches
Tags
No related merge requests found
Pipeline #481 canceled with stage
use crate::database::*;
use crate::util::result::{Error, Result};
use serde::{Serialize, Deserialize};
use rocket_contrib::json::Json;
use validator::Validate;
use mongodb::bson::doc;
use ulid::Ulid;
#[derive(Validate, Serialize, Deserialize)]
pub struct Data {
#[validate(length(min = 1, max = 2000))]
content: String,
// Maximum length of 36 allows both ULIDs and UUIDs.
#[validate(length(min = 1, max = 36))]
nonce: String,
}
#[post("/<target>/messages", data = "<message>")]
pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<()> {
message.validate()
.map_err(|error| Error::FailedValidation { error })?;
let target = target.fetch_channel().await?;
let perm = permissions::channel::calculate(&user, &target).await;
if !perm.get_send_message() {
Err(Error::LabelMe)?
}
if get_collection("messages")
.find_one(
doc! {
"nonce": &message.nonce
},
None
)
.await
.map_err(|_| Error::DatabaseError { operation: "find_one", with: "message" })?
.is_some() {
Err(Error::AlreadySentMessage)?
}
Message {
id: Ulid::new().to_string(),
channel: target.id().to_string(),
author: user.id,
content: message.content.clone(),
nonce: Some(message.nonce.clone()),
edited: None,
}
.send()
.await?;
Ok(())
}
......@@ -2,10 +2,12 @@ use rocket::Route;
mod fetch_channel;
mod delete_channel;
mod message_send;
pub fn routes() -> Vec<Route> {
routes![
fetch_channel::req,
delete_channel::req
delete_channel::req,
message_send::req
]
}
......@@ -31,6 +31,10 @@ pub enum Error {
#[snafu(display("You have been blocked by this user."))]
BlockedByOther,
// ? Channel related errors.
#[snafu(display("Already sent a message with this nonce."))]
AlreadySentMessage,
// ? General errors.
#[snafu(display("Failed to validate fields."))]
FailedValidation { error: ValidationErrors },
......@@ -62,6 +66,8 @@ impl<'r> Responder<'r, 'static> for Error {
Error::Blocked => Status::Conflict,
Error::BlockedByOther => Status::Forbidden,
Error::AlreadySentMessage => Status::Conflict,
Error::FailedValidation { .. } => Status::UnprocessableEntity,
Error::DatabaseError { .. } => Status::InternalServerError,
Error::InternalError => Status::InternalServerError,
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment