refactor: make loading single account not borrow manifest mutably

This commit is contained in:
Carson McManus 2022-02-22 09:03:40 -05:00
parent 02014972b4
commit 10d97efe16
3 changed files with 72 additions and 17 deletions

View file

@ -94,23 +94,36 @@ impl Manifest {
self.passkey = passkey; self.passkey = passkey;
} }
/// Loads all accounts, registers them, and performs auto upgrades.
pub fn load_accounts(&mut self) -> anyhow::Result<(), ManifestAccountLoadError> { pub fn load_accounts(&mut self) -> anyhow::Result<(), ManifestAccountLoadError> {
let account_names: Vec<String> = self self.auto_upgrade()?;
.entries let mut accounts = vec![];
.iter() for entry in &self.entries {
.map(|entry| entry.account_name.clone()) let account = self.load_account_by_entry(&entry)?;
.collect(); accounts.push(account);
for account_name in account_names { }
self.load_account(&account_name)?; for account in accounts {
self.register_loaded_account(account);
} }
Ok(()) Ok(())
} }
/// Loads an account by account name.
/// Must call `register_loaded_account` after loading the account.
fn load_account( fn load_account(
&mut self, &self,
account_name: &String, account_name: &String,
) -> anyhow::Result<(), ManifestAccountLoadError> { ) -> anyhow::Result<Arc<Mutex<SteamGuardAccount>>, ManifestAccountLoadError> {
let mut entry = self.get_entry_mut(account_name)?.clone(); let entry = self.get_entry(account_name)?;
self.load_account_by_entry(&entry)
}
/// Loads an account from a manifest entry.
/// Must call `register_loaded_account` after loading the account.
fn load_account_by_entry(
&self,
entry: &ManifestEntry,
) -> anyhow::Result<Arc<Mutex<SteamGuardAccount>>, ManifestAccountLoadError> {
let path = Path::new(&self.folder).join(&entry.filename); let path = Path::new(&self.folder).join(&entry.filename);
debug!("loading account: {:?}", path); debug!("loading account: {:?}", path);
let file = File::open(path)?; let file = File::open(path)?;
@ -135,11 +148,14 @@ impl Manifest {
account = serde_json::from_reader(reader)?; account = serde_json::from_reader(reader)?;
} }
}; };
entry.account_name = account.account_name.clone(); let account = Arc::new(Mutex::new(account));
self.accounts Ok(account)
.insert(entry.account_name.clone(), Arc::new(Mutex::new(account))); }
*self.get_entry_mut(account_name)? = entry;
Ok(()) /// Register an account as loaded, so it can be operated on.
fn register_loaded_account(&mut self, account: Arc<Mutex<SteamGuardAccount>>) {
let account_name = account.lock().unwrap().account_name.clone();
self.accounts.insert(account_name, account);
} }
pub fn account_exists(&self, account_name: &String) -> bool { pub fn account_exists(&self, account_name: &String) -> bool {
@ -289,8 +305,27 @@ impl Manifest {
if account.is_ok() { if account.is_ok() {
return Ok(account.unwrap()); return Ok(account.unwrap());
} }
self.load_account(&account_name)?; let account = self.load_account(&account_name)?;
return Ok(self.get_account(account_name)?); self.register_loaded_account(account.clone());
return Ok(account);
}
/// Determine if any manifest entries are missing `account_name`.
fn is_missing_account_name(&self) -> bool {
self.entries.iter().any(|e| e.account_name.is_empty())
}
pub fn auto_upgrade(&mut self) -> anyhow::Result<(), ManifestAccountLoadError> {
debug!("Performing auto-upgrade...");
if self.is_missing_account_name() {
debug!("Adding missing account names");
for i in 0..self.entries.len() {
let account = self.load_account_by_entry(&self.entries[i].clone())?;
self.entries[i].account_name = account.lock().unwrap().account_name.clone();
}
}
Ok(())
} }
} }
@ -668,4 +703,22 @@ mod tests {
); );
Ok(()) Ok(())
} }
#[cfg(test)]
mod manifest_upgrades {
use super::*;
#[test]
fn test_missing_account_name() {
let path = Path::new("src/fixtures/maFiles/compat/missing-account-name/manifest.json");
assert!(path.is_file());
let mut manifest = Manifest::load(path).unwrap();
assert_eq!(manifest.entries.len(), 1);
assert_eq!(manifest.entries[0].account_name, "".to_string());
assert!(manifest.is_missing_account_name());
manifest.auto_upgrade().unwrap();
assert_eq!(manifest.entries[0].account_name, "example".to_string());
}
}
} }

View file

@ -0,0 +1 @@
{"shared_secret":"zvIayp3JPvtvX/QGHqsqKBk/44s=","serial_number":"kljasfhds","revocation_code":"R12345","uri":"otpauth://totp/Steam:example?secret=ASDF&issuer=Steam","server_time":1602522478,"account_name":"example","token_gid":"jkkjlhkhjgf","identity_secret":"kjsdlwowiqe=","secret_1":"sklduhfgsdlkjhf=","status":1,"device_id":"android:99d2ad0e-4bad-4247-b111-26393aae0be3","fully_enrolled":true,"Session":{"SessionID":"a;lskdjf","SteamLogin":"983498437543","SteamLoginSecure":"dlkjdsl;j%7C%32984730298","WebCookie":";lkjsed;klfjas98093","OAuthToken":"asdk;lf;dsjlkfd","SteamID":1234}}

View file

@ -0,0 +1 @@
{"encrypted":false,"first_run":true,"entries":[{"encryption_iv":null,"encryption_salt":null,"filename":"1234.maFile","steamid":1234}],"periodic_checking":false,"periodic_checking_interval":5,"periodic_checking_checkall":false,"auto_confirm_market_transactions":false,"auto_confirm_trades":false}