From 63064cc9bb932fb0011f85597663c5eba3138806 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 3 Feb 2022 22:52:04 +0000 Subject: [PATCH] feat: implement edit user / username --- Cargo.lock | 166 +++------------------------- Cargo.toml | 6 +- src/routes/users/change_username.rs | 5 +- src/routes/users/edit_user.rs | 81 ++++++++++++-- 4 files changed, 94 insertions(+), 164 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 322181c6..6e0f7882 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1422,22 +1422,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6" -dependencies = [ - "bytes 0.5.6", - "futures-util", - "hyper 0.13.10", - "log", - "rustls 0.18.1", - "tokio 0.2.25", - "tokio-rustls 0.14.1", - "webpki", -] - [[package]] name = "hyper-tls" version = "0.4.3" @@ -1748,16 +1732,6 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -[[package]] -name = "mime_guess" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "miniz_oxide" version = "0.4.4" @@ -1853,6 +1827,7 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd2a1cb6fd58c27e51ee650dca3b6924c4ce533dc0384f05b3219709ea1f1eb6" dependencies = [ + "async-std", "async-trait", "base64 0.11.0", "bitflags", @@ -1869,10 +1844,8 @@ dependencies = [ "pbkdf2", "percent-encoding", "rand 0.7.3", - "reqwest 0.10.10", "rustls 0.17.0", "serde", - "serde_bytes", "serde_with", "sha-1 0.9.8", "sha2", @@ -1889,7 +1862,7 @@ dependencies = [ "uuid", "version_check", "webpki", - "webpki-roots 0.21.1", + "webpki-roots", ] [[package]] @@ -1938,7 +1911,7 @@ dependencies = [ "uuid", "version_check", "webpki", - "webpki-roots 0.21.1", + "webpki-roots", ] [[package]] @@ -2753,7 +2726,7 @@ dependencies = [ [[package]] name = "rauth" version = "1.0.0" -source = "git+https://github.com/insertish/rauth?rev=157263ffcbd6cb1073e288b215db227634c4c29a#157263ffcbd6cb1073e288b215db227634c4c29a" +source = "git+https://github.com/insertish/rauth?rev=501d445e7b42a1c229bfa88c01fa6415f4cb7992#501d445e7b42a1c229bfa88c01fa6415f4cb7992" dependencies = [ "async-std", "base32", @@ -2767,14 +2740,14 @@ dependencies = [ "nanoid", "rand 0.8.4", "regex", - "reqwest 0.11.4", + "reqwest", "rocket", "rust-argon2", "serde", "serde_json", "totp-lite", "ulid", - "validator 0.14.0", + "validator", "wither", ] @@ -2884,43 +2857,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "reqwest" -version = "0.10.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c" -dependencies = [ - "base64 0.13.0", - "bytes 0.5.6", - "encoding_rs", - "futures-core", - "futures-util", - "http", - "http-body 0.3.1", - "hyper 0.13.10", - "hyper-rustls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite 0.2.7", - "rustls 0.18.1", - "serde", - "serde_json", - "serde_urlencoded", - "tokio 0.2.25", - "tokio-rustls 0.14.1", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.20.0", - "winreg 0.7.0", -] - [[package]] name = "reqwest" version = "0.11.4" @@ -2998,7 +2934,7 @@ dependencies = [ "rauth", "redis 0.21.2", "regex", - "reqwest 0.11.4", + "reqwest", "revolt-quark", "rmp-serde", "rocket", @@ -3007,7 +2943,7 @@ dependencies = [ "serde_json", "ulid", "url", - "validator 0.11.0", + "validator", "web-push", ] @@ -3028,7 +2964,7 @@ dependencies = [ "rauth", "rocket", "serde", - "validator 0.14.0", + "validator", ] [[package]] @@ -3203,19 +3139,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "rustls" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" -dependencies = [ - "base64 0.12.3", - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.19.1" @@ -3804,7 +3727,6 @@ dependencies = [ "lazy_static", "memchr", "mio 0.6.23", - "num_cpus", "pin-project-lite 0.1.12", "slab", "tokio-macros 0.2.6", @@ -3873,18 +3795,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "tokio-rustls" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a" -dependencies = [ - "futures-core", - "rustls 0.18.1", - "tokio 0.2.25", - "webpki", -] - [[package]] name = "tokio-rustls" version = "0.22.0" @@ -4286,23 +4196,6 @@ dependencies = [ "serde", ] -[[package]] -name = "validator" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4effc922f18d14f3daf201b1d13c61e5ef62f5975e7d18df381f67badd76cfcd" -dependencies = [ - "idna", - "lazy_static", - "regex", - "serde", - "serde_derive", - "serde_json", - "url", - "validator_derive 0.11.0", - "validator_types 0.11.0", -] - [[package]] name = "validator" version = "0.14.0" @@ -4316,24 +4209,8 @@ dependencies = [ "serde_derive", "serde_json", "url", - "validator_derive 0.14.0", - "validator_types 0.14.0", -] - -[[package]] -name = "validator_derive" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15529099583e8ce2b070ab6a637454a1b42c7146e6daee4a6817a82bee33bd41" -dependencies = [ - "if_chain", - "lazy_static", - "proc-macro-error", - "proc-macro2", - "quote 1.0.9", - "regex", - "syn 1.0.76", - "validator_types 0.11.0", + "validator_derive", + "validator_types", ] [[package]] @@ -4349,15 +4226,9 @@ dependencies = [ "quote 1.0.9", "regex", "syn 1.0.76", - "validator_types 0.14.0", + "validator_types", ] -[[package]] -name = "validator_types" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add324da7950ac1f76b1c16ce8b5406147953d5d6a2ac1c5da93785f2cfc738b" - [[package]] name = "validator_types" version = "0.14.0" @@ -4531,15 +4402,6 @@ dependencies = [ "untrusted 0.7.1", ] -[[package]] -name = "webpki-roots" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.21.1" @@ -4628,7 +4490,7 @@ dependencies = [ [[package]] name = "wither" version = "0.9.0" -source = "git+https://github.com/insertish/wither?branch=master#25226946ff9a2cafac390968b317df83eaafe31f" +source = "git+https://github.com/insertish/wither?rev=25226946ff9a2cafac390968b317df83eaafe31f#25226946ff9a2cafac390968b317df83eaafe31f" dependencies = [ "async-trait", "chrono", @@ -4644,7 +4506,7 @@ dependencies = [ [[package]] name = "wither_derive" version = "0.9.0" -source = "git+https://github.com/insertish/wither?branch=master#25226946ff9a2cafac390968b317df83eaafe31f" +source = "git+https://github.com/insertish/wither?rev=25226946ff9a2cafac390968b317df83eaafe31f#25226946ff9a2cafac390968b317df83eaafe31f" dependencies = [ "Inflector", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index abbfbdb5..9951fda7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ base64 = "0.13.0" # serde serde_json = "1.0.57" serde = { version = "1.0.115", features = ["derive"] } -validator = { version = "0.11", features = ["derive"] } +validator = { version = "0.14", features = ["derive"] } rmp-serde = { git = "https://github.com/insertish/msgpack-rust", rev = "5bf2c24203ad422233cf35b7b7bfad9f7e811814" } # async @@ -50,7 +50,7 @@ async-std = { version = "1.8.0", features = ["tokio1", "tokio02", "attributes"] web-push = "0.7.2" many-to-many = "0.1.2" lettre = "0.10.0-alpha.4" -rauth = { git = "https://github.com/insertish/rauth", rev = "157263ffcbd6cb1073e288b215db227634c4c29a" } +rauth = { git = "https://github.com/insertish/rauth", rev = "501d445e7b42a1c229bfa88c01fa6415f4cb7992" } hive_pubsub = { git = "https://gitlab.insrt.uk/insert/hive", rev = "b0f3db9d33990530d7640d4bbb309c8d9eb5c0cf", features = ["redis-backend"] } # redis @@ -61,7 +61,7 @@ mobc-redis = { version = "0.7.0", default-features = false, features = ["async-s # web async-tungstenite = { version = "0.10.0", features = ["async-std-runtime"] } rocket = { version = "0.5.0-rc.1", default-features = false, features = ["json"] } -mongodb = { version = "1.2.2", features = ["tokio-runtime"], default-features = false } +mongodb = { version = "1.2.2", features = ["async-std-runtime"], default-features = false } rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "5843861a88958c16bfaa0b40f0d8910772bcd2f6" } # quark diff --git a/src/routes/users/change_username.rs b/src/routes/users/change_username.rs index 1848bdea..65169ed5 100644 --- a/src/routes/users/change_username.rs +++ b/src/routes/users/change_username.rs @@ -18,9 +18,10 @@ pub struct Data { pub async fn req( db: &State, account: Account, - user: User, + mut user: User, data: Json, ) -> Result { + let data = data.into_inner(); account.verify_password(&data.password).map_err(|_| Error::InvalidCredentials)?; - user.update_username(db, &data.username).await + user.update_username(db, data.username).await.map(|_| EmptyResponse) } diff --git a/src/routes/users/edit_user.rs b/src/routes/users/edit_user.rs index b2a10a31..7d0f82f0 100644 --- a/src/routes/users/edit_user.rs +++ b/src/routes/users/edit_user.rs @@ -1,7 +1,10 @@ -use revolt_quark::{EmptyResponse, Result, models::user::FieldsUser}; +use revolt_quark::models::File; +use revolt_quark::{Error, Result, Database}; +use revolt_quark::models::user::{FieldsUser, User, PartialUser}; -use mongodb::bson::{doc, to_document}; +use mongodb::bson::doc; use revolt_quark::models::user::UserStatus; +use rocket::State; use rocket::serde::json::Json; use serde::{Deserialize, Serialize}; use validator::Validate; @@ -18,16 +21,80 @@ pub struct UserProfileData { #[derive(Validate, Serialize, Deserialize)] pub struct Data { - // #[validate] + #[validate] status: Option, #[validate] profile: Option, #[validate(length(min = 1, max = 128))] avatar: Option, - remove: Option, + #[validate(length(min = 1))] + remove: Option>, } -#[patch("/<_ignore_id>", data = "")] -pub async fn req(/*user: UserRef,*/ data: Json, _ignore_id: String) -> Result { - todo!() +#[patch("/@me", data = "")] +pub async fn req(db: &State, mut user: User, data: Json) -> Result> { + let data = data.into_inner(); + data.validate().map_err(|error| Error::FailedValidation { error })?; + + if data.status.is_none() && data.profile.is_none() && data.avatar.is_none() && data.remove.is_none() { + return Ok(Json(user)) + } + + if let Some(fields) = &data.remove { + if fields.contains(&FieldsUser::Avatar) { + if let Some(_avatar) = &user.avatar { + // TODO: delete the avatar + } + } + + if fields.contains(&FieldsUser::ProfileBackground) { + if let Some(profile) = &user.profile { + if let Some(_background) = &profile.background { + // TODO: delete the background + } + } + } + + for field in fields { + user.remove(field); + } + } + + let mut partial: PartialUser = Default::default(); + + if let Some(avatar) = data.avatar { + partial.avatar = Some(File::use_avatar(db, &avatar, &user.id).await?); + user.avatar = partial.avatar.clone(); + } + + if let Some(status) = data.status { + let mut new_status = user.status.take().unwrap_or_default(); + if let Some(text) = status.text { + new_status.text = Some(text); + } + + if let Some(presence) = status.presence { + new_status.presence = Some(presence); + } + + partial.status = Some(new_status); + user.status = partial.status.clone(); + } + + if let Some(profile) = data.profile { + let mut new_profile = user.profile.take().unwrap_or_default(); + if let Some(content) = profile.content { + new_profile.content = Some(content); + } + + if let Some(background) = profile.background { + new_profile.background = Some(File::use_background(db, &background, &user.id).await?); + } + + partial.profile = Some(new_profile); + user.profile = partial.profile.clone(); + } + + db.update_user(&user.id, &partial, data.remove.unwrap_or_default()).await?; + Ok(Json(user)) }