diff --git a/src/database/entities/server.rs b/src/database/entities/server.rs index fefdc0e9ddf53f82e2d0fcd84c89d1c64c932263..ff1d48e2ca9541be82406d4d931109937ea36d2d 100644 --- a/src/database/entities/server.rs +++ b/src/database/entities/server.rs @@ -42,9 +42,6 @@ pub struct Server { pub owner: String, pub name: String, - // pub default_permissions: u32, - // pub invites: Vec<Invite>, - // pub bans: Vec<Ban>, pub channels: Vec<String>, #[serde(skip_serializing_if = "Option::is_none")] @@ -90,6 +87,8 @@ impl Server { let messages = get_collection("messages"); // Check if there are any attachments we need to delete. + // ! FIXME: make this generic and merge with channel delete + // ! e.g. delete_channel(filter: doc!) let message_ids = messages .find( doc! { @@ -206,6 +205,32 @@ impl Server { Ok(()) } + pub async fn fetch_members(id: &str) -> Result<Vec<String>> { + Ok(get_collection("server_members") + .find( + doc! { + "_id.server": id + }, + None, + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "find", + with: "server_members", + })? + .filter_map(async move |s| s.ok()) + .collect::<Vec<Document>>() + .await + .into_iter() + .filter_map(|x| { + x.get_document("_id") + .ok() + .map(|i| i.get_str("user").ok().map(|x| x.to_string())) + }) + .flatten() + .collect::<Vec<String>>()) + } + pub async fn join_member(&self, id: &str) -> Result<()> { get_collection("server_members") .insert_one( diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs index 7833ccdd6c8ae708c53a8aeb1cb84567870bf5b7..21c427dc2d212a09954728343cdf765727ea3d1b 100644 --- a/src/database/entities/user.rs +++ b/src/database/entities/user.rs @@ -184,6 +184,7 @@ impl User { } /// Utility function for fetching multiple users from the perspective of one. + /// Assumes user has a mutual connection with others. pub async fn fetch_multiple_users(&self, user_ids: Vec<String>) -> Result<Vec<User>> { let mut users = vec![]; let mut cursor = get_collection("users") diff --git a/src/notifications/events.rs b/src/notifications/events.rs index f51c329dcfb776a3be68dfb71ecaec71de3682b1..a78a312d0f6bbc8752ba105540fbbf694aff4e35 100644 --- a/src/notifications/events.rs +++ b/src/notifications/events.rs @@ -166,30 +166,7 @@ pub async fn prehandle_hook(notification: &ClientboundNotification) -> Result<() } Channel::TextChannel { server, .. } => { // ! FIXME: write a better algorithm? - let members = get_collection("server_members") - .find( - doc! { - "_id.server": server - }, - None, - ) - .await - .map_err(|_| Error::DatabaseError { - operation: "find", - with: "server_members", - })? - .filter_map(async move |s| s.ok()) - .collect::<Vec<Document>>() - .await - .into_iter() - .filter_map(|x| { - x.get_document("_id") - .ok() - .map(|i| i.get_str("user").ok().map(|x| x.to_string())) - }) - .flatten() - .collect::<Vec<String>>(); - + let members = Server::fetch_members(server).await?; for member in members { subscribe_if_exists(member.clone(), channel_id.to_string()).ok(); } diff --git a/src/routes/servers/members_fetch.rs b/src/routes/servers/members_fetch.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfe9a375e5d2b3470eafe0021edd587a2f1f334d --- /dev/null +++ b/src/routes/servers/members_fetch.rs @@ -0,0 +1,23 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use rocket_contrib::json::JsonValue; + +// ! FIXME: this is a temporary route while permissions are being worked on. + +#[get("/<target>/members")] +pub async fn req(user: User, target: Ref) -> Result<JsonValue> { + let target = target.fetch_server().await?; + + let perm = permissions::PermissionCalculator::new(&user) + .with_server(&target) + .for_server() + .await?; + + if !perm.get_view() { + Err(Error::MissingPermission)? + } + + let members = Server::fetch_members(&target.id).await?; + Ok(json!(user.fetch_multiple_users(members).await?)) +} diff --git a/src/routes/servers/mod.rs b/src/routes/servers/mod.rs index 20ef08b0aa43dd86a99ef77d2dd1fd55139dae0e..b668399dfa0c141d1efd79238119976eea6b7c5a 100644 --- a/src/routes/servers/mod.rs +++ b/src/routes/servers/mod.rs @@ -7,12 +7,15 @@ mod server_edit; mod channel_create; +mod members_fetch; + pub fn routes() -> Vec<Route> { routes![ server_create::req, server_delete::req, server_fetch::req, server_edit::req, - channel_create::req + channel_create::req, + members_fetch::req ] }