Add util, fix fetch DMs, fully implement delete.

This commit is contained in:
Paul Makles
2020-04-09 18:33:08 +01:00
parent e92b686410
commit 8a4a386ec5
6 changed files with 115 additions and 23 deletions

View File

@@ -159,7 +159,7 @@ impl PermissionCalculator {
let mut other_user = ""; let mut other_user = "";
for item in arr { for item in arr {
if item == &self.user.id { if item == &self.user.id {
permissions = 49; permissions = 177;
} else { } else {
other_user = item; other_user = item;
} }
@@ -174,7 +174,7 @@ impl PermissionCalculator {
{ {
permissions = 1; permissions = 1;
} else if has_mutual_connection(self.user.id, other_user.to_string()) { } else if has_mutual_connection(self.user.id, other_user.to_string()) {
permissions = 49; permissions = 177;
} }
} }
} }
@@ -188,7 +188,7 @@ impl PermissionCalculator {
if let Some(arr) = &channel.recipients { if let Some(arr) = &channel.recipients {
for item in arr { for item in arr {
if item == &self.user.id { if item == &self.user.id {
permissions = 49; permissions = 177;
break; break;
} }
} }

View File

@@ -64,6 +64,7 @@ impl<'r> FromParam<'r> for ChannelRef {
"type": 1, "type": 1,
"recipients": 1, "recipients": 1,
"guild": 1, "guild": 1,
"owner": 1,
}) })
.build(), .build(),
) )

View File

@@ -10,6 +10,7 @@ pub mod database;
pub mod email; pub mod email;
pub mod guards; pub mod guards;
pub mod routes; pub mod routes;
pub mod util;
pub mod websocket; pub mod websocket;
use dotenv; use dotenv;

View File

