diff --git a/Cargo.lock b/Cargo.lock index f109ac8..69c4156 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,6 +290,26 @@ dependencies = [ "generic-array", ] +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "discard" version = "1.0.4" @@ -1198,6 +1218,16 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.2", + "redox_syscall", +] + [[package]] name = "regex" version = "1.4.5" @@ -1637,6 +1667,7 @@ dependencies = [ "base64", "clap", "cookie", + "dirs", "hmac-sha1", "lazy_static 1.4.0", "log", diff --git a/Cargo.toml b/Cargo.toml index 8026e97..1f893f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ lazy_static = "1.4.0" uuid = { version = "0.8", features = ["v4"] } termion = "1.5.6" steamguard = { path = "./steamguard" } +dirs = "3.0.2" diff --git a/src/accountmanager.rs b/src/accountmanager.rs index 537b86d..6105a96 100644 --- a/src/accountmanager.rs +++ b/src/accountmanager.rs @@ -10,11 +10,17 @@ use steamguard::SteamGuardAccount; pub struct Manifest { pub encrypted: bool, pub entries: Vec, + /// Not implemented, kept for compatibility with SDA. pub first_run: bool, + /// Not implemented, kept for compatibility with SDA. pub periodic_checking: bool, + /// Not implemented, kept for compatibility with SDA. pub periodic_checking_interval: i32, + /// Not implemented, kept for compatibility with SDA. pub periodic_checking_checkall: bool, + /// Not implemented, kept for compatibility with SDA. pub auto_confirm_market_transactions: bool, + /// Not implemented, kept for compatibility with SDA. pub auto_confirm_trades: bool, #[serde(skip)] @@ -32,8 +38,34 @@ pub struct ManifestEntry { pub steam_id: u64, } +impl Default for Manifest { + fn default() -> Self { + Manifest { + encrypted: false, + entries: vec![], + first_run: false, + periodic_checking: false, + periodic_checking_interval: 0, + periodic_checking_checkall: false, + auto_confirm_market_transactions: false, + auto_confirm_trades: false, + + accounts: vec![], + folder: "".into(), + } + } +} + impl Manifest { - pub fn load(path: &Path) -> anyhow::Result { + /// `path` should be the path to manifest.json + pub fn new(path: &Path) -> Self { + Manifest { + folder: String::from(path.parent().unwrap().to_str().unwrap()), + ..Default::default() + } + } + + pub fn load(path: &Path) -> anyhow::Result { debug!("loading manifest: {:?}", &path); let file = File::open(path)?; let reader = BufReader::new(file); diff --git a/src/main.rs b/src/main.rs index 96e55b6..3cffa3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ use termion::{ extern crate lazy_static; #[macro_use] extern crate anyhow; +extern crate dirs; mod accountmanager; lazy_static! { @@ -57,7 +58,7 @@ fn main() { .long("mafiles-path") .short("m") .default_value("~/maFiles") - .help("Specify which folder your maFiles are in.") + .help("Specify which folder your maFiles are in. This should be a path to a folder that contains manifest.json.") ) .arg( Arg::with_name("passkey") @@ -116,15 +117,33 @@ fn main() { return; } - let path = Path::new(matches.value_of("mafiles-path").unwrap()).join("manifest.json"); + let mafiles_dir = get_mafiles_dir(matches.value_of("mafiles-path")); + info!("reading manifest from {}", mafiles_dir); + let path = Path::new(&mafiles_dir).join("manifest.json"); let mut manifest: accountmanager::Manifest; - match accountmanager::Manifest::load(path.as_path()) { - Ok(m) => { - manifest = m; + if !path.exists() { + error!("Did not find manifest in {}", mafiles_dir); + print!("Would you like to create a manifest in {} ? [Yn] ", mafiles_dir); + match prompt().to_lowercase().as_str() { + "n" => { + info!("Aborting!"); + return; + } + _ => {} } - Err(e) => { - error!("Could not load manifest: {}", e); - return; + std::fs::create_dir_all(mafiles_dir).expect("failed to create directory"); + + manifest = accountmanager::Manifest::new(path.as_path()); + } + else { + match accountmanager::Manifest::load(path.as_path()) { + Ok(m) => { + manifest = m; + } + Err(e) => { + error!("Could not load manifest: {}", e); + return; + } } } @@ -657,3 +676,22 @@ fn demo_confirmation_menu() { ]); println!("accept: {}, deny: {}", accept.len(), deny.len()); } + +fn get_mafiles_dir(arg: Option<&str>) -> String { + if let Some(arg_path) = arg { + return arg_path.into(); + } + + let paths = vec![ + Path::new(&dirs::config_dir().unwrap()).join("steamguard-cli/maFiles"), + Path::new(&dirs::home_dir().unwrap()).join("maFiles"), + ]; + + for path in &paths { + if path.join("manifest.json").is_file() { + return path.to_str().unwrap().into(); + } + } + + return paths[0].to_str().unwrap().into(); +}