Skip to content

Commit

Permalink
alias serde_yaml in sy
Browse files Browse the repository at this point in the history
  • Loading branch information
glehmann committed Feb 1, 2024
1 parent 24878e0 commit 4236a87
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 49 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"cSpell.words": [
"keygen",
"pubkey",
"tempdir",
"tempfile",
"treediff",
"yage"
]
}
6 changes: 4 additions & 2 deletions src/decrypt.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
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};

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(())
}
12 changes: 6 additions & 6 deletions src/edit.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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);
}
Expand Down
6 changes: 4 additions & 2 deletions src/encrypt.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
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};

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(())
}
14 changes: 8 additions & 6 deletions src/env.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
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};

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 {
Expand All @@ -26,10 +28,10 @@ pub fn env(args: &EnvArgs) -> Result<()> {
Ok(())
}

fn build_env(data: &serde_yaml::Value) -> Result<HashMap<String, String>> {
fn build_env(data: &sy::Value) -> Result<HashMap<String, String>> {
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)?;
Expand All @@ -41,10 +43,10 @@ fn build_env(data: &serde_yaml::Value) -> Result<HashMap<String, String>> {
Ok(env)
}

fn plain_value_to_string(data: &serde_yaml::Value) -> Result<String> {
fn plain_value_to_string(data: &sy::Value) -> Result<String> {
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() {
Expand Down
5 changes: 3 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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}")]
Expand Down
54 changes: 23 additions & 31 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -30,37 +31,34 @@ 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<serde_yaml::Value> {
pub fn decrypt_yaml(value: &sy::Value, identities: &[x25519::Identity]) -> Result<sy::Value> {
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)
}
_ => Ok(value.clone()),
}
}

pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result<serde_yaml::Value> {
pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result<sy::Value> {
if is_yage_encoded(s) {
// remove the yage[…] prefix and suffix
let encoded = s.substring(5, s.len() - 1);
Expand All @@ -72,10 +70,10 @@ pub fn decrypt_value(s: &str, identities: &[x25519::Identity]) -> Result<serde_y
let mut decrypted = vec![];
let mut reader = decryptor.decrypt(identities.iter().map(|i| i as &dyn age::Identity))?;
reader.read_to_end(&mut decrypted)?;
let value: serde_yaml::Value = serde_yaml::from_slice(&decrypted)?;
let value: sy::Value = sy::from_slice(&decrypted)?;
Ok(value)
} else {
Ok(serde_yaml::Value::String(s.to_owned()))
Ok(sy::Value::String(s.to_owned()))
}
}

Expand All @@ -99,51 +97,45 @@ pub fn load_identities(keys: &[String], key_files: &[PathBuf]) -> Result<Vec<x25
Ok(identities)
}

pub fn encrypt_yaml(
value: &serde_yaml::Value,
recipients: &[x25519::Recipient],
) -> Result<serde_yaml::Value> {
pub fn encrypt_yaml(value: &sy::Value, recipients: &[x25519::Recipient]) -> Result<sy::Value> {
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<String> {
pub fn encrypt_value(value: &sy::Value, recipients: &[x25519::Recipient]) -> Result<String> {
type Recipients = Vec<Box<dyn age::Recipient + Send + 'static>>;
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<dyn age::Recipient + Send + 'static>)
Expand Down

0 comments on commit 4236a87

Please sign in to comment.