add a debug command to help triage deserialization issues (#213)

- add a debug command to help triage deserialization issues
- adjust the parsing for legacy accounts
This commit is contained in:
Carson McManus 2023-06-24 08:17:56 -04:00 committed by GitHub
parent 6a5b8d5573
commit 2934dd3927
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 8 deletions

View file

@ -142,15 +142,15 @@ pub struct SdaAccount {
#[zeroize(drop)]
#[deprecated(note = "this is not used anymore, the closest equivalent is `Tokens`")]
pub struct Session {
#[serde(rename = "SessionID")]
#[serde(default, rename = "SessionID")]
pub session_id: String,
#[serde(rename = "SteamLogin")]
#[serde(default, rename = "SteamLogin")]
pub steam_login: String,
#[serde(rename = "SteamLoginSecure")]
#[serde(default, rename = "SteamLoginSecure")]
pub steam_login_secure: String,
#[serde(default, rename = "WebCookie")]
pub web_cookie: Option<String>,
#[serde(rename = "OAuthToken")]
#[serde(default, rename = "OAuthToken")]
pub token: String,
#[serde(rename = "SteamID")]
pub steam_id: u64,

View file

@ -1,6 +1,3 @@
// notes for migration:
// account names must be made lowercase
use std::{fs::File, io::Read, path::Path};
use log::debug;

View file

@ -1,7 +1,7 @@
use log::*;
use steamguard::{Confirmation, ConfirmationType};
use crate::tui;
use crate::{debug::parse_json_stripped, tui};
use super::*;
@ -16,6 +16,12 @@ pub struct DebugCommand {
pub demo_prompt_char: bool,
#[clap(long, help = "Show an example confirmation menu using dummy data.")]
pub demo_conf_menu: bool,
#[clap(
long,
help = "Read the specified file, parse it, strip values, and print the result."
)]
pub print_stripped_json: Option<String>,
}
impl ConstCommand for DebugCommand {
@ -32,6 +38,9 @@ impl ConstCommand for DebugCommand {
if self.demo_conf_menu {
demo_confirmation_menu();
}
if let Some(path) = self.print_stripped_json.as_ref() {
debug_print_json(path)?;
}
Ok(())
}
}
@ -96,3 +105,11 @@ pub fn demo_confirmation_menu() {
.expect("confirmation menu demo failed");
println!("accept: {}, deny: {}", accept.len(), deny.len());
}
fn debug_print_json(path: &str) -> anyhow::Result<()> {
let json = std::fs::read_to_string(path)?;
let v = parse_json_stripped(&json)?;
println!("{}", serde_json::to_string_pretty(&v)?);
Ok(())
}

27
src/debug.rs Normal file
View file

@ -0,0 +1,27 @@
/// Parses a JSON string and prints it in a readable format, with all values stripped and replaced with their types.
pub fn parse_json_stripped(json: &str) -> anyhow::Result<serde_json::Value> {
let v: serde_json::Value = serde_json::from_str(json)?;
let v = strip_json_value(v);
Ok(v)
}
pub fn strip_json_value(v: serde_json::Value) -> serde_json::Value {
match v {
serde_json::Value::Object(mut map) => {
for (_, v) in map.iter_mut() {
*v = strip_json_value(v.clone());
}
serde_json::Value::Object(map)
}
serde_json::Value::Array(mut arr) => {
for v in arr.iter_mut() {
*v = strip_json_value(v.clone());
}
serde_json::Value::Array(arr)
}
serde_json::Value::String(_) => serde_json::Value::String("string".into()),
serde_json::Value::Number(_) => serde_json::Value::Number(0.into()),
serde_json::Value::Bool(_) => serde_json::Value::Bool(false),
serde_json::Value::Null => serde_json::Value::Null,
}
}

View file

@ -26,6 +26,7 @@ extern crate proptest;
extern crate ring;
mod accountmanager;
mod commands;
mod debug;
mod encryption;
mod errors;
mod secret_string;