automatically refresh access token to avoid prompting to log in (#221)
This commit is contained in:
parent
64697b6808
commit
bff16bd341
4 changed files with 66 additions and 3 deletions
27
src/main.rs
27
src/main.rs
|
@ -6,11 +6,13 @@ use std::{
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use steamguard::protobufs::steammessages_auth_steamclient::{
|
use steamguard::{
|
||||||
EAuthSessionGuardType, EAuthTokenPlatformType,
|
protobufs::steammessages_auth_steamclient::{EAuthSessionGuardType, EAuthTokenPlatformType},
|
||||||
|
refresher::TokenRefresher,
|
||||||
|
transport::WebApiTransport,
|
||||||
};
|
};
|
||||||
use steamguard::token::Tokens;
|
|
||||||
use steamguard::{steamapi, DeviceDetails, LoginError, SteamGuardAccount, UserLogin};
|
use steamguard::{steamapi, DeviceDetails, LoginError, SteamGuardAccount, UserLogin};
|
||||||
|
use steamguard::{steamapi::AuthenticationClient, token::Tokens};
|
||||||
|
|
||||||
use crate::accountmanager::migrate::load_and_migrate;
|
use crate::accountmanager::migrate::load_and_migrate;
|
||||||
pub use crate::accountmanager::{AccountManager, ManifestAccountLoadError, ManifestLoadError};
|
pub use crate::accountmanager::{AccountManager, ManifestAccountLoadError, ManifestLoadError};
|
||||||
|
@ -219,6 +221,25 @@ fn get_selected_accounts(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_login(account: &mut SteamGuardAccount) -> anyhow::Result<()> {
|
fn do_login(account: &mut SteamGuardAccount) -> anyhow::Result<()> {
|
||||||
|
if let Some(tokens) = account.tokens.as_mut() {
|
||||||
|
info!("Refreshing access token...");
|
||||||
|
let client = AuthenticationClient::new(WebApiTransport::new());
|
||||||
|
let mut refresher = TokenRefresher::new(client);
|
||||||
|
match refresher.refresh(account.steam_id, tokens) {
|
||||||
|
Ok(token) => {
|
||||||
|
info!("Successfully refreshed access token, no need to prompt to log in.");
|
||||||
|
tokens.set_access_token(token);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
warn!(
|
||||||
|
"Failed to refresh access token, prompting for login: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !account.account_name.is_empty() {
|
if !account.account_name.is_empty() {
|
||||||
info!("Username: {}", account.account_name);
|
info!("Username: {}", account.account_name);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub mod accountlinker;
|
||||||
mod api_responses;
|
mod api_responses;
|
||||||
mod confirmation;
|
mod confirmation;
|
||||||
pub mod protobufs;
|
pub mod protobufs;
|
||||||
|
pub mod refresher;
|
||||||
mod secret_string;
|
mod secret_string;
|
||||||
pub mod steamapi;
|
pub mod steamapi;
|
||||||
pub mod token;
|
pub mod token;
|
||||||
|
|
37
steamguard/src/refresher.rs
Normal file
37
steamguard/src/refresher.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use crate::{
|
||||||
|
protobufs::steammessages_auth_steamclient::CAuthentication_AccessToken_GenerateForApp_Request,
|
||||||
|
steamapi::{AuthenticationClient, EResult},
|
||||||
|
token::{Jwt, Tokens},
|
||||||
|
transport::WebApiTransport,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TokenRefresher {
|
||||||
|
client: AuthenticationClient<WebApiTransport>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TokenRefresher {
|
||||||
|
pub fn new(client: AuthenticationClient<WebApiTransport>) -> Self {
|
||||||
|
Self { client }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh(&mut self, steam_id: u64, tokens: &Tokens) -> Result<Jwt, anyhow::Error> {
|
||||||
|
let mut req = CAuthentication_AccessToken_GenerateForApp_Request::new();
|
||||||
|
req.set_steamid(steam_id);
|
||||||
|
req.set_refresh_token(tokens.refresh_token().expose_secret().to_owned());
|
||||||
|
|
||||||
|
let resp = self
|
||||||
|
.client
|
||||||
|
.generate_access_token(req, tokens.access_token())?;
|
||||||
|
|
||||||
|
if resp.result != EResult::OK {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Failed to refresh access token: {:?}",
|
||||||
|
resp.result
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut resp = resp.into_response_data();
|
||||||
|
|
||||||
|
Ok(resp.take_access_token().into())
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,6 +102,10 @@ impl Tokens {
|
||||||
&self.access_token
|
&self.access_token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_access_token(&mut self, token: Jwt) {
|
||||||
|
self.access_token = token;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn refresh_token(&self) -> &Jwt {
|
pub fn refresh_token(&self) -> &Jwt {
|
||||||
&self.refresh_token
|
&self.refresh_token
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue