Add group creation. Sync channels to clients on creation.

This commit is contained in:
Paul Makles
2021-01-18 22:02:32 +00:00
parent c562d33c8f
commit 34ac8f54ef
10 changed files with 139 additions and 25 deletions

View File

@@ -0,0 +1,74 @@
use crate::database::*;
use crate::util::result::{Error, Result};
use crate::util::variables::MAX_GROUP_SIZE;
use mongodb::bson::doc;
use rocket_contrib::json::{Json, JsonValue};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::iter::FromIterator;
use ulid::Ulid;
use validator::Validate;
#[derive(Validate, Serialize, Deserialize)]
pub struct Data {
#[validate(length(min = 1, max = 32))]
name: String,
#[validate(length(min = 0, max = 1024))]
description: Option<String>,
// Maximum length of 36 allows both ULIDs and UUIDs.
#[validate(length(min = 1, max = 36))]
nonce: String,
users: Vec<String>
}
#[post("/create", data = "<info>")]
pub async fn req(user: User, info: Json<Data>) -> Result<JsonValue> {
info
.validate()
.map_err(|error| Error::FailedValidation { error })?;
let mut set: HashSet<String> = HashSet::from_iter(info.users.iter().cloned());
set.insert(user.id.clone());
if set.len() > *MAX_GROUP_SIZE {
Err(Error::GroupTooLarge { max: *MAX_GROUP_SIZE })?
}
if get_collection("channels")
.find_one(
doc! {
"nonce": &info.nonce
},
None,
)
.await
.map_err(|_| Error::DatabaseError {
operation: "find_one",
with: "channel",
})?
.is_some()
{
Err(Error::DuplicateNonce)?
}
for target in &set {
if get_relationship(&user, target) != RelationshipStatus::Friend {
Err(Error::NotFriends)?
}
}
let id = Ulid::new().to_string();
let channel = Channel::Group {
id,
nonce: Some(info.nonce.clone()),
name: info.name.clone(),
description: info.description.clone().unwrap_or_else(|| "A group.".to_string()),
owner: user.id,
recipients: set.into_iter().collect::<Vec<String>>()
};
channel.clone().publish().await?;
Ok(json!(channel))
}

View File

@@ -2,7 +2,7 @@ use crate::database::*;
use crate::util::result::{Error, Result};
use mongodb::bson::doc;
use rocket_contrib::json::Json;
use rocket_contrib::json::{Json, JsonValue};
use serde::{Deserialize, Serialize};
use ulid::Ulid;
use validator::Validate;
@@ -17,7 +17,7 @@ pub struct Data {
}
#[post("/<target>/messages", data = "<message>")]
pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<()> {
pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<JsonValue> {
message
.validate()
.map_err(|error| Error::FailedValidation { error })?;
@@ -43,10 +43,10 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<()> {
})?
.is_some()
{
Err(Error::AlreadySentMessage)?
Err(Error::DuplicateNonce)?
}
Message {
let msg = Message {
id: Ulid::new().to_string(),
channel: target.id().to_string(),
author: user.id,
@@ -54,9 +54,12 @@ pub async fn req(user: User, target: Ref, message: Json<Data>) -> Result<()> {
content: message.content.clone(),
nonce: Some(message.nonce.clone()),
edited: None,
}
.send()
.await?;
};
msg
.clone()
.publish()
.await?;
Ok(())
Ok(json!(msg))
}

View File

@@ -7,6 +7,7 @@ mod message_edit;
mod message_fetch;
mod message_query;
mod message_send;
mod group_create;
pub fn routes() -> Vec<Route> {
routes![
@@ -16,6 +17,7 @@ pub fn routes() -> Vec<Route> {
message_query::req,
message_fetch::req,
message_edit::req,
message_delete::req
message_delete::req,
group_create::req
]
}