diff --git a/src/routes/users/change_username.rs b/src/routes/users/change_username.rs index c3637061..1848bdea 100644 --- a/src/routes/users/change_username.rs +++ b/src/routes/users/change_username.rs @@ -1,25 +1,26 @@ -use revolt_quark::{EmptyResponse, Result}; +use revolt_quark::{Error, EmptyResponse, Result, models::User, Database}; use crate::util::regex::RE_USERNAME; use mongodb::bson::doc; use rauth::entities::Account; -use rocket::serde::json::Json; +use rocket::{serde::json::Json, State}; use serde::{Deserialize, Serialize}; use validator::Validate; #[derive(Validate, Serialize, Deserialize)] pub struct Data { #[validate(length(min = 2, max = 32), regex = "RE_USERNAME")] - username: Option, + username: String, #[validate(length(min = 8, max = 1024))] password: String, } -#[patch("/<_ignore_id>/username", data = "")] +#[patch("/@me/username", data = "")] pub async fn req( + db: &State, account: Account, - //user: UserRef, + user: User, data: Json, - _ignore_id: String, ) -> Result { - todo!() + account.verify_password(&data.password).map_err(|_| Error::InvalidCredentials)?; + user.update_username(db, &data.username).await } diff --git a/src/routes/users/fetch_relationship.rs b/src/routes/users/fetch_relationship.rs deleted file mode 100644 index 6d3360e8..00000000 --- a/src/routes/users/fetch_relationship.rs +++ /dev/null @@ -1,8 +0,0 @@ -use revolt_quark::{Error, Result}; - -use rocket::serde::json::Value; - -#[get("//relationship")] -pub async fn req(/*user: UserRef, target: Ref*/ target: String) -> Result { - todo!() -} diff --git a/src/routes/users/fetch_relationships.rs b/src/routes/users/fetch_relationships.rs deleted file mode 100644 index 9f5edb02..00000000 --- a/src/routes/users/fetch_relationships.rs +++ /dev/null @@ -1,8 +0,0 @@ -use revolt_quark::{Error, Result}; - -use rocket::serde::json::Value; - -#[get("/relationships")] -pub async fn req(/*user: UserRef*/) -> Result { - todo!() -} diff --git a/src/routes/users/fetch_self.rs b/src/routes/users/fetch_self.rs index 4dfdf3db..89831878 100755 --- a/src/routes/users/fetch_self.rs +++ b/src/routes/users/fetch_self.rs @@ -1,3 +1,5 @@ +//! Fetch the currently authenticated session's user account + use revolt_quark::Result; use revolt_quark::models::User; diff --git a/src/routes/users/fetch_user.rs b/src/routes/users/fetch_user.rs index 008444ea..d3684235 100644 --- a/src/routes/users/fetch_user.rs +++ b/src/routes/users/fetch_user.rs @@ -1,8 +1,19 @@ -use revolt_quark::{Ref, Result, models::User}; +//! Fetch another user +//! +//! Will fail if the authenticated user does not +//! have permission to access the other user. -use rocket::serde::json::Value; +use revolt_quark::{Ref, Result, Error, models::User, perms, Database}; + +use rocket::{serde::json::Json, State}; #[get("/")] -pub async fn req(user: User, target: Ref) -> Result { - todo!() +pub async fn req(db: &State, user: User, target: Ref) -> Result> { + let target = target.as_user(db).await?; + + if perms(&user).user(&target).calc_user(db).await.get_access() { + Ok(Json(target)) + } else { + Err(Error::NotFound) + } } diff --git a/src/routes/users/get_default_avatar.rs b/src/routes/users/get_default_avatar.rs index 56e3bc2a..b30c61ba 100644 --- a/src/routes/users/get_default_avatar.rs +++ b/src/routes/users/get_default_avatar.rs @@ -5,7 +5,7 @@ use std::path::Path; pub struct CachedFile(NamedFile); -pub static CACHE_CONTROL: &'static str = "public, max-age=31536000, immutable"; +pub static CACHE_CONTROL: &str = "public, max-age=31536000, immutable"; impl<'r> Responder<'r, 'static> for CachedFile { fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> { @@ -19,22 +19,22 @@ impl<'r> Responder<'r, 'static> for CachedFile { pub async fn req(target: String) -> Option { match target.chars().nth(25).unwrap() { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' => { - NamedFile::open(Path::new("assets/user_red.png")).await.ok().map(|n| CachedFile(n)) + NamedFile::open(Path::new("assets/user_red.png")).await.ok().map(CachedFile) } '8' | '9' | 'A' | 'C' | 'B' | 'D' | 'E' | 'F' => { NamedFile::open(Path::new("assets/user_green.png")) .await - .ok().map(|n| CachedFile(n)) + .ok().map(CachedFile) } 'G' | 'H' | 'J' | 'K' | 'M' | 'N' | 'P' | 'Q' => { NamedFile::open(Path::new("assets/user_blue.png")) .await - .ok().map(|n| CachedFile(n)) + .ok().map(CachedFile) } 'R' | 'S' | 'T' | 'V' | 'W' | 'X' | 'Y' | 'Z' => { NamedFile::open(Path::new("assets/user_yellow.png")) .await - .ok().map(|n| CachedFile(n)) + .ok().map(CachedFile) } _ => unreachable!(), } diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs index a28b649b..084267ab 100644 --- a/src/routes/users/mod.rs +++ b/src/routes/users/mod.rs @@ -6,8 +6,6 @@ mod change_username; mod edit_user; mod fetch_dms; mod fetch_profile; -mod fetch_relationship; -mod fetch_relationships; mod fetch_user; mod find_mutual; mod get_default_avatar; @@ -30,8 +28,6 @@ pub fn routes() -> Vec { open_dm::req, // Relationships find_mutual::req, - fetch_relationships::req, - fetch_relationship::req, add_friend::req, remove_friend::req, block_user::req, diff --git a/src/routes/users/open_dm.rs b/src/routes/users/open_dm.rs index 5f08a333..8f40d0e7 100644 --- a/src/routes/users/open_dm.rs +++ b/src/routes/users/open_dm.rs @@ -1,10 +1,31 @@ -use revolt_quark::{Error, Result}; +//! Open a direct message with another user + +use revolt_quark::{Error, Result, Ref, models::{User, Channel}, Database, perms, UserPermission}; use mongodb::bson::doc; -use rocket::serde::json::Value; +use rocket::{State, serde::json::Json}; use ulid::Ulid; #[get("//dm")] -pub async fn req(/*user: UserRef, target: Ref*/ target: String) -> Result { - todo!() +pub async fn req(db: &State, user: User, target: Ref) -> Result> { + let target = target.as_user(db).await?; + + if let Ok(channel) = db.find_direct_message_channel(&user.id, &target.id).await { + Ok(Json(channel)) + } else if perms(&user).user(&target).calc_user(db).await.get_send_message() { + let new_channel = Channel::DirectMessage { + id: Ulid::new().to_string(), + active: false, + recipients: vec! [ + user.id.clone(), + target.id.clone() + ], + last_message_id: None, + }; + + db.insert_channel(&new_channel).await?; + Ok(Json(new_channel)) + } else { + Error::from_permission(UserPermission::SendMessage) + } }