refactor to make adding proxy support easier later (#263)

This commit is contained in:
Carson McManus 2023-07-02 07:17:09 -04:00 committed by GitHub
parent 55a8bee695
commit 3146d4824c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 86 additions and 57 deletions

View file

@ -1,7 +1,7 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use log::*; use log::*;
use steamguard::{QrApprover, QrApproverError}; use steamguard::{transport::WebApiTransport, QrApprover, QrApproverError};
use crate::AccountManager; use crate::AccountManager;
@ -42,7 +42,7 @@ impl AccountCommand for QrLoginCommand {
return Err(anyhow!("No tokens found for {}", account.account_name)); return Err(anyhow!("No tokens found for {}", account.account_name));
}; };
let mut approver = QrApprover::new(tokens); let mut approver = QrApprover::new(WebApiTransport::default(), tokens);
match approver.approve(&account, &self.url) { match approver.approve(&account, &self.url) {
Ok(_) => { Ok(_) => {
info!("Login approved."); info!("Login approved.");

View file

@ -31,7 +31,7 @@ impl ManifestCommand for SetupCommand {
crate::do_login_raw(username).expect("Failed to log in. Account has not been linked."); crate::do_login_raw(username).expect("Failed to log in. Account has not been linked.");
info!("Adding authenticator..."); info!("Adding authenticator...");
let mut linker = AccountLinker::new(tokens); let mut linker = AccountLinker::new(WebApiTransport::default(), tokens);
let link: AccountLinkSuccess; let link: AccountLinkSuccess;
loop { loop {
match linker.link() { match linker.link() {
@ -130,7 +130,7 @@ impl ManifestCommand for SetupCommand {
} }
pub fn do_add_phone_number(tokens: &Tokens) -> anyhow::Result<()> { pub fn do_add_phone_number(tokens: &Tokens) -> anyhow::Result<()> {
let client = PhoneClient::new(WebApiTransport::new()); let client = PhoneClient::new(WebApiTransport::default());
let linker = PhoneLinker::new(client, tokens.clone()); let linker = PhoneLinker::new(client, tokens.clone());

View file

@ -274,7 +274,7 @@ 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() { if let Some(tokens) = account.tokens.as_mut() {
info!("Refreshing access token..."); info!("Refreshing access token...");
let client = AuthenticationClient::new(WebApiTransport::new()); let client = AuthenticationClient::new(WebApiTransport::default());
let mut refresher = TokenRefresher::new(client); let mut refresher = TokenRefresher::new(client);
match refresher.refresh(account.steam_id, tokens) { match refresher.refresh(account.steam_id, tokens) {
Ok(token) => { Ok(token) => {
@ -327,7 +327,7 @@ fn do_login_impl(
password: String, password: String,
account: Option<&SteamGuardAccount>, account: Option<&SteamGuardAccount>,
) -> anyhow::Result<Tokens> { ) -> anyhow::Result<Tokens> {
let mut login = UserLogin::new(build_device_details()); let mut login = UserLogin::new(WebApiTransport::default(), build_device_details());
let mut password = password; let mut password = password;
let confirmation_methods; let confirmation_methods;

View file

@ -3,28 +3,34 @@ use crate::protobufs::service_twofactor::{
}; };
use crate::steamapi::twofactor::TwoFactorClient; use crate::steamapi::twofactor::TwoFactorClient;
use crate::token::TwoFactorSecret; use crate::token::TwoFactorSecret;
use crate::transport::WebApiTransport; use crate::transport::Transport;
use crate::{steamapi::EResult, token::Tokens, SteamGuardAccount}; use crate::{steamapi::EResult, token::Tokens, SteamGuardAccount};
use log::*; use log::*;
use thiserror::Error; use thiserror::Error;
#[derive(Debug)] #[derive(Debug)]
pub struct AccountLinker { pub struct AccountLinker<T>
where
T: Transport,
{
device_id: String, device_id: String,
pub account: Option<SteamGuardAccount>, pub account: Option<SteamGuardAccount>,
pub finalized: bool, pub finalized: bool,
tokens: Tokens, tokens: Tokens,
client: TwoFactorClient<WebApiTransport>, client: TwoFactorClient<T>,
} }
impl AccountLinker { impl<T> AccountLinker<T>
pub fn new(tokens: Tokens) -> AccountLinker { where
T: Transport,
{
pub fn new(transport: T, tokens: Tokens) -> Self {
Self { Self {
device_id: generate_device_id(), device_id: generate_device_id(),
account: None, account: None,
finalized: false, finalized: false,
tokens, tokens,
client: TwoFactorClient::new(WebApiTransport::new()), client: TwoFactorClient::new(transport),
} }
} }

View file

@ -109,7 +109,7 @@ impl SteamGuardAccount {
let Some(tokens) = &self.tokens else { let Some(tokens) = &self.tokens else {
return Err(RemoveAuthenticatorError::TransportError(TransportError::Unauthorized)); return Err(RemoveAuthenticatorError::TransportError(TransportError::Unauthorized));
}; };
let mut client = TwoFactorClient::new(WebApiTransport::new()); let mut client = TwoFactorClient::new(WebApiTransport::default());
let mut req = CTwoFactor_RemoveAuthenticator_Request::new(); let mut req = CTwoFactor_RemoveAuthenticator_Request::new();
req.set_revocation_code( req.set_revocation_code(
revocation_code revocation_code

View file

@ -1,20 +1,25 @@
use crate::protobufs::service_phone::*; use crate::protobufs::service_phone::*;
use crate::transport::TransportError; use crate::transport::{Transport, TransportError};
use crate::{ use crate::{
steamapi::{EResult, PhoneClient}, steamapi::{EResult, PhoneClient},
token::Tokens, token::Tokens,
transport::WebApiTransport,
}; };
pub use phonenumber::PhoneNumber; pub use phonenumber::PhoneNumber;
pub struct PhoneLinker { pub struct PhoneLinker<T>
client: PhoneClient<WebApiTransport>, where
T: Transport,
{
client: PhoneClient<T>,
tokens: Tokens, tokens: Tokens,
} }
impl PhoneLinker { impl<T> PhoneLinker<T>
pub fn new(client: PhoneClient<WebApiTransport>, tokens: Tokens) -> Self { where
T: Transport,
{
pub fn new(client: PhoneClient<T>, tokens: Tokens) -> Self {
Self { client, tokens } Self { client, tokens }
} }

View file

@ -5,21 +5,27 @@ use crate::{
protobufs::steammessages_auth_steamclient::CAuthentication_UpdateAuthSessionWithMobileConfirmation_Request, protobufs::steammessages_auth_steamclient::CAuthentication_UpdateAuthSessionWithMobileConfirmation_Request,
steamapi::{AuthenticationClient, EResult}, steamapi::{AuthenticationClient, EResult},
token::{Tokens, TwoFactorSecret}, token::{Tokens, TwoFactorSecret},
transport::WebApiTransport, transport::Transport,
SteamGuardAccount, SteamGuardAccount,
}; };
/// QR code login approver /// QR code login approver
/// ///
/// This can be used to approve a login request from another device that is displaying a QR code. /// This can be used to approve a login request from another device that is displaying a QR code.
pub struct QrApprover<'a> { pub struct QrApprover<'a, T>
where
T: Transport,
{
tokens: &'a Tokens, tokens: &'a Tokens,
client: AuthenticationClient<WebApiTransport>, client: AuthenticationClient<T>,
} }
impl<'a> QrApprover<'a> { impl<'a, T> QrApprover<'a, T>
pub fn new(tokens: &'a Tokens) -> Self { where
let client = AuthenticationClient::new(WebApiTransport::new()); T: Transport,
{
pub fn new(transport: T, tokens: &'a Tokens) -> Self {
let client = AuthenticationClient::new(transport);
Self { tokens, client } Self { tokens, client }
} }

View file

@ -2,15 +2,21 @@ use crate::{
protobufs::steammessages_auth_steamclient::CAuthentication_AccessToken_GenerateForApp_Request, protobufs::steammessages_auth_steamclient::CAuthentication_AccessToken_GenerateForApp_Request,
steamapi::{AuthenticationClient, EResult}, steamapi::{AuthenticationClient, EResult},
token::{Jwt, Tokens}, token::{Jwt, Tokens},
transport::WebApiTransport, transport::Transport,
}; };
pub struct TokenRefresher { pub struct TokenRefresher<T>
client: AuthenticationClient<WebApiTransport>, where
T: Transport,
{
client: AuthenticationClient<T>,
} }
impl TokenRefresher { impl<T> TokenRefresher<T>
pub fn new(client: AuthenticationClient<WebApiTransport>) -> Self { where
T: Transport,
{
pub fn new(client: AuthenticationClient<T>) -> Self {
Self { client } Self { client }
} }

View file

@ -21,7 +21,7 @@ lazy_static! {
/// ///
/// Endpoint: `/ITwoFactorService/QueryTime/v0001` /// Endpoint: `/ITwoFactorService/QueryTime/v0001`
pub fn get_server_time() -> anyhow::Result<CTwoFactor_Time_Response> { pub fn get_server_time() -> anyhow::Result<CTwoFactor_Time_Response> {
let mut client = TwoFactorClient::new(WebApiTransport::new()); let mut client = TwoFactorClient::new(WebApiTransport::default());
let resp = client.query_time()?; let resp = client.query_time()?;
if resp.result != EResult::OK { if resp.result != EResult::OK {
return Err(anyhow::anyhow!("QueryTime failed: {:?}", resp)); return Err(anyhow::anyhow!("QueryTime failed: {:?}", resp));

View file

@ -17,21 +17,24 @@ pub struct WebApiTransport {
impl Default for WebApiTransport { impl Default for WebApiTransport {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new(reqwest::blocking::Client::new())
} }
} }
impl WebApiTransport { impl WebApiTransport {
pub fn new() -> WebApiTransport { pub fn new(client: reqwest::blocking::Client) -> Self {
Self { Self { client }
client: reqwest::blocking::Client::new(),
// client: reqwest::blocking::Client::builder()
// .danger_accept_invalid_certs(true)
// .proxy(reqwest::Proxy::all("http://localhost:8080").unwrap())
// .build()
// .unwrap(),
}
} }
// pub fn new_with_proxy(proxy: &str) -> Self {
// Self {
// client: reqwest::blocking::Client::builder()
// // .danger_accept_invalid_certs(true)
// .proxy(reqwest::Proxy::all(proxy).unwrap())
// .build()
// .unwrap(),
// }
// }
} }
impl Transport for WebApiTransport { impl Transport for WebApiTransport {

View file

@ -6,20 +6,17 @@ use crate::protobufs::steammessages_auth_steamclient::{
CAuthentication_PollAuthSessionStatus_Request, CAuthentication_PollAuthSessionStatus_Response, CAuthentication_PollAuthSessionStatus_Request, CAuthentication_PollAuthSessionStatus_Response,
EAuthSessionGuardType, EAuthSessionGuardType,
}; };
use crate::protobufs::steammessages_auth_steamclient::{
CAuthentication_BeginAuthSessionViaCredentials_Response,
CAuthentication_BeginAuthSessionViaQR_Request, CAuthentication_BeginAuthSessionViaQR_Response,
CAuthentication_GetPasswordRSAPublicKey_Response,
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Request,
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Response, EAuthTokenPlatformType,
};
use crate::steamapi::authentication::AuthenticationClient; use crate::steamapi::authentication::AuthenticationClient;
use crate::steamapi::EResult; use crate::steamapi::EResult;
use crate::token::Tokens; use crate::token::Tokens;
use crate::{ use crate::transport::Transport;
protobufs::steammessages_auth_steamclient::{
CAuthentication_BeginAuthSessionViaCredentials_Response,
CAuthentication_BeginAuthSessionViaQR_Request,
CAuthentication_BeginAuthSessionViaQR_Response,
CAuthentication_GetPasswordRSAPublicKey_Response,
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Request,
CAuthentication_UpdateAuthSessionWithSteamGuardCode_Response, EAuthTokenPlatformType,
},
transport::WebApiTransport,
};
use log::*; use log::*;
use rsa::{PublicKey, RsaPublicKey}; use rsa::{PublicKey, RsaPublicKey};
use std::time::Duration; use std::time::Duration;
@ -82,17 +79,23 @@ impl BeginQrLoginResponse {
/// Handles the user login flow. /// Handles the user login flow.
#[derive(Debug)] #[derive(Debug)]
pub struct UserLogin { pub struct UserLogin<T>
client: AuthenticationClient<WebApiTransport>, where
T: Transport,
{
client: AuthenticationClient<T>,
device_details: DeviceDetails, device_details: DeviceDetails,
started_auth: Option<StartAuth>, started_auth: Option<StartAuth>,
} }
impl UserLogin { impl<T> UserLogin<T>
pub fn new(device_details: DeviceDetails) -> Self { where
T: Transport,
{
pub fn new(transport: T, device_details: DeviceDetails) -> Self {
Self { Self {
client: AuthenticationClient::new(WebApiTransport::new()), client: AuthenticationClient::new(transport),
device_details, device_details,
started_auth: None, started_auth: None,
} }