From 44f27f7a0e468a40792d08280025db24ed21c8a5 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Mon, 15 May 2023 23:20:23 +0200 Subject: [PATCH 1/4] Start working on User::modify(). --- src/api/users/users.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 88a68ca..1320546 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -76,6 +76,23 @@ impl<'a> User<'a> { Err(e) => Err(e), } } + + pub async fn modify( + self, + username: Option<&str>, + avatar: Option<&str>, + bio: Option<&str>, + accent_color: Option, + banner: Option<&str>, + current_password: Option<&str>, + new_password: Option<&str>, + code: Option<&str>, + email: Option<&str>, + discriminator: Option, + ) { + let mut limits = self.limits; + let request = Client::new().patch(format!("{}/users/@me/", self.belongs_to.urls.get_api())); + } } impl Instance { From d17c0464806ee4f1bdb960bca4e93109cdcc77cf Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 16 May 2023 15:58:51 +0200 Subject: [PATCH 2/4] Add PasswordRequiredError --- src/errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/errors.rs b/src/errors.rs index d449559..f76b029 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -22,6 +22,7 @@ custom_error! { TokenExpired = "Token expired, invalid or not found.", NoPermission = "You do not have the permissions needed to perform this action.", NotFound{error: String} = "The provided resource hasn't been found: {}", + PasswordRequiredError = "You need to provide your current password to authenticate for this action.", } custom_error! { From 8e58f7a54dc3297f64e17b5db6a807cf1c76f73f Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 16 May 2023 15:59:06 +0200 Subject: [PATCH 3/4] Add UserModifySchema --- src/api/schemas.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/api/schemas.rs b/src/api/schemas.rs index 1fd0e76..e84abdf 100644 --- a/src/api/schemas.rs +++ b/src/api/schemas.rs @@ -299,6 +299,21 @@ pub struct GuildCreateSchema { pub rules_channel_id: Option, } +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub struct UserModifySchema { + pub username: Option, + pub avatar: Option, + pub bio: Option, + pub accent_color: Option, + pub banner: Option, + pub current_password: Option, + pub new_password: Option, + pub code: Option, + pub email: Option, + pub discriminator: Option, +} + // I know that some of these tests are... really really basic and unneccessary, but sometimes, I // just feel like writing tests, so there you go :) -@bitfl0wer #[cfg(test)] From 0c225716605010e44540fc0605306d71b6e8283a Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Tue, 16 May 2023 15:59:23 +0200 Subject: [PATCH 4/4] Implement modify(), untested as of now --- src/api/users/users.rs | 59 +++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/api/users/users.rs b/src/api/users/users.rs index 1320546..7d97734 100644 --- a/src/api/users/users.rs +++ b/src/api/users/users.rs @@ -1,13 +1,15 @@ use reqwest::Client; +use serde_json::{from_str, to_string}; use crate::{ api::{ limits::Limits, types::{User, UserObject}, - UserSettings, + UserModifySchema, UserSettings, }, errors::InstanceServerError, instance::Instance, + limit::LimitedRequester, }; impl<'a> User<'a> { @@ -77,21 +79,48 @@ impl<'a> User<'a> { } } + /// Modify the current user's `UserObject`. + /// + /// # Arguments + /// + /// * `modify_schema` - A `UserModifySchema` object containing the fields to modify. + /// + /// # Errors + /// + /// Returns an `InstanceServerError` if the request fails or if a password is required but not provided. pub async fn modify( - self, - username: Option<&str>, - avatar: Option<&str>, - bio: Option<&str>, - accent_color: Option, - banner: Option<&str>, - current_password: Option<&str>, - new_password: Option<&str>, - code: Option<&str>, - email: Option<&str>, - discriminator: Option, - ) { - let mut limits = self.limits; - let request = Client::new().patch(format!("{}/users/@me/", self.belongs_to.urls.get_api())); + &mut self, + modify_schema: UserModifySchema, + ) -> Result { + if modify_schema.new_password.is_some() + || modify_schema.email.is_some() + || modify_schema.code.is_some() + { + return Err(InstanceServerError::PasswordRequiredError); + } + let request = Client::new() + .patch(format!("{}/users/@me/", self.belongs_to.urls.get_api())) + .body(to_string(&modify_schema).unwrap()) + .bearer_auth(self.token()); + let result = match LimitedRequester::new() + .await + .send_request( + request, + crate::api::limits::LimitType::Global, + &mut self.belongs_to.limits, + &mut self.limits, + ) + .await + { + Ok(response) => response, + Err(e) => return Err(e), + }; + let user_updated: UserObject = from_str(&result.text().await.unwrap()).unwrap(); + let _ = std::mem::replace( + &mut self.object.as_mut().unwrap(), + &mut user_updated.clone(), + ); + Ok(user_updated) } }