From 2dcee5cff0c1d9c6d9956b61f9c541599302405b Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 17:58:46 +0100 Subject: [PATCH 01/12] feat: add Request/Response and other necessary objects for MFA implementation --- src/types/entities/mfa_token.rs | 7 ++++ src/types/entities/mod.rs | 2 ++ src/types/schema/mfa.rs | 62 +++++++++++++++++++++++++++++++++ src/types/schema/mod.rs | 2 ++ 4 files changed, 73 insertions(+) create mode 100644 src/types/entities/mfa_token.rs create mode 100644 src/types/schema/mfa.rs diff --git a/src/types/entities/mfa_token.rs b/src/types/entities/mfa_token.rs new file mode 100644 index 0000000..1c2a3e8 --- /dev/null +++ b/src/types/entities/mfa_token.rs @@ -0,0 +1,7 @@ +use chrono::{DateTime, Utc}; + +#[derive(Debug, Clone)] +pub struct MfaToken { + pub token: String, + pub expires_at: DateTime, +} diff --git a/src/types/entities/mod.rs b/src/types/entities/mod.rs index 4227e24..cd343c8 100644 --- a/src/types/entities/mod.rs +++ b/src/types/entities/mod.rs @@ -26,6 +26,7 @@ pub use user::*; pub use user_settings::*; pub use voice_state::*; pub use webhook::*; +pub use mfa_token::*; use crate::types::Shared; #[cfg(feature = "client")] @@ -67,6 +68,7 @@ mod user; mod user_settings; mod voice_state; mod webhook; +mod mfa_token; #[cfg(feature = "client")] #[async_trait(?Send)] diff --git a/src/types/schema/mfa.rs b/src/types/schema/mfa.rs new file mode 100644 index 0000000..10709cf --- /dev/null +++ b/src/types/schema/mfa.rs @@ -0,0 +1,62 @@ +use std::fmt::Display; + +use serde::{Serialize, Deserialize}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(rename_all = "snake_case")] +pub struct MfaRequiredSchema { + pub message: String, + pub code: i32, + pub mfa: MfaVerificationSchema, +} + +impl Display for MfaRequiredSchema { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MfaRequired") + .field("message", &self.message) + .field("code", &self.code) + .field("mfa", &self.mfa) + .finish() + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(rename_all = "snake_case")] +pub struct MfaVerificationSchema { + pub ticket: String, + pub methods: Vec +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(rename_all = "snake_case")] +pub struct MfaMethod { + #[serde(rename = "type")] + pub kind: MfaType, + #[serde(skip_serializing_if = "Option::is_none")] + pub challenge: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub backup_codes_allowed: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +#[serde(rename_all = "snake_case")] +pub enum MfaType { + TOTP, + SMS, + Backup, + WebAuthn, + Password, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub struct MfaVerifySchema { + pub ticket: String, + pub mfa_type: MfaType, + pub data: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct MfaTokenSchema { + pub token: String, +} diff --git a/src/types/schema/mod.rs b/src/types/schema/mod.rs index ef3233d..b2cb80f 100644 --- a/src/types/schema/mod.rs +++ b/src/types/schema/mod.rs @@ -4,6 +4,7 @@ pub use apierror::*; pub use auth::*; +pub use mfa::*; pub use channel::*; pub use guild::*; pub use message::*; @@ -14,6 +15,7 @@ pub use invites::*; mod apierror; mod auth; +mod mfa; mod channel; mod guild; mod message; From c3eec16c29e519cca537ee9609ff150a9804ed79 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:02:10 +0100 Subject: [PATCH 02/12] refactor: remove old Response object involved in MFA implementation --- src/types/schema/auth.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/types/schema/auth.rs b/src/types/schema/auth.rs index 83c88dc..fd91a7a 100644 --- a/src/types/schema/auth.rs +++ b/src/types/schema/auth.rs @@ -35,12 +35,3 @@ pub struct LoginSchema { pub login_source: Option, pub gift_code_sku_id: Option, } - -#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -pub struct TotpSchema { - code: String, - ticket: String, - gift_code_sku_id: Option, - login_source: Option, -} From 538781502c413c4dfd65c7cd363d8349ea4577b9 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:03:04 +0100 Subject: [PATCH 03/12] feat: add MFARequired error to ChorusError --- src/errors.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 0d130dd..c922669 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -5,7 +5,7 @@ //! Contains all the errors that can be returned by the library. use custom_error::custom_error; -use crate::types::WebSocketEvent; +use crate::types::{MfaRequiredSchema, WebSocketEvent}; use chorus_macros::WebSocketEvent; custom_error! { @@ -46,7 +46,9 @@ custom_error! { /// Malformed or unexpected response. InvalidResponse{error: String} = "The response is malformed and cannot be processed. Error: {error}", /// Invalid, insufficient or too many arguments provided. - InvalidArguments{error: String} = "Invalid arguments were provided. Error: {error}" + InvalidArguments{error: String} = "Invalid arguments were provided. Error: {error}", + /// The request requires MFA verification + MfaRequired {error: MfaRequiredSchema} = "Mfa verification required to perform this action" } impl From for ChorusError { From 4920c91e52af99296d3889f302130cb42e43fb8d Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:27:37 +0100 Subject: [PATCH 04/12] refactor: wrap object field type with `Option` and change `shell()` method accordingly This change allows to exactly know when a ChorusUser is authenticated or not --- src/instance.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index d23a567..d9bd0a0 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -159,9 +159,10 @@ impl fmt::Display for Token { pub struct ChorusUser { pub belongs_to: Shared, pub token: String, + pub mfa_token: Option, pub limits: Option>, pub settings: Shared, - pub object: Shared, + pub object: Option>, pub gateway: GatewayHandle, } @@ -192,12 +193,13 @@ impl ChorusUser { token: String, limits: Option>, settings: Shared, - object: Shared, + object: Option>, gateway: GatewayHandle, ) -> ChorusUser { ChorusUser { belongs_to, token, + mfa_token: None, limits, settings, object, @@ -212,12 +214,12 @@ impl ChorusUser { /// first. pub(crate) async fn shell(instance: Shared, token: String) -> ChorusUser { let settings = Arc::new(RwLock::new(UserSettings::default())); - let object = Arc::new(RwLock::new(User::default())); let wss_url = instance.read().unwrap().urls.wss.clone(); // Dummy gateway object let gateway = Gateway::spawn(wss_url).await.unwrap(); ChorusUser { token, + mfa_token: None, belongs_to: instance.clone(), limits: instance .read() @@ -226,7 +228,7 @@ impl ChorusUser { .as_ref() .map(|info| info.ratelimits.clone()), settings, - object, + object: None, gateway, } } From 85a2878f9a60116ea0b1596f2b53cd42f0604110 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:28:23 +0100 Subject: [PATCH 05/12] feat: add `complete_mfa_challenge` method to ChorusUser --- src/instance.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/instance.rs b/src/instance.rs index d9bd0a0..d9b3047 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -8,16 +8,18 @@ use std::collections::HashMap; use std::fmt; use std::sync::{Arc, RwLock}; +use std::time::Duration; use reqwest::Client; use serde::{Deserialize, Serialize}; +use chrono::Utc; use crate::errors::ChorusResult; use crate::gateway::{Gateway, GatewayHandle}; use crate::ratelimiter::ChorusRequest; use crate::types::types::subconfigs::limits::rates::RateLimits; use crate::types::{ - GeneralConfiguration, Limit, LimitType, LimitsConfiguration, Shared, User, UserSettings, + GeneralConfiguration, Limit, LimitType, LimitsConfiguration, MfaTokenSchema, MfaVerifySchema, Shared, User, UserSettings, MfaToken }; use crate::UrlBundle; @@ -232,4 +234,35 @@ impl ChorusUser { gateway, } } + + /// Sends a request to complete an MFA challenge. + /// # Reference + /// See + /// + /// If successful, the MFA verification JWT returned is set on the current [ChorusUser] executing the + /// request. + /// + /// The JWT token expires after 5 minutes. + pub async fn complete_mfa_challenge(&mut self, mfa_verify_schema: MfaVerifySchema) -> ChorusResult<()> { + let endpoint_url = "/mfa/finish"; + let chorus_request = ChorusRequest { + request: Client::new() + .post(endpoint_url) + .json(&mfa_verify_schema), + limit_type: match self.object.is_some() { + true => LimitType::Global, + false => LimitType::Ip, + }, + }; + + let mfa_token_schema = chorus_request + .deserialize_response::(self).await?; + + self.mfa_token = Some(MfaToken { + token: mfa_token_schema.token, + expires_at: Utc::now() + Duration::from_secs(60 * 5), + }); + + Ok(()) + } } From 2c4e06926941865eb895d32dfa427481cd5caf0b Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:34:50 +0100 Subject: [PATCH 06/12] refactor: remove mfa_token argument from `ChorusRequest` `new` method --- src/ratelimiter.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index 5e69d95..bc0e8a2 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -35,13 +35,12 @@ impl ChorusRequest { /// * [`http::Method::DELETE`] /// * [`http::Method::PATCH`] /// * [`http::Method::HEAD`] - #[allow(unused_variables)] // TODO: Add mfa_token to request, once we figure out *how* to do so correctly + #[allow(unused_variables)] pub fn new( method: http::Method, url: &str, body: Option, audit_log_reason: Option<&str>, - mfa_token: Option<&str>, chorus_user: Option<&mut ChorusUser>, limit_type: LimitType, ) -> ChorusRequest { From a3aa4625f9b848b48800316345f469f0622bac97 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 18:37:33 +0100 Subject: [PATCH 07/12] feat: add handling for MFA Required response errors --- src/ratelimiter.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ratelimiter.rs b/src/ratelimiter.rs index bc0e8a2..ab56b24 100644 --- a/src/ratelimiter.rs +++ b/src/ratelimiter.rs @@ -14,7 +14,7 @@ use serde_json::from_str; use crate::{ errors::{ChorusError, ChorusResult}, instance::ChorusUser, - types::{types::subconfigs::limits::rates::RateLimits, Limit, LimitType, LimitsConfiguration}, + types::{types::subconfigs::limits::rates::RateLimits, Limit, LimitType, LimitsConfiguration, MfaRequiredSchema}, }; /// Chorus' request struct. This struct is used to send rate-limited requests to the Spacebar server. @@ -266,7 +266,14 @@ impl ChorusRequest { async fn interpret_error(response: reqwest::Response) -> ChorusError { match response.status().as_u16() { - 401..=403 | 407 => ChorusError::NoPermission, + 401 => { + let response = response.text().await.unwrap(); + match serde_json::from_str::(&response) { + Ok(response) => ChorusError::MfaRequired { error: response }, + Err(_) => ChorusError::NoPermission, + } + } + 402..=403 | 407 => ChorusError::NoPermission, 404 => ChorusError::NotFound { error: response.text().await.unwrap(), }, From 6ef33c01c758b3b7059f9d78cf9dd138d69a8aa4 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 19:08:38 +0100 Subject: [PATCH 08/12] refactor: change `User` object assignements according to changes done in `ChorusUser` --- src/api/auth/login.rs | 2 +- src/api/auth/mod.rs | 2 +- src/api/auth/register.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index 7c58e0e..57c03b7 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -40,7 +40,7 @@ impl Instance { user.settings = login_result.settings; let object = User::get(&mut user, None).await?; - *user.object.write().unwrap() = object; + user.object = Some(Arc::new(RwLock::new(object))); let mut identify = GatewayIdentifyPayload::common(); identify.token = user.token(); diff --git a/src/api/auth/mod.rs b/src/api/auth/mod.rs index 498080e..e8a859c 100644 --- a/src/api/auth/mod.rs +++ b/src/api/auth/mod.rs @@ -29,7 +29,7 @@ impl Instance { let object = User::get(&mut user, None).await?; let settings = User::get_settings(&mut user).await?; - *user.object.write().unwrap() = object; + user.object = Some(Arc::new(RwLock::new(object))); *user.settings.write().unwrap() = settings; let mut identify = GatewayIdentifyPayload::common(); diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index 6b94a4d..5582b0b 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -49,7 +49,7 @@ impl Instance { let object = User::get(&mut user, None).await?; let settings = User::get_settings(&mut user).await?; - *user.object.write().unwrap() = object; + user.object = Some(Arc::new(RwLock::new(object))); *user.settings.write().unwrap() = settings; let mut identify = GatewayIdentifyPayload::common(); From 8f995a9f63d9119a059aeeb17c05125734ba09d8 Mon Sep 17 00:00:00 2001 From: xystrive Date: Thu, 4 Jul 2024 19:09:28 +0100 Subject: [PATCH 09/12] refactor: change `ChorusUser` new method calls according to changes done --- src/api/channels/channels.rs | 6 ------ src/api/channels/messages.rs | 11 ----------- src/api/channels/permissions.rs | 1 - src/api/channels/reactions.rs | 6 ------ src/api/guilds/guilds.rs | 10 ---------- src/api/guilds/roles.rs | 1 - 6 files changed, 35 deletions(-) diff --git a/src/api/channels/channels.rs b/src/api/channels/channels.rs index 6c41576..7cb9ee3 100644 --- a/src/api/channels/channels.rs +++ b/src/api/channels/channels.rs @@ -30,7 +30,6 @@ impl Channel { ), None, None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -61,7 +60,6 @@ impl Channel { &url, None, audit_log_reason.as_deref(), - None, Some(user), LimitType::Channel(self.id), ); @@ -101,7 +99,6 @@ impl Channel { &url, Some(to_string(&modify_data).unwrap()), audit_log_reason.as_deref(), - None, Some(user), LimitType::Channel(channel_id), ); @@ -134,7 +131,6 @@ impl Channel { &url, None, None, - None, Some(user), Default::default(), ); @@ -196,7 +192,6 @@ impl Channel { &url, None, None, - None, Some(user), LimitType::Channel(self.id), ); @@ -225,7 +220,6 @@ impl Channel { &url, Some(to_string(&schema).unwrap()), None, - None, Some(user), LimitType::Guild(guild_id), ); diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index feabc37..af990c6 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -151,7 +151,6 @@ impl Message { .as_str(), None, None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -182,7 +181,6 @@ impl Message { .as_str(), None, audit_log_reason, - None, Some(user), LimitType::Channel(channel_id), ); @@ -209,7 +207,6 @@ impl Message { .as_str(), None, audit_log_reason, - None, Some(user), LimitType::Channel(channel_id), ); @@ -258,7 +255,6 @@ impl Message { .as_str(), Some(to_string(&schema).unwrap()), None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -292,7 +288,6 @@ impl Message { .as_str(), Some(to_string(&schema).unwrap()), None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -321,7 +316,6 @@ impl Message { .as_str(), None, None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -348,7 +342,6 @@ impl Message { &url, None, None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -382,7 +375,6 @@ impl Message { &url, Some(to_string(&schema).unwrap()), None, - None, Some(user), LimitType::Channel(channel_id), ); @@ -409,7 +401,6 @@ impl Message { &url, None, audit_log_reason.as_deref(), - None, Some(user), LimitType::Channel(channel_id), ); @@ -447,7 +438,6 @@ impl Message { .as_str(), Some(to_string(&messages).unwrap()), audit_log_reason.as_deref(), - None, Some(user), LimitType::Channel(channel_id), ); @@ -472,7 +462,6 @@ impl Message { .as_str(), None, None, - None, Some(user), LimitType::Channel(channel_id), ); diff --git a/src/api/channels/permissions.rs b/src/api/channels/permissions.rs index 03465b8..19492cd 100644 --- a/src/api/channels/permissions.rs +++ b/src/api/channels/permissions.rs @@ -83,7 +83,6 @@ impl types::Channel { &url, None, None, - None, Some(user), LimitType::Channel(channel_id), ); diff --git a/src/api/channels/reactions.rs b/src/api/channels/reactions.rs index b7c42e1..762cdb0 100644 --- a/src/api/channels/reactions.rs +++ b/src/api/channels/reactions.rs @@ -36,7 +36,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); @@ -65,7 +64,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); @@ -96,7 +94,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); @@ -130,7 +127,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); @@ -159,7 +155,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); @@ -196,7 +191,6 @@ impl ReactionMeta { &url, None, None, - None, Some(user), LimitType::Channel(self.channel_id), ); diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e2ff9ba..615600b 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -220,7 +220,6 @@ impl Guild { .as_str(), None, None, - None, Some(user), LimitType::Guild(guild_id), ); @@ -246,7 +245,6 @@ impl Guild { .as_str(), None, None, - None, Some(user), LimitType::Guild(guild_id), ); @@ -279,7 +277,6 @@ impl Guild { .as_str(), None, audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); @@ -309,7 +306,6 @@ impl Guild { .as_str(), Some(to_string(&schema).unwrap()), audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); @@ -336,7 +332,6 @@ impl Guild { .as_str(), Some(to_string(&schema).unwrap()), audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); @@ -362,7 +357,6 @@ impl Guild { .as_str(), Some(to_string(&schema).unwrap()), None, - None, Some(user), LimitType::Guild(guild_id), ); @@ -393,7 +387,6 @@ impl Guild { &url, None, None, - None, Some(user), LimitType::Guild(guild_id), ); @@ -426,7 +419,6 @@ impl Guild { &url, None, None, - None, Some(user), LimitType::Guild(guild_id), ); @@ -456,7 +448,6 @@ impl Guild { .as_str(), Some(to_string(&schema).unwrap()), audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); @@ -487,7 +478,6 @@ impl Guild { &url, None, audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); diff --git a/src/api/guilds/roles.rs b/src/api/guilds/roles.rs index 6100a48..7e76010 100644 --- a/src/api/guilds/roles.rs +++ b/src/api/guilds/roles.rs @@ -188,7 +188,6 @@ impl types::RoleObject { &url, None, audit_log_reason.as_deref(), - None, Some(user), LimitType::Guild(guild_id), ); From c3c506bc1b38488bcadf71f8f74bb8d38ab20bb9 Mon Sep 17 00:00:00 2001 From: xystrive Date: Fri, 5 Jul 2024 17:04:05 +0100 Subject: [PATCH 10/12] fix: typo in `ChorusError::MfaRequired` `Display` message --- src/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/errors.rs b/src/errors.rs index c922669..23df755 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -48,7 +48,7 @@ custom_error! { /// Invalid, insufficient or too many arguments provided. InvalidArguments{error: String} = "Invalid arguments were provided. Error: {error}", /// The request requires MFA verification - MfaRequired {error: MfaRequiredSchema} = "Mfa verification required to perform this action" + MfaRequired {error: MfaRequiredSchema} = "Mfa verification is required to perform this action" } impl From for ChorusError { From ee19cb762fbaa732f06c67cbec1f2f5dace1a80e Mon Sep 17 00:00:00 2001 From: xystrive Date: Fri, 5 Jul 2024 17:06:16 +0100 Subject: [PATCH 11/12] fix: concatenate `Instance`'s api url with endpoint --- src/instance.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/instance.rs b/src/instance.rs index d9b3047..67d7bd2 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -244,10 +244,11 @@ impl ChorusUser { /// /// The JWT token expires after 5 minutes. pub async fn complete_mfa_challenge(&mut self, mfa_verify_schema: MfaVerifySchema) -> ChorusResult<()> { - let endpoint_url = "/mfa/finish"; + let endpoint_url = self.belongs_to.read().unwrap().urls.api.clone() + "/mfa/finish"; let chorus_request = ChorusRequest { request: Client::new() .post(endpoint_url) + .header("Authorization", self.token()) .json(&mfa_verify_schema), limit_type: match self.object.is_some() { true => LimitType::Global, From 317dbe1ed1faed866ef9df296c2987291bec4899 Mon Sep 17 00:00:00 2001 From: xystrive Date: Fri, 5 Jul 2024 17:15:24 +0100 Subject: [PATCH 12/12] fix: according to changes made to `ChorusUser` object field 4920c91e52af99296d3889f302130cb42e43fb8d --- examples/login.rs | 2 +- tests/auth.rs | 6 ++++-- tests/channels.rs | 26 ++++++++++++++++++-------- tests/common/mod.rs | 1 + tests/guilds.rs | 7 +++++-- tests/members.rs | 3 ++- tests/messages.rs | 2 +- tests/relationships.rs | 25 +++++++++++++------------ 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/examples/login.rs b/examples/login.rs index e89d8d2..2449d6c 100644 --- a/examples/login.rs +++ b/examples/login.rs @@ -24,5 +24,5 @@ async fn main() { .await .expect("An error occurred during the login process"); dbg!(user.belongs_to); - dbg!(&user.object.read().unwrap().username); + dbg!(&user.object.unwrap().as_ref().read().unwrap().username); } diff --git a/tests/auth.rs b/tests/auth.rs index 705328a..c7da756 100644 --- a/tests/auth.rs +++ b/tests/auth.rs @@ -85,8 +85,10 @@ async fn test_login_with_token() { .await .unwrap(); assert_eq!( - bundle.user.object.read().unwrap().id, - other_user.object.read().unwrap().id + bundle.user.object.as_ref().unwrap() + .read().unwrap() + .id, + other_user.object.unwrap().read().unwrap().id ); assert_eq!(bundle.user.token, other_user.token); diff --git a/tests/channels.rs b/tests/channels.rs index e00744a..5127fd6 100644 --- a/tests/channels.rs +++ b/tests/channels.rs @@ -2,7 +2,11 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -use chorus::types::{self, Channel, GetChannelMessagesSchema, MessageSendSchema, PermissionFlags, PermissionOverwrite, PermissionOverwriteType, PrivateChannelCreateSchema, RelationshipType, Snowflake}; +use chorus::types::{ + self, Channel, GetChannelMessagesSchema, MessageSendSchema, PermissionFlags, + PermissionOverwrite, PermissionOverwriteType, PrivateChannelCreateSchema, RelationshipType, + Snowflake, +}; mod common; @@ -67,7 +71,7 @@ async fn modify_channel() { assert_eq!(modified_channel.name, Some(CHANNEL_NAME.to_string())); let permission_override = PermissionFlags::MANAGE_CHANNELS | PermissionFlags::MANAGE_MESSAGES; - let user_id: types::Snowflake = bundle.user.object.read().unwrap().id; + let user_id: types::Snowflake = bundle.user.object.as_ref().unwrap().read().unwrap().id; let permission_override = PermissionOverwrite { id: user_id, overwrite_type: PermissionOverwriteType::Member, @@ -155,7 +159,13 @@ async fn create_dm() { let other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { - recipients: Some(Vec::from([other_user.object.read().unwrap().id])), + recipients: Some(Vec::from([other_user + .object + .as_ref() + .unwrap() + .read() + .unwrap() + .id])), access_tokens: None, nicks: None, }; @@ -175,7 +185,7 @@ async fn create_dm() { .unwrap() .id .clone(), - other_user.object.read().unwrap().id + other_user.object.unwrap().read().unwrap().id ); assert_eq!( dm_channel @@ -188,7 +198,7 @@ async fn create_dm() { .unwrap() .id .clone(), - user.object.read().unwrap().id.clone() + user.object.as_ref().unwrap().read().unwrap().id.clone() ); common::teardown(bundle).await; } @@ -200,9 +210,9 @@ async fn remove_add_person_from_to_dm() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let mut third_user = bundle.create_user("integrationtestuser3").await; - let third_user_id = third_user.object.read().unwrap().id; - let other_user_id = other_user.object.read().unwrap().id; - let user_id = bundle.user.object.read().unwrap().id; + let third_user_id = third_user.object.as_ref().unwrap().read().unwrap().id; + let other_user_id = other_user.object.as_ref().unwrap().read().unwrap().id; + let user_id = bundle.user.object.as_ref().unwrap().read().unwrap().id; let user = &mut bundle.user; let private_channel_create_schema = PrivateChannelCreateSchema { recipients: Some(Vec::from([other_user_id, third_user_id])), diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 315db38..d0af796 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -47,6 +47,7 @@ impl TestBundle { ChorusUser { belongs_to: self.user.belongs_to.clone(), token: self.user.token.clone(), + mfa_token: None, limits: self.user.limits.clone(), settings: self.user.settings.clone(), object: self.user.object.clone(), diff --git a/tests/guilds.rs b/tests/guilds.rs index e3a73f5..85dd3ce 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -60,7 +60,8 @@ async fn guild_create_ban() { .await .unwrap(); other_user.accept_invite(&invite.code, None).await.unwrap(); - let other_user_id = other_user.object.read().unwrap().id; + let other_user_id = other_user.object.as_ref().unwrap() + .read().unwrap().id; Guild::create_ban( guild.id, other_user_id, @@ -112,7 +113,9 @@ async fn guild_remove_member() { .await .unwrap(); other_user.accept_invite(&invite.code, None).await.unwrap(); - let other_user_id = other_user.object.read().unwrap().id; + let other_user_id = other_user.object + .as_ref().unwrap() + .read().unwrap().id; Guild::remove_member(guild.id, other_user_id, None, &mut bundle.user) .await .unwrap(); diff --git a/tests/members.rs b/tests/members.rs index a66d25a..0fc45d4 100644 --- a/tests/members.rs +++ b/tests/members.rs @@ -16,7 +16,8 @@ async fn add_remove_role() -> ChorusResult<()> { let mut bundle = common::setup().await; let guild = bundle.guild.read().unwrap().id; let role = bundle.role.read().unwrap().id; - let member_id = bundle.user.object.read().unwrap().id; + let member_id = bundle.user.object.as_ref().unwrap() + .read().unwrap().id; GuildMember::add_role(&mut bundle.user, guild, member_id, role).await?; let member = GuildMember::get(&mut bundle.user, guild, member_id) .await diff --git a/tests/messages.rs b/tests/messages.rs index 3ca6e16..b1de770 100644 --- a/tests/messages.rs +++ b/tests/messages.rs @@ -106,7 +106,7 @@ async fn search_messages() { let _arg = Some(&vec_attach); let message = bundle.user.send_message(message, channel.id).await.unwrap(); let query = MessageSearchQuery { - author_id: Some(Vec::from([bundle.user.object.read().unwrap().id])), + author_id: Some(Vec::from([bundle.user.object.as_ref().unwrap().read().unwrap().id])), ..Default::default() }; let guild_id = bundle.guild.read().unwrap().id; diff --git a/tests/relationships.rs b/tests/relationships.rs index 2eea5b3..4cd1492 100644 --- a/tests/relationships.rs +++ b/tests/relationships.rs @@ -16,9 +16,10 @@ async fn test_get_mutual_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.read().unwrap().username.clone(); - let discriminator = user.object.read().unwrap().discriminator.clone(); - let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; + + let username = user.object.as_ref().unwrap().read().unwrap().username.clone(); + let discriminator = user.object.as_ref().unwrap().read().unwrap().discriminator.clone(); + let other_user_id: types::Snowflake = other_user.object.as_ref().unwrap().read().unwrap().id; let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -38,8 +39,8 @@ async fn test_get_relationships() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let username = user.object.read().unwrap().username.clone(); - let discriminator = user.object.read().unwrap().discriminator.clone(); + let username = user.object.as_ref().unwrap().read().unwrap().username.clone(); + let discriminator = user.object.as_ref().unwrap().read().unwrap().discriminator.clone(); let friend_request_schema = types::FriendRequestSendSchema { username, discriminator: Some(discriminator), @@ -51,7 +52,7 @@ async fn test_get_relationships() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.read().unwrap().id + other_user.object.unwrap().read().unwrap().id ); common::teardown(bundle).await } @@ -62,8 +63,8 @@ async fn test_modify_relationship_friends() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.read().unwrap().id; - let other_user_id: types::Snowflake = other_user.object.read().unwrap().id; + let user_id: types::Snowflake = user.object.as_ref().unwrap().read().unwrap().id; + let other_user_id: types::Snowflake = other_user.object.as_ref().unwrap().read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Friends) @@ -72,7 +73,7 @@ async fn test_modify_relationship_friends() { let relationships = user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - other_user.object.read().unwrap().id + other_user.object.as_ref().unwrap().read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -81,7 +82,7 @@ async fn test_modify_relationship_friends() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.read().unwrap().id + user.object.as_ref().unwrap().read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type, @@ -114,7 +115,7 @@ async fn test_modify_relationship_block() { let mut bundle = common::setup().await; let mut other_user = bundle.create_user("integrationtestuser2").await; let user = &mut bundle.user; - let user_id: types::Snowflake = user.object.read().unwrap().id; + let user_id: types::Snowflake = user.object.as_ref().unwrap().read().unwrap().id; other_user .modify_user_relationship(user_id, types::RelationshipType::Blocked) @@ -125,7 +126,7 @@ async fn test_modify_relationship_block() { let relationships = other_user.get_relationships().await.unwrap(); assert_eq!( relationships.get(0).unwrap().id, - user.object.read().unwrap().id + user.object.as_ref().unwrap().read().unwrap().id ); assert_eq!( relationships.get(0).unwrap().relationship_type,