@@ -5,6 +5,7 @@ use crate::database::{
}; };
use crate::guards::auth::UserRef; use crate::guards::auth::UserRef;
use crate::guards::channel::ChannelRef; use crate::guards::channel::ChannelRef;
use crate::util::vec_to_set;
use bson::{doc, from_bson, Bson, Bson::UtcDatetime}; use bson::{doc, from_bson, Bson, Bson::UtcDatetime};
use chrono::prelude::*; use chrono::prelude::*;
@@ -51,11 +52,8 @@ pub fn create_group(user: UserRef, info: Json<CreateGroup>) -> Response {
let name: String = info.name.chars().take(32).collect(); let name: String = info.name.chars().take(32).collect();
let nonce: String = info.nonce.chars().take(32).collect(); let nonce: String = info.nonce.chars().take(32).collect();
let mut set = HashSet::new(); let mut set = vec_to_set(&info.users);
set.insert(user.id.clone()); set.insert(user.id.clone());
for item in &info.users {
set.insert(item.clone());
}
if set.len() > MAXGROUPSIZE { if set.len() > MAXGROUPSIZE {
return Response::BadRequest(json!({ "error": "Maximum group size is 50." })); return Response::BadRequest(json!({ "error": "Maximum group size is 50." }));
@@ -109,11 +107,29 @@ pub fn channel(user: UserRef, target: ChannelRef) -> Option<Response> {
with_permissions!(user, target); with_permissions!(user, target);
match target.channel_type { match target.channel_type {
0..=1 => Some(Response::Success(json!({ 0 => Some(Response::Success(json!({
"id": target.id, "id": target.id,
"type": target.channel_type, "type": target.channel_type,
"recipients": target.recipients, "recipients": target.recipients,
}))), }))),
1 => {
if let Some(info) = target.fetch_data(doc! {
"name": 1,
"description": 1,
"owner": 1,
}) {
Some(Response::Success(json!({
"id": target.id,
"type": target.channel_type,
"recipients": target.recipients,
"name": info.get_str("name").unwrap(),
"owner": info.get_str("owner").unwrap(),
"description": info.get_str("description").unwrap_or(""),
})))
} else {
None
}
},
2 => { 2 => {
if let Some(info) = target.fetch_data(doc! { if let Some(info) = target.fetch_data(doc! {
"name": 1, "name": 1,
@@ -146,11 +162,33 @@ pub fn delete(user: UserRef, target: ChannelRef) -> Option<Response> {
} }
let col = database::get_collection("channels"); let col = database::get_collection("channels");
let target_id = target.id.clone();
let try_delete = || {
let messages = database::get_collection("messages");
if messages.delete_many(
doc! { "channel": &target_id },
None
).is_ok() {
if col.delete_one(
doc! { "_id": &target_id },
None
).is_ok() {
Some(Response::Result(super::Status::Ok))
} else {
Some(Response::InternalServerError(json!({ "error": "Failed to delete group." })))
}
} else {
Some(Response::InternalServerError(json!({ "error": "Failed to delete messages." })))
}
};
match target.channel_type { match target.channel_type {
0 => { 0 => {
if col if col
.update_one( .update_one(
doc! { "_id": target.id }, doc! { "_id": &target_id },
doc! { "$set": { "active": false } }, doc! { "$set": { "active": false } },
None, None,
) )
@@ -164,14 +202,40 @@ pub fn delete(user: UserRef, target: ChannelRef) -> Option<Response> {
} }
} }
1 => { 1 => {
// ? TODO: group dm let mut recipients =
vec_to_set(&target.recipients.expect("Missing recipients on Group DM."));
let owner = target.owner.expect("Missing owner on Group DM.");
Some(Response::Result(super::Status::Ok)) if recipients.len() == 1 {
try_delete()
} else {
recipients.remove(&user.id);
let new_owner = if owner == user.id {
recipients.iter().next().unwrap()
} else {
&owner
};
if col.update_one(
doc! { "_id": target_id },
doc! {
"$set": {
"owner": new_owner,
},
"$pull": {
"recipients": &user.id,
}
},
None
).is_ok() {
Some(Response::Result(super::Status::Ok))
} else {
Some(Response::InternalServerError(json!({ "error": "Failed to remove you from the group." })))
}
}
} }
2 => { 2 => {
// ? TODO: guild try_delete()
Some(Response::Result(super::Status::Ok))
} }
_ => Some(Response::InternalServerError( _ => Some(Response::InternalServerError(
json!({ "error": "Unknown error has occurred." }), json!({ "error": "Unknown error has occurred." }),

View File

@@ -92,21 +92,41 @@ pub fn dms(user: UserRef) -> Response {
], ],
"recipients": user.id "recipients": user.id
}, },
None, FindOptions::builder()
.projection(doc! {
})
.build(),
) )
.expect("Failed channel lookup"); .expect("Failed channel lookup");
let mut channels = Vec::new(); let mut channels = Vec::new();
for item in results { for item in results {
let channel: Channel = if let Ok(doc) = item {
from_bson(bson::Bson::Document(item.unwrap())).expect("Failed to unwrap channel."); let id = doc.get_str("_id").unwrap();
let recipients = doc.get_array("recipients").unwrap();
channels.push(json!({ match doc.get_i32("type").unwrap() {
"id": channel.id, 0 => {
"type": channel.channel_type, channels.push(json!({
"recipients": channel.recipients, "id": id,
"active": channel.active.unwrap() "type": 0,
})); "recipients": recipients,
}));
},
1 => {
channels.push(json!({
"id": id,
"type": 1,
"recipients": recipients,
"name": doc.get_str("name").unwrap(),
"owner": doc.get_str("owner").unwrap(),
"description": doc.get_str("description").unwrap_or(""),
}));
},
_ => unreachable!()
}
}
} }
Response::Success(json!(channels)) Response::Success(json!(channels))

6
src/util/mod.rs Normal file
View File

@@ -0,0 +1,6 @@
use hashbrown::HashSet;
use std::iter::FromIterator;
pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &Vec<T>) -> HashSet<T> {
HashSet::from_iter(data.iter().cloned())
}