diff options
Diffstat (limited to 'ozone/src/auth.rs')
| -rw-r--r-- | ozone/src/auth.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/ozone/src/auth.rs b/ozone/src/auth.rs index ca06e93..9b934cd 100644 --- a/ozone/src/auth.rs +++ b/ozone/src/auth.rs @@ -15,6 +15,7 @@ pub use types::*; use crate::auth::error::{AuthError, AuthErrorKind}; use self::msa::{XSTS_RP_MINECRAFT_SERVICES, XSTS_RP_XBOX_LIVE}; use crate::util; +use crate::util::progress::{Step, StepProgress}; impl Token { fn is_expired(&self, now: DateTime<Utc>) -> bool { @@ -72,7 +73,7 @@ impl MsaAccount { // logs into xbox live using a refresh token // (panics if no refresh token present) - async fn xbl_login_refresh(&mut self, client: &reqwest::Client) -> Result<(), AuthError> { + async fn xbl_login_refresh(&mut self, client: &reqwest::Client, xbl_login: Step<'_, '_>) -> Result<(), AuthError> { debug!("Using refresh token for XBL login"); let oauth_client = create_oauth_client!(self.is_azure_client_id, self.client_id.clone()); let refresh_token = self.refresh_token.as_ref().expect("refresh_access_token called with no refresh token"); @@ -80,7 +81,6 @@ impl MsaAccount { let tokenres: BasicTokenResponse = oauth_client .exchange_refresh_token(refresh_token) .add_scopes(self.scopes_iter()) - .add_extra_param("response_type", "device_code") .request_async(client) .await.map_err(|e| match e { RequestTokenError::ServerResponse(res) @@ -91,6 +91,7 @@ impl MsaAccount { self.refresh_token = tokenres.refresh_token().cloned(); + xbl_login.make_current(); self.xbl_login(client, tokenres.access_token()).await } @@ -124,7 +125,7 @@ impl MsaAccount { // - check if the XBL token is valid/not expired // - if it is expired, try to use refresh token to get a new one // - get rid of auth token if yeah - async fn ensure_xbl(&mut self, client: &reqwest::Client, now: DateTime<Utc>) -> Result<(), AuthError> { + async fn ensure_xbl<'p>(&mut self, client: &reqwest::Client, now: DateTime<Utc>, xbl_refresh_step: Step<'p, '_>, xbl_login_step: Step<'p, '_>) -> Result<(), AuthError> { if self.xbl_token.as_ref().is_some_and(|tok| !tok.is_expired(now)) { debug!("XBL token valid. Using it."); return Ok(()) @@ -135,7 +136,8 @@ impl MsaAccount { } debug!("XBL token expired. Trying to refresh it."); - self.xbl_login_refresh(client).await?; + xbl_refresh_step.make_current(); + self.xbl_login_refresh(client, xbl_login_step).await?; self.mc_token = None; @@ -146,12 +148,13 @@ impl MsaAccount { // - if the minecraft services token invalid/expired/missing, do the following // - get minecraftservices xsts token // - use minecraftservices to get mojang token with that xsts token - async fn ensure_mc_token(&mut self, client: &reqwest::Client, now: DateTime<Utc>) -> Result<(), AuthError> { + async fn ensure_mc_token<'p>(&mut self, client: &reqwest::Client, now: DateTime<Utc>, xsts_step: Step<'p, '_>, login_step: Step<'p, '_>) -> Result<(), AuthError> { if self.mc_token.as_ref().is_some_and(|tok| !tok.is_expired(now)) { debug!("Mojang token valid. Using it."); return Ok(()) } + xsts_step.make_current(); debug!("Mojang token has expired. Must log in again."); let xbl_token = self.xbl_token.as_ref().expect("ensure_mc_token requires xbl token").value.as_str(); let (user_hash, mc_xsts_tok) = match msa::xsts_request(client, xbl_token, XSTS_RP_MINECRAFT_SERVICES).await? { @@ -163,6 +166,7 @@ impl MsaAccount { msa::XSTSAuthResponse::Error(e) => return Err(e.into()) }; + login_step.make_current(); debug!("Got MinecraftServices XSTS, logging in."); self.mc_token = Some(mcservices::login_with_xbox(client, mc_xsts_tok.as_str(), user_hash.as_str()).await?); @@ -190,18 +194,23 @@ impl MsaAccount { Ok(()) } - async fn load_profile(&mut self, client: &reqwest::Client) -> Result<(), AuthError> { + async fn load_profile(&mut self, client: &reqwest::Client, steps: [Step<'_, '_>; 4]) -> Result<(), AuthError> { + steps[0].make_current(); self.load_xbox_info(client).await?; let mc_token = self.mc_token.as_ref().expect("minecraft token missing").value.as_str(); + steps[1].make_current(); debug!("Checking if you own the game..."); if !mcservices::owns_the_game(client, mc_token).await? { return Err(AuthErrorKind::NotEntitled.into()); } debug!("Getting your profile info..."); + steps[2].make_current(); let player_info = mcservices::get_player_info(client, mc_token).await?; + + steps[3].make_current(); let player_profile = mcservices::get_player_profile(client, player_info.id).await .map_err(|e| AuthError::internal_msg_src("looking up profile", e))?; @@ -211,14 +220,28 @@ impl MsaAccount { Ok(()) } - pub async fn log_in_silent(&mut self, client: &reqwest::Client) -> Result<(), AuthError> { + pub async fn log_in_silent(&mut self, client: &reqwest::Client, progress: &dyn util::progress::ProgressIndication) -> Result<(), AuthError> { + let steps = StepProgress::from(progress); + let step_login = steps.step("Attempt non-interactive login"); + let step_xbl_refresh = steps.step("Refresh Xbox Live token"); + let step_xbl_login = steps.step("Log into Xbox Live"); + let step_mc_xsts = steps.step("Request Minecraft XSTS token"); + let step_mcs_login = steps.step("Log into Minecraft"); + let step_xbl_profile = steps.step("Retrieve your Xbox profile"); + let step_mc_entitlement = steps.step("Check if you own Minecraft"); + let step_mc_profile_1 = steps.step("Look up your Minecraft profile (1)"); + let step_mc_profile_2 = steps.step("Look up your Minecraft profile (2)"); + steps.update_max(); + + step_login.make_current(); + // see it's kind of funny that I call this variable "now" despite the fact that it's // unconditionally 12 hours in the future - figboot let now = Utc::now() + TimeDelta::hours(12); - self.ensure_xbl(client, now).await?; - self.ensure_mc_token(client, now).await?; - self.load_profile(client).await?; + self.ensure_xbl(client, now, step_xbl_refresh, step_xbl_login).await?; + self.ensure_mc_token(client, now, step_mc_xsts, step_mcs_login).await?; + self.load_profile(client, [step_xbl_profile, step_mc_entitlement, step_mc_profile_1, step_mc_profile_2]).await?; Ok(()) } |
