Skip to content

Commit 51b2cc2

Browse files
committed
feat: v1.5.3, environment support vec string
1 parent 5ab4a9e commit 51b2cc2

9 files changed

Lines changed: 72 additions & 15 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "tiny-encrypt"
3-
version = "1.5.1"
3+
version = "1.5.3"
44
edition = "2021"
55
license = "MIT"
66
description = "A simple and tiny file encrypt tool"

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Encrypt config `~/.tinyencrypt/config-rs.json`:
4949
"environment": {
5050
"TINY_ENCRYPT_DEFAULT_ALGORITHM": "AES or CHACHA20"
5151
},
52+
"namespaces": {
53+
"name": "/Users/example/.name"
54+
},
5255
"envelops": [
5356
{
5457
"type": "pgp-rsa",

src/cmd_decrypt.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use yubikey::piv::{AlgorithmId, decrypt_data};
2020
use yubikey::YubiKey;
2121
use zeroize::Zeroize;
2222

23-
use crate::{cmd_encrypt, consts, crypto_simple, util, util_enc_file, util_env, util_envelop, util_file, util_pgp, util_piv};
23+
use crate::{cmd_encrypt, config, consts, crypto_simple, util, util_enc_file, util_env, util_envelop, util_file, util_pgp, util_piv};
2424
use crate::compress::GzStreamDecoder;
2525
use crate::config::TinyEncryptConfig;
2626
use crate::consts::{
@@ -102,8 +102,9 @@ pub fn decrypt(cmd_decrypt: CmdDecrypt) -> XResult<()> {
102102
let key_id = cmd_decrypt.key_id.clone().or_else(util_env::get_key_id);
103103

104104
for path in &cmd_decrypt.paths {
105+
let path = config::resolve_path_namespace(&config, path, true);
105106
let start_decrypt_single = Instant::now();
106-
match decrypt_single(&config, path, &pin, &key_id, &cmd_decrypt.slot, &cmd_decrypt) {
107+
match decrypt_single(&config, &path, &pin, &key_id, &cmd_decrypt.slot, &cmd_decrypt) {
107108
Ok(len) => {
108109
succeed_count += 1;
109110
if len > 0 {
@@ -328,7 +329,12 @@ fn get_file_editor() -> (bool, String) {
328329
fn create_edit_temp_file(file_content: &[u8], path_out: &str) -> XResult<PathBuf> {
329330
let temp_dir = temp_dir();
330331
let current_millis = util_time::get_current_millis();
331-
let temp_file = temp_dir.join(format!("tmp_file_{}_{}", current_millis, path_out));
332+
let file_name = if path_out.contains('/') {
333+
path_out.split('/').last().unwrap().to_string()
334+
} else {
335+
path_out.to_string()
336+
};
337+
let temp_file = temp_dir.join(format!("tmp_file_{}_{}", current_millis, file_name));
332338
information!("Temp file: {}", temp_file.display());
333339
opt_result!(fs::write(&temp_file, file_content), "Write temp file failed: {}");
334340
Ok(temp_file)

src/cmd_encrypt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ pub fn encrypt(cmd_encrypt: CmdEncrypt) -> XResult<()> {
8282
let mut failed_count = 0;
8383
let mut total_len = 0_u64;
8484
for path in &cmd_encrypt.paths {
85+
let path = config.resolve_path_namespace(path, false);
8586
let start_encrypt_single = Instant::now();
86-
match encrypt_single(path, &envelops, &cmd_encrypt) {
87+
match encrypt_single(&path, &envelops, &cmd_encrypt) {
8788
Ok(len) => {
8889
total_len += len;
8990
if len > 0 { succeed_count += 1; } else { skipped_count += 1; }

src/cmd_execenv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rust_util::{debugging, iff, information, opt_result, simple_error, util_cmd,
88
use serde_json::Value;
99
use zeroize::Zeroize;
1010

11-
use crate::{consts, util, util_env};
11+
use crate::{config, consts, util, util_env};
1212
use crate::cmd_decrypt::{decrypt_limited_content_to_vec, select_envelop, try_decrypt_key};
1313
use crate::config::TinyEncryptConfig;
1414
use crate::consts::TINY_ENC_CONFIG_FILE;
@@ -52,6 +52,7 @@ pub fn exec_env(cmd_exec_env: CmdExecEnv) -> XResult<()> {
5252
let key_id = cmd_exec_env.key_id.clone().or_else(util_env::get_key_id);
5353

5454
let path = PathBuf::from(&cmd_exec_env.file_name);
55+
let path = config::resolve_path_namespace(&config, &path, true);
5556
let path_display = format!("{}", &path.display());
5657
util::require_tiny_enc_file_and_exists(&path)?;
5758

src/cmd_info.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rust_util::{
1111
use rust_util::util_time::UnixEpochTime;
1212
use simpledateformat::format_human2;
1313

14-
use crate::{util, util_enc_file, util_envelop};
14+
use crate::{config, util, util_enc_file, util_envelop};
1515
use crate::config::TinyEncryptConfig;
1616
use crate::consts::{DATE_TIME_FORMAT, TINY_ENC_AES_GCM, TINY_ENC_CONFIG_FILE, TINY_ENC_FILE_EXT};
1717
use crate::wrap_key::WrapKey;
@@ -28,8 +28,9 @@ pub struct CmdInfo {
2828
pub fn info(cmd_info: CmdInfo) -> XResult<()> {
2929
let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE).ok();
3030
for (i, path) in cmd_info.paths.iter().enumerate() {
31+
let path = config::resolve_path_namespace(&config, path, true);
3132
if i > 0 { println!("{}", "-".repeat(88)); }
32-
if let Err(e) = info_single(path, &cmd_info, &config) {
33+
if let Err(e) = info_single(&path, &cmd_info, &config) {
3334
failure!("Parse Tiny Encrypt file info failed: {}", e);
3435
}
3536
}

src/config.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use std::{env, fs};
12
use std::cmp::Ordering;
23
use std::collections::HashMap;
3-
use std::{env, fs};
4+
use std::path::PathBuf;
45

5-
use rust_util::{debugging, opt_result, simple_error, XResult};
6+
use rust_util::{debugging, opt_result, simple_error, warning, XResult};
67
use rust_util::util_file::resolve_file_path;
78
use serde::{Deserialize, Serialize};
89

10+
use crate::consts::TINY_ENC_FILE_EXT;
911
use crate::spec::TinyEncryptEnvelopType;
1012

1113
/// Config file sample:
@@ -34,11 +36,19 @@ use crate::spec::TinyEncryptEnvelopType;
3436
#[derive(Clone, Debug, Serialize, Deserialize)]
3537
#[serde(rename_all = "camelCase")]
3638
pub struct TinyEncryptConfig {
37-
pub environment: Option<HashMap<String, String>>,
39+
pub environment: Option<HashMap<String, StringOrVecString>>,
40+
pub namespaces: Option<HashMap<String, String>>,
3841
pub envelops: Vec<TinyEncryptConfigEnvelop>,
3942
pub profiles: HashMap<String, Vec<String>>,
4043
}
4144

45+
#[derive(Clone, Debug, Serialize, Deserialize)]
46+
#[serde(untagged)]
47+
pub enum StringOrVecString {
48+
String(String),
49+
Vec(Vec<String>),
50+
}
51+
4252
#[derive(Clone, Debug, Serialize, Deserialize)]
4353
#[serde(rename_all = "camelCase")]
4454
pub struct TinyEncryptConfigEnvelop {
@@ -78,6 +88,10 @@ impl TinyEncryptConfig {
7888

7989
if let Some(environment) = &config.environment {
8090
for (k, v) in environment {
91+
let v = match v {
92+
StringOrVecString::String(s) => { s.to_string() }
93+
StringOrVecString::Vec(vs) => { vs.join(",") }
94+
};
8195
debugging!("Set env: {}={}", k, v);
8296
env::set_var(k, v);
8397
}
@@ -86,6 +100,30 @@ impl TinyEncryptConfig {
86100
Ok(config)
87101
}
88102

103+
pub fn resolve_path_namespace(&self, path: &PathBuf, append_te: bool) -> PathBuf {
104+
if let Some(path_str) = path.to_str() {
105+
if path_str.starts_with(':') {
106+
let namespace = path_str.chars().skip(1)
107+
.take_while(|c| *c != ':').collect::<String>();
108+
let mut filename = path_str.chars().skip(1)
109+
.skip_while(|c| *c != ':').skip(1).collect::<String>();
110+
if append_te && !filename.ends_with(TINY_ENC_FILE_EXT) {
111+
filename.push_str(TINY_ENC_FILE_EXT);
112+
}
113+
114+
match self.find_namespace(&namespace) {
115+
None => warning!("Namespace: {} not found", &namespace),
116+
Some(dir) => return PathBuf::from(dir).join(&filename),
117+
}
118+
}
119+
}
120+
path.clone()
121+
}
122+
123+
pub fn find_namespace(&self, prefix: &str) -> Option<&String> {
124+
self.namespaces.as_ref().and_then(|m| m.get(prefix))
125+
}
126+
89127
pub fn find_first_arg_by_kid(&self, kid: &str) -> Option<&String> {
90128
self.find_args_by_kid(kid).and_then(|a| a.iter().next())
91129
}
@@ -169,3 +207,10 @@ impl TinyEncryptConfig {
169207
Ok(envelops)
170208
}
171209
}
210+
211+
pub fn resolve_path_namespace(config: &Option<TinyEncryptConfig>, path: &PathBuf, append_te: bool) -> PathBuf {
212+
match config {
213+
None => path.clone(),
214+
Some(config) => config.resolve_path_namespace(path, append_te),
215+
}
216+
}

src/util_keychainstatic.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ impl KeychainKey {
101101
let mut s = String::new();
102102
s.push_str(KEYCHAIN_KEY_PREFIX);
103103
s.push_str(&self.keychain_name);
104-
s.push_str(":");
104+
s.push(':');
105105
s.push_str(&self.service_name);
106-
s.push_str(":");
106+
s.push(':');
107107
s.push_str(&self.key_name);
108108
s
109109
}
@@ -123,7 +123,7 @@ impl KeychainKey {
123123

124124
pub fn set_password(&self, password: &[u8]) -> XResult<()> {
125125
let sec_keychain = self.get_keychain()?;
126-
if let Ok(_) = sec_keychain.find_generic_password(&self.service_name, &self.key_name) {
126+
if sec_keychain.find_generic_password(&self.service_name, &self.key_name).is_ok() {
127127
return simple_error!("Password {}.{} exists", &self.service_name, &self.key_name);
128128
}
129129
opt_result!(

0 commit comments

Comments
 (0)