Refactor / fix login and register (#495)

Change login and register to only use one ChorusUser object, change the
api of related methods which were also somewhat ugly
This commit is contained in:
kozabrada123 2024-05-05 14:43:23 +02:00 committed by GitHub
parent aac31726ec
commit 03f1e7d983
4 changed files with 50 additions and 104 deletions

View File

@ -11,7 +11,7 @@ use crate::errors::ChorusResult;
use crate::gateway::Gateway;
use crate::instance::{ChorusUser, Instance};
use crate::ratelimiter::ChorusRequest;
use crate::types::{GatewayIdentifyPayload, LimitType, LoginResult, LoginSchema};
use crate::types::{GatewayIdentifyPayload, LimitType, LoginResult, LoginSchema, User};
impl Instance {
/// Logs into an existing account on the spacebar server.
@ -30,27 +30,22 @@ impl Instance {
// We do not have a user yet, and the UserRateLimits will not be affected by a login
// request (since login is an instance wide limit), which is why we are just cloning the
// instances' limits to pass them on as user_rate_limits later.
let mut shell =
let mut user =
ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await;
let login_result = chorus_request
.deserialize_response::<LoginResult>(&mut shell)
.deserialize_response::<LoginResult>(&mut user)
.await?;
let object = self.get_user(login_result.token.clone(), None).await?;
if self.limits_information.is_some() {
self.limits_information.as_mut().unwrap().ratelimits = shell.limits.clone().unwrap();
}
user.set_token(login_result.token);
user.settings = login_result.settings;
let object = User::get(&mut user, None).await?;
*user.object.write().unwrap() = object;
let mut identify = GatewayIdentifyPayload::common();
let gateway = Gateway::spawn(self.urls.wss.clone()).await.unwrap();
identify.token = login_result.token.clone();
gateway.send_identify(identify).await;
let user = ChorusUser::new(
Arc::new(RwLock::new(self.clone())),
login_result.token,
self.clone_limits_if_some(),
login_result.settings,
Arc::new(RwLock::new(object)),
gateway,
);
identify.token = user.token();
user.gateway.send_identify(identify).await;
Ok(user)
}
}

View File

@ -23,26 +23,19 @@ pub mod register;
impl Instance {
/// Logs into an existing account on the spacebar server, using only a token.
pub async fn login_with_token(&mut self, token: String) -> ChorusResult<ChorusUser> {
let object_result = self.get_user(token.clone(), None).await;
if let Err(e) = object_result {
return Result::Err(e);
}
let mut user =
ChorusUser::shell(Arc::new(RwLock::new(self.clone())), token).await;
let object = User::get(&mut user, None).await?;
let settings = User::get_settings(&mut user).await?;
*user.object.write().unwrap() = object;
*user.settings.write().unwrap() = settings;
let user_settings = User::get_settings(&token, &self.urls.api, &mut self.clone())
.await
.unwrap();
let mut identify = GatewayIdentifyPayload::common();
let gateway = Gateway::spawn(self.urls.wss.clone()).await.unwrap();
identify.token = token.clone();
gateway.send_identify(identify).await;
let user = ChorusUser::new(
Arc::new(RwLock::new(self.clone())),
token.clone(),
self.clone_limits_if_some(),
Arc::new(RwLock::new(user_settings)),
Arc::new(RwLock::new(object_result.unwrap())),
gateway,
);
identify.token = user.token();
user.gateway.send_identify(identify).await;
Ok(user)
}
}

View File

@ -8,7 +8,7 @@ use reqwest::Client;
use serde_json::to_string;
use crate::gateway::{Gateway, GatewayHandle};
use crate::types::GatewayIdentifyPayload;
use crate::types::{GatewayIdentifyPayload, User};
use crate::{
errors::ChorusResult,
instance::{ChorusUser, Instance, Token},
@ -37,29 +37,25 @@ impl Instance {
// We do not have a user yet, and the UserRateLimits will not be affected by a login
// request (since register is an instance wide limit), which is why we are just cloning
// the instances' limits to pass them on as user_rate_limits later.
let mut shell =
let mut user =
ChorusUser::shell(Arc::new(RwLock::new(self.clone())), "None".to_string()).await;
let token = chorus_request
.deserialize_response::<Token>(&mut shell)
.deserialize_response::<Token>(&mut user)
.await?
.token;
if self.limits_information.is_some() {
self.limits_information.as_mut().unwrap().ratelimits = shell.limits.unwrap();
}
let user_object = self.get_user(token.clone(), None).await.unwrap();
let settings = ChorusUser::get_settings(&token, &self.urls.api.clone(), self).await?;
user.set_token(token);
let object = User::get(&mut user, None).await?;
let settings = User::get_settings(&mut user).await?;
*user.object.write().unwrap() = object;
*user.settings.write().unwrap() = settings;
let mut identify = GatewayIdentifyPayload::common();
let gateway: GatewayHandle = Gateway::spawn(self.urls.wss.clone()).await.unwrap();
identify.token = token.clone();
gateway.send_identify(identify).await;
let user = ChorusUser::new(
Arc::new(RwLock::new(self.clone())),
token.clone(),
self.clone_limits_if_some(),
Arc::new(RwLock::new(settings)),
Arc::new(RwLock::new(user_object)),
gateway,
);
identify.token = user.token();
user.gateway.send_identify(identify).await;
Ok(user)
}
}

View File

@ -30,13 +30,9 @@ impl ChorusUser {
/// Gets the user's settings.
///
/// # Notes
/// This functions is a wrapper around [`User::get_settings`].
pub async fn get_settings(
token: &String,
url_api: &String,
instance: &mut Instance,
) -> ChorusResult<UserSettings> {
User::get_settings(token, url_api, instance).await
/// This function is a wrapper around [`User::get_settings`].
pub async fn get_settings(&mut self) -> ChorusResult<UserSettings> {
User::get_settings(self).await
}
/// Modifies the current user's representation. (See [`User`])
@ -118,56 +114,22 @@ impl User {
///
/// # Reference
/// See <https://luna.gitlab.io/discord-unofficial-docs/docs/user_settings.html#get-usersmesettings>
pub async fn get_settings(
token: &String,
url_api: &String,
instance: &mut Instance,
) -> ChorusResult<UserSettings> {
pub async fn get_settings(user: &mut ChorusUser) -> ChorusResult<UserSettings> {
let url_api = user.belongs_to.read().unwrap().urls.api.clone();
let request: reqwest::RequestBuilder = Client::new()
.get(format!("{}/users/@me/settings", url_api))
.header("Authorization", token);
let mut user =
ChorusUser::shell(Arc::new(RwLock::new(instance.clone())), token.clone()).await;
.header("Authorization", user.token());
let chorus_request = ChorusRequest {
request,
limit_type: LimitType::Global,
};
let result = match chorus_request.send_request(&mut user).await {
Ok(result) => Ok(serde_json::from_str(&result.text().await.unwrap()).unwrap()),
match chorus_request.send_request(user).await {
Ok(result) => {
let result_text = result.text().await.unwrap();
Ok(serde_json::from_str(&result_text).unwrap())
}
Err(e) => Err(e),
};
if instance.limits_information.is_some() {
instance.limits_information.as_mut().unwrap().ratelimits = user
.belongs_to
.read()
.unwrap()
.clone_limits_if_some()
.unwrap();
}
result
}
}
impl Instance {
/// Gets a user by id, or if the id is None, gets the current user.
///
/// # Notes
/// This function is a wrapper around [`User::get`].
///
/// # Reference
/// See <https://discord-userdoccers.vercel.app/resources/user#get-user> and
/// <https://discord-userdoccers.vercel.app/resources/user#get-current-user>
pub async fn get_user(&mut self, token: String, id: Option<&String>) -> ChorusResult<User> {
let mut user = ChorusUser::shell(Arc::new(RwLock::new(self.clone())), token).await;
let result = User::get(&mut user, id).await;
if self.limits_information.is_some() {
self.limits_information.as_mut().unwrap().ratelimits = user
.belongs_to
.read()
.unwrap()
.clone_limits_if_some()
.unwrap();
}
result
}
}