diff --git a/src/routes/servers/member_edit.rs b/src/routes/servers/member_edit.rs index d7e51f62..b382e204 100644 --- a/src/routes/servers/member_edit.rs +++ b/src/routes/servers/member_edit.rs @@ -1,4 +1,10 @@ -use revolt_quark::{models::server_member::FieldsMember, EmptyResponse, Result}; +use revolt_quark::{ + models::{ + server_member::{FieldsMember, PartialMember}, + File, Member, User, + }, + perms, Db, Error, Ref, Result, +}; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; @@ -16,9 +22,69 @@ pub struct Data { #[patch("//members/", data = "")] pub async fn req( - /*user: UserRef, server: Ref,*/ server: String, - target: String, + db: &Db, + user: User, + server: Ref, + target: Ref, data: Json, -) -> Result { - todo!() +) -> Result> { + let data = data.into_inner(); + data.validate() + .map_err(|error| Error::FailedValidation { error })?; + + let server = server.as_server(db).await?; + let permissions = perms(&user).server(&server).calc_server(db).await; + if !permissions.get_view() { + return Err(Error::NotFound); + } + + let mut member = target.as_member(db, &server.id).await?; + + let Data { + nickname, + avatar, + roles, + remove, + } = data; + + let mut partial = PartialMember { + nickname, + roles, + ..Default::default() + }; + + // ! FIXME: calculate permission against member + + // 1. Remove fields from object + if let Some(fields) = &remove { + if fields.contains(&FieldsMember::Avatar) { + if let Some(avatar) = &member.avatar { + db.mark_attachment_as_deleted(&avatar.id).await?; + } + } + + for field in fields { + member.remove(field); + } + } + + // 2. Apply new avatar + if let Some(avatar) = avatar { + partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?); + member.avatar = partial.avatar.clone(); + } + + // 3. Copy over other fields + if let Some(nickname) = &partial.nickname { + member.nickname.replace(nickname.clone()); + } + + if let Some(roles) = &partial.roles { + member.roles.replace(roles.clone()); + } + + db.update_member(&member.id, &partial, remove.unwrap_or_else(Vec::new)) + .await?; + + Ok(Json(member)) } diff --git a/src/routes/servers/member_fetch.rs b/src/routes/servers/member_fetch.rs index 045d8e82..f9212cc4 100644 --- a/src/routes/servers/member_fetch.rs +++ b/src/routes/servers/member_fetch.rs @@ -1,12 +1,20 @@ -use revolt_quark::{Error, Result}; - -use mongodb::bson::doc; -use rocket::serde::json::Value; +use revolt_quark::{ + models::{Member, User}, + perms, Db, Error, Ref, Result, +}; +use rocket::serde::json::Json; #[get("//members/")] -pub async fn req( - /*user: UserRef, target: Ref,*/ target: String, - member: String, -) -> Result { - todo!() +pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result> { + let server = target.as_server(db).await?; + if !perms(&user) + .server(&server) + .calc_server(db) + .await + .get_view() + { + return Err(Error::NotFound); + } + + member.as_member(db, &server.id).await.map(Json) } diff --git a/src/routes/servers/member_fetch_all.rs b/src/routes/servers/member_fetch_all.rs index ebf1fc03..7e739315 100644 --- a/src/routes/servers/member_fetch_all.rs +++ b/src/routes/servers/member_fetch_all.rs @@ -1,9 +1,30 @@ -use revolt_quark::{Error, Result}; +use revolt_quark::{models::User, perms, Db, Error, Ref, Result}; -use mongodb::bson::{doc, from_document, Document}; use rocket::serde::json::Value; #[get("//members")] -pub async fn req(/*user: UserRef, target: Ref*/ target: String) -> Result { - todo!() +pub async fn req(db: &Db, user: User, target: Ref) -> Result { + let server = target.as_server(db).await?; + if !perms(&user) + .server(&server) + .calc_server(db) + .await + .get_view() + { + return Err(Error::NotFound); + } + + let members = db.fetch_all_members(&server.id).await?; + + let mut user_ids = vec![]; + for member in &members { + user_ids.push(member.id.user.clone()); + } + + let users = db.fetch_users(&user_ids).await?; + + Ok(json!({ + "members": members, + "users": users + })) } diff --git a/src/routes/servers/member_remove.rs b/src/routes/servers/member_remove.rs index bc3a114f..ec2d5b6f 100644 --- a/src/routes/servers/member_remove.rs +++ b/src/routes/servers/member_remove.rs @@ -1,11 +1,23 @@ -use revolt_quark::{EmptyResponse, Result}; +use revolt_quark::{models::User, perms, Db, EmptyResponse, Error, Ref, Result, ServerPermission}; use mongodb::bson::doc; #[delete("//members/")] -pub async fn req( - /*user: UserRef, target: Ref,*/ target: String, - member: String, -) -> Result { - todo!() +pub async fn req(db: &Db, user: User, target: Ref, member: Ref) -> Result { + let server = target.as_server(db).await?; + if !perms(&user) + .server(&server) + .calc_server(db) + .await + .get_kick_members() + { + return Err(Error::MissingPermission { + permission: ServerPermission::KickMembers as i32, + }); + } + + let member = member.as_member(db, &server.id).await?; + // ! FIXME: calculate permission against member + + db.delete_member(&member.id).await.map(|_| EmptyResponse) }