diff --git a/.vscode/settings.json b/.vscode/settings.json index 534a2f7..e139a01 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,10 @@ { "cSpell.words": [ + "keygen", + "pubkey", "tempdir", "tempfile", + "treediff", "yage" ] } diff --git a/src/decrypt.rs b/src/decrypt.rs index 0684795..a04e863 100644 --- a/src/decrypt.rs +++ b/src/decrypt.rs @@ -1,3 +1,5 @@ +use serde_yaml as sy; + use crate::cli::DecryptArgs; use crate::error::Result; use crate::util::{decrypt_yaml, load_identities, stdin_or_file, stdout_or_file}; @@ -5,13 +7,13 @@ use crate::util::{decrypt_yaml, load_identities, stdin_or_file, stdout_or_file}; pub fn decrypt(args: &DecryptArgs) -> Result<()> { let identities = load_identities(&args.keys, &args.key_files)?; debug!("loading yaml file: {:?}", args.file); - let input_data: serde_yaml::Value = serde_yaml::from_reader(stdin_or_file(&args.file)?)?; + let input_data: sy::Value = sy::from_reader(stdin_or_file(&args.file)?)?; let output_data = decrypt_yaml(&input_data, &identities)?; let output = stdout_or_file(if args.inplace { &args.file } else { &args.output })?; - serde_yaml::to_writer(output, &output_data)?; + sy::to_writer(output, &output_data)?; Ok(()) } diff --git a/src/edit.rs b/src/edit.rs index 8d97ff0..7bbca03 100644 --- a/src/edit.rs +++ b/src/edit.rs @@ -1,5 +1,6 @@ use std::fs::File; +use serde_yaml as sy; use tempfile::tempdir; use treediff::tools::{ChangeType, Recorder}; use treediff::value::Key; @@ -17,8 +18,7 @@ pub fn edit(args: &EditArgs) -> Result<()> { recipients.push(identity.to_public()); } debug!("loading yaml file: {:?}", args.file); - let input_data: serde_yaml::Value = - serde_yaml::from_reader(File::open(&args.file).path_ctx(&args.file)?)?; + let input_data: sy::Value = sy::from_reader(File::open(&args.file).path_ctx(&args.file)?)?; let previous_data = decrypt_yaml(&input_data, &identities)?; // save the decrypted data in an editable temporary file. The file has the same name as the // original file, but in a temporary directory. This way the user knows which file he is @@ -33,7 +33,7 @@ pub fn edit(args: &EditArgs) -> Result<()> { let temp_file = dir.path().join(filename); { let output = File::create(&temp_file).path_ctx(&temp_file)?; - serde_yaml::to_writer(output, &previous_data)?; + sy::to_writer(output, &previous_data)?; } // open the editor let status = std::process::Command::new(&args.editor) @@ -44,7 +44,7 @@ pub fn edit(args: &EditArgs) -> Result<()> { return Err(AppError::EditorError); } // load the data edited by the user - let edited_data: serde_yaml::Value = serde_yaml::from_reader(File::open(&temp_file)?)?; + let edited_data: sy::Value = sy::from_reader(File::open(&temp_file)?)?; // find what has not changed, and keep the encrypted data unchanged. That data is encrypted // with a nonce that make it appear different every time it is encrypted, so we avoid @@ -65,12 +65,12 @@ pub fn edit(args: &EditArgs) -> Result<()> { let output_data = encrypt_yaml(&to_encrypt_data, &recipients)?; // save the encrypted data in the original file let output = File::create(&args.file).path_ctx(&args.file)?; - serde_yaml::to_writer(output, &output_data)?; + sy::to_writer(output, &output_data)?; Ok(()) } -fn yaml_get<'a>(data: &'a serde_yaml::Value, keys: &[Key]) -> Result<&'a serde_yaml::Value> { +fn yaml_get<'a>(data: &'a sy::Value, keys: &[Key]) -> Result<&'a sy::Value> { if keys.is_empty() { return Ok(data); } diff --git a/src/encrypt.rs b/src/encrypt.rs index 94162c5..1b0722a 100644 --- a/src/encrypt.rs +++ b/src/encrypt.rs @@ -1,3 +1,5 @@ +use serde_yaml as sy; + use crate::cli::EncryptArgs; use crate::error::Result; use crate::util::{encrypt_yaml, load_recipients, stdin_or_file, stdout_or_file}; @@ -5,13 +7,13 @@ use crate::util::{encrypt_yaml, load_recipients, stdin_or_file, stdout_or_file}; pub fn encrypt(args: &EncryptArgs) -> Result<()> { let recipients = load_recipients(&args.recipients, &args.recipients_paths)?; debug!("loading yaml file: {:?}", args.file); - let input_data: serde_yaml::Value = serde_yaml::from_reader(stdin_or_file(&args.file)?)?; + let input_data: sy::Value = sy::from_reader(stdin_or_file(&args.file)?)?; let output_data = encrypt_yaml(&input_data, &recipients)?; let output = stdout_or_file(if args.inplace { &args.file } else { &args.output })?; - serde_yaml::to_writer(output, &output_data)?; + sy::to_writer(output, &output_data)?; Ok(()) } diff --git a/src/env.rs b/src/env.rs index 909791a..c4edde9 100644 --- a/src/env.rs +++ b/src/env.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; use std::process::Command; +use serde_yaml as sy; + use crate::cli::EnvArgs; use crate::error::{AppError, Result}; use crate::util::{decrypt_yaml, load_identities, stdin_or_file}; @@ -8,7 +10,7 @@ use crate::util::{decrypt_yaml, load_identities, stdin_or_file}; pub fn env(args: &EnvArgs) -> Result<()> { let identities = load_identities(&args.keys, &args.key_files)?; debug!("loading yaml file: {:?}", args.file); - let input_data: serde_yaml::Value = serde_yaml::from_reader(stdin_or_file(&args.file)?)?; + let input_data: sy::Value = sy::from_reader(stdin_or_file(&args.file)?)?; let output_data = decrypt_yaml(&input_data, &identities)?; let env_data = build_env(&output_data)?; for (key, value) in &env_data { @@ -26,10 +28,10 @@ pub fn env(args: &EnvArgs) -> Result<()> { Ok(()) } -fn build_env(data: &serde_yaml::Value) -> Result> { +fn build_env(data: &sy::Value) -> Result> { let mut env = HashMap::new(); match data { - serde_yaml::Value::Mapping(mapping) => { + sy::Value::Mapping(mapping) => { for (key, value) in mapping { let key = plain_value_to_string(key)?; let value = plain_value_to_string(value)?; @@ -41,10 +43,10 @@ fn build_env(data: &serde_yaml::Value) -> Result> { Ok(env) } -fn plain_value_to_string(data: &serde_yaml::Value) -> Result { +fn plain_value_to_string(data: &sy::Value) -> Result { Ok(match data { - serde_yaml::Value::String(s) => s.to_owned(), - serde_yaml::Value::Number(n) => { + sy::Value::String(s) => s.to_owned(), + sy::Value::Number(n) => { if n.is_f64() { n.as_f64().unwrap().to_string() } else if n.is_i64() { diff --git a/src/error.rs b/src/error.rs index 972d208..eab0044 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,7 @@ +use std::io; use std::{path::PathBuf, result}; -use std::io; +use serde_yaml as sy; use thiserror::Error; #[derive(Error, Debug)] @@ -13,7 +14,7 @@ pub enum AppError { #[error(transparent)] IoError(#[from] std::io::Error), #[error(transparent)] - YamlError(#[from] serde_yaml::Error), + YamlError(#[from] sy::Error), #[error("can't parse recipient {recipient}: {message}")] RecipientParseError { recipient: String, message: String }, #[error("can't parse key: {message}")] diff --git a/src/util.rs b/src/util.rs index c0af1d7..c977f51 100644 --- a/src/util.rs +++ b/src/util.rs @@ -6,6 +6,7 @@ use std::str::FromStr; use age::x25519; use base64::prelude::*; +use serde_yaml as sy; use substring::Substring; use crate::error::{AppError, IOResultExt, Result}; @@ -30,29 +31,26 @@ pub fn is_yage_encoded(s: &str) -> bool { s.starts_with("yage[") && s.ends_with("]") } -pub fn decrypt_yaml( - value: &serde_yaml::Value, - identities: &[x25519::Identity], -) -> Result { +pub fn decrypt_yaml(value: &sy::Value, identities: &[x25519::Identity]) -> Result { match value { - serde_yaml::Value::Mapping(mapping) => { - let mut output = serde_yaml::Mapping::new(); + sy::Value::Mapping(mapping) => { + let mut output = sy::Mapping::new(); for (key, value) in mapping { let key = key.clone(); let value = decrypt_yaml(value, identities)?; output.insert(key, value); } - Ok(serde_yaml::Value::Mapping(output)) + Ok(sy::Value::Mapping(output)) } - serde_yaml::Value::Sequence(sequence) => { + sy::Value::Sequence(sequence) => { let mut output = Vec::new(); for value in sequence { let value = decrypt_yaml(value, identities)?; output.push(value); } - Ok(serde_yaml::Value::Sequence(output)) + Ok(sy::Value::Sequence(output)) } - serde_yaml::Value::String(encrypted) => { + sy::Value::String(encrypted) => { let decrypted = decrypt_value(encrypted, identities)?; Ok(decrypted) } @@ -60,7 +58,7 @@ pub fn decrypt_yaml( } } -pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result { +pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result { if is_yage_encoded(s) { // remove the yage[…] prefix and suffix let encoded = s.substring(5, s.len() - 1); @@ -72,10 +70,10 @@ pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result Result Result { +pub fn encrypt_yaml(value: &sy::Value, recipients: &[x25519::Recipient]) -> Result { match value { - serde_yaml::Value::Mapping(mapping) => { - let mut output = serde_yaml::Mapping::new(); + sy::Value::Mapping(mapping) => { + let mut output = sy::Mapping::new(); for (key, value) in mapping { let key = key.clone(); let value = encrypt_yaml(value, recipients)?; output.insert(key, value); } - Ok(serde_yaml::Value::Mapping(output)) + Ok(sy::Value::Mapping(output)) } - serde_yaml::Value::Sequence(sequence) => { + sy::Value::Sequence(sequence) => { let mut output = Vec::new(); for value in sequence { let value = encrypt_yaml(value, recipients)?; output.push(value); } - Ok(serde_yaml::Value::Sequence(output)) + Ok(sy::Value::Sequence(output)) } - serde_yaml::Value::String(s) => { + sy::Value::String(s) => { let output = if is_yage_encoded(s) { // keep the already encrypted value s.to_owned() } else { encrypt_value(value, recipients)? }; - Ok(serde_yaml::Value::String(output)) + Ok(sy::Value::String(output)) } - serde_yaml::Value::Number(_) => { + sy::Value::Number(_) => { let output = encrypt_value(value, recipients)?; - Ok(serde_yaml::Value::String(output)) + Ok(sy::Value::String(output)) } _ => Ok(value.clone()), } } -pub fn encrypt_value( - value: &serde_yaml::Value, - recipients: &[x25519::Recipient], -) -> Result { +pub fn encrypt_value(value: &sy::Value, recipients: &[x25519::Recipient]) -> Result { type Recipients = Vec>; - let data = serde_yaml::to_string(value)?; + let data = sy::to_string(value)?; let recipients = recipients .iter() .map(|r| Box::new(r.clone()) as Box)