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 log::*;
use steamguard::{QrApprover, QrApproverError};
use steamguard::{transport::WebApiTransport, QrApprover, QrApproverError};
use crate::AccountManager;
@ -42,7 +42,7 @@ impl AccountCommand for QrLoginCommand {
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) {
Ok(_) => {
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.");
info!("Adding authenticator...");
let mut linker = AccountLinker::new(tokens);
let mut linker = AccountLinker::new(WebApiTransport::default(), tokens);
let link: AccountLinkSuccess;
loop {
match linker.link() {
@ -130,7 +130,7 @@ impl ManifestCommand for SetupCommand {
}
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());

View file

@ -274,7 +274,7 @@ fn get_selected_accounts(
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 client = AuthenticationClient::new(WebApiTransport::default());
let mut refresher = TokenRefresher::new(client);
match refresher.refresh(account.steam_id, tokens) {
Ok(token) => {
@ -327,7 +327,7 @@ fn do_login_impl(
password: String,
account: Option<&SteamGuardAccount>,
) -> 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 confirmation_methods;

View file

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

View file

@ -109,7 +109,7 @@ impl SteamGuardAccount {
let Some(tokens) = &self.tokens else {
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();
req.set_revocation_code(
revocation_code

View file

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

View file

@ -5,21 +5,27 @@ use crate::{
protobufs::steammessages_auth_steamclient::CAuthentication_UpdateAuthSessionWithMobileConfirmation_Request,
steamapi::{AuthenticationClient, EResult},
token::{Tokens, TwoFactorSecret},
transport::WebApiTransport,
transport::Transport,
SteamGuardAccount,
};
/// QR code login approver
///
/// 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,
client: AuthenticationClient<WebApiTransport>,
client: AuthenticationClient<T>,
}
impl<'a> QrApprover<'a> {
pub fn new(tokens: &'a Tokens) -> Self {
let client = AuthenticationClient::new(WebApiTransport::new());
impl<'a, T> QrApprover<'a, T>
where
T: Transport,
{
pub fn new(transport: T, tokens: &'a Tokens) -> Self {
let client = AuthenticationClient::new(transport);
Self { tokens, client }
}

View file

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

View file

@ -21,7 +21,7 @@ lazy_static! {
///
/// Endpoint: `/ITwoFactorService/QueryTime/v0001`
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()?;
if resp.result != EResult::OK {
return Err(anyhow::anyhow!("QueryTime failed: {:?}", resp));

View file

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

View file

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