Files
stoatchat/src/routes/channels/message_send.rs
2021-01-26 22:05:32 +00:00

66 lines
1.6 KiB
Rust

use crate::database::*;
use crate::util::result::{Error, Result};
use mongodb::bson::doc;
use rocket_contrib::json::{Json, JsonValue};
use serde::{Deserialize, Serialize};
use ulid::Ulid;
use validator::Validate;
#[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<JsonValue> {
message
.validate()
.map_err(|error| Error::FailedValidation { error })?;
let target = target.fetch_channel().await?;
let perm = permissions::PermissionCalculator::new(&user)
.with_channel(&target)
.for_channel()
.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::DuplicateNonce)?
}
let msg = 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,
};
msg.clone().publish(&target).await?;
Ok(json!(msg))
}