From b6b51bca26cd4ca94e749664dcbdb1912af36388 Mon Sep 17 00:00:00 2001 From: Paul Makles <paulmakles@gmail.com> Date: Tue, 16 Feb 2021 09:34:24 +0000 Subject: [PATCH] Route which lets clients determine messages that have updated / deleted. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/routes/channels/message_query_stale.rs | 74 ++++++++++++++++++++++ src/routes/channels/mod.rs | 2 + src/routes/root.rs | 2 +- src/routes/users/find_mutual.rs | 41 ++++++++++++ src/routes/users/mod.rs | 2 + 7 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/routes/channels/message_query_stale.rs create mode 100644 src/routes/users/find_mutual.rs diff --git a/Cargo.lock b/Cargo.lock index 5a6fcf5..f264925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2454,7 +2454,7 @@ dependencies = [ [[package]] name = "revolt" -version = "0.3.3-alpha.3" +version = "0.3.3-alpha.4" dependencies = [ "async-std", "async-tungstenite", diff --git a/Cargo.toml b/Cargo.toml index 25ced13..98bfdd2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt" -version = "0.3.3-alpha.3" +version = "0.3.3-alpha.4" authors = ["Paul Makles <paulmakles@gmail.com>"] edition = "2018" diff --git a/src/routes/channels/message_query_stale.rs b/src/routes/channels/message_query_stale.rs new file mode 100644 index 0000000..d2ee19d --- /dev/null +++ b/src/routes/channels/message_query_stale.rs @@ -0,0 +1,74 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use futures::StreamExt; +use mongodb::bson::{doc, from_document}; +use rocket_contrib::json::{Json, JsonValue}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct Options { + ids: Vec<String> +} + +#[post("/<target>/messages/stale", data = "<data>")] +pub async fn req(user: User, target: Ref, data: Json<Options>) -> Result<JsonValue> { + if data.ids.len() > 150 { + return Err(Error::LabelMe); + } + + let target = target.fetch_channel().await?; + + let perm = permissions::PermissionCalculator::new(&user) + .with_channel(&target) + .for_channel() + .await?; + if !perm.get_view() { + Err(Error::LabelMe)? + } + + let mut cursor = get_collection("messages") + .find( + doc! { + "_id": { + "$in": &data.ids + }, + "channel": target.id() + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "find", + with: "messages", + })?; + + let mut updated = vec![]; + let mut found_ids = vec![]; + while let Some(result) = cursor.next().await { + if let Ok(doc) = result { + let msg = from_document::<Message>(doc) + .map_err(|_| Error::DatabaseError { + operation: "from_document", + with: "message", + })?; + + found_ids.push(msg.id.clone()); + if msg.edited.is_some() { + updated.push(msg); + } + } + } + + let mut deleted = vec![]; + for id in &data.ids { + if found_ids.iter().find(|x| *x == id).is_none() { + deleted.push(id); + } + } + + Ok(json!({ + "updated": updated, + "deleted": deleted + })) +} diff --git a/src/routes/channels/mod.rs b/src/routes/channels/mod.rs index ccc1389..b8f37fe 100644 --- a/src/routes/channels/mod.rs +++ b/src/routes/channels/mod.rs @@ -9,6 +9,7 @@ mod message_delete; mod message_edit; mod message_fetch; mod message_query; +mod message_query_stale; mod message_send; pub fn routes() -> Vec<Route> { @@ -17,6 +18,7 @@ pub fn routes() -> Vec<Route> { delete_channel::req, message_send::req, message_query::req, + message_query_stale::req, message_fetch::req, message_edit::req, message_delete::req, diff --git a/src/routes/root.rs b/src/routes/root.rs index 126479a..70ff4a5 100644 --- a/src/routes/root.rs +++ b/src/routes/root.rs @@ -8,7 +8,7 @@ use rocket_contrib::json::JsonValue; #[get("/")] pub async fn root() -> JsonValue { json!({ - "revolt": "0.3.3-alpha.2", + "revolt": "0.3.3-alpha.4", "features": { "registration": !*DISABLE_REGISTRATION, "captcha": { diff --git a/src/routes/users/find_mutual.rs b/src/routes/users/find_mutual.rs new file mode 100644 index 0000000..e75c07e --- /dev/null +++ b/src/routes/users/find_mutual.rs @@ -0,0 +1,41 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use futures::StreamExt; +use mongodb::options::FindOptions; +use mongodb::bson::{Document, doc}; +use rocket_contrib::json::JsonValue; + +#[get("/<target>/mutual")] +pub async fn req(user: User, target: Ref) -> Result<JsonValue> { + let channels = get_collection("channels") + .find( + doc! { + "$or": [ + { "type": "Group" }, + ], + "$and": [ + { "recipients": &user.id }, + { "recipients": &target.id } + ] + }, + FindOptions::builder() + .projection(doc! { "_id": 1 }) + .build() + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "find", + with: "channels", + })? + .filter_map(async move |s| s.ok()) + .collect::<Vec<Document>>() + .await + .into_iter() + .filter_map(|x| x.get_str("_id").ok().map(|x| x.to_string())) + .collect::<Vec<String>>(); + + Ok(json!({ + "channels": channels + })) +} diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs index 2a0cd2f..163978f 100644 --- a/src/routes/users/mod.rs +++ b/src/routes/users/mod.rs @@ -6,6 +6,7 @@ mod fetch_dms; mod fetch_relationship; mod fetch_relationships; mod fetch_user; +mod find_mutual; mod get_avatar; mod get_default_avatar; mod open_dm; @@ -22,6 +23,7 @@ pub fn routes() -> Vec<Route> { fetch_dms::req, open_dm::req, // Relationships + find_mutual::req, fetch_relationships::req, fetch_relationship::req, add_friend::req, -- GitLab