Skip to content

Commit c8ccd67

Browse files
benhillisjstarks
andauthored
flowey: fix saving secret vars (#1417) (#1421)
We are trying to write a non-JSON-formatted value to track that an env-var-sourced variable is secret. Fix this by writing `null`. Also add in some diagnostics and improve the in-memory variable representation to avoid so many allocations. Co-authored-by: John Starks <[email protected]>
1 parent 07681ef commit c8ccd67

File tree

3 files changed

+14
-16
lines changed

3 files changed

+14
-16
lines changed

flowey/flowey_cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ log.workspace = true
1919
parking_lot.workspace = true
2020
petgraph.workspace = true
2121
serde = { workspace = true, features = ["derive"] }
22-
serde_json.workspace = true
22+
serde_json = { workspace = true, features = ["raw_value"] }
2323
serde_yaml.workspace = true
2424
toml_edit = { workspace = true, features = ["serde"] }
2525
xshell.workspace = true

flowey/flowey_cli/src/cli/var_db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ impl VarDb {
273273
if is_secret {
274274
// Remember that this environment variable is secret so that
275275
// it cannot be easily laundered into a non-secret variable.
276-
runtime_var_db.set_var(&env_source_name(&env), false, Vec::new());
276+
runtime_var_db.set_var(&env_source_name(&env), false, "null".into());
277277
}
278278

279279
match backend {

flowey/flowey_cli/src/var_db/single_json_file.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use anyhow::Context;
77
use fs_err::File;
88
use serde::Deserialize;
99
use serde::Serialize;
10+
use serde_json::value::RawValue;
11+
use std::borrow::Cow;
1012
use std::collections::BTreeMap;
1113
use std::io::Seek;
1214
use std::io::Write;
@@ -15,8 +17,8 @@ use std::path::Path;
1517
/// On-disk format for the var db
1618
#[derive(Serialize, Deserialize)]
1719
#[serde(transparent)]
18-
struct VarDb {
19-
vars: BTreeMap<String, (bool, serde_json::Value)>,
20+
struct VarDb<'a> {
21+
vars: BTreeMap<String, (bool, Cow<'a, RawValue>)>,
2022
}
2123

2224
/// Implements [`flowey_core::node::RuntimeVarDb`] backed by a JSON file.
@@ -47,7 +49,7 @@ impl SingleJsonFileVarDb {
4749
Ok(Self { file })
4850
}
4951

50-
fn load_db(&mut self) -> VarDb {
52+
fn load_db(&mut self) -> VarDb<'static> {
5153
self.file.rewind().unwrap();
5254
serde_json::from_reader(&self.file).expect("corrupt runtime variable db")
5355
}
@@ -57,30 +59,26 @@ impl flowey_core::node::RuntimeVarDb for SingleJsonFileVarDb {
5759
fn try_get_var(&mut self, var_name: &str) -> Option<(Vec<u8>, bool)> {
5860
let db = self.load_db();
5961
let (is_secret, ref val) = *db.vars.get(var_name)?;
60-
let val = val.to_string();
6162
if is_secret {
6263
log::debug!("[db] read var: {} = <secret>", var_name);
6364
} else {
6465
log::debug!("[db] read var: {} = {}", var_name, val);
6566
}
66-
Some((val.into(), is_secret))
67+
Some((val.get().into(), is_secret))
6768
}
6869

6970
fn set_var(&mut self, var_name: &str, is_secret: bool, value: Vec<u8>) {
71+
let value: &RawValue = serde_json::from_slice(&value)
72+
.unwrap_or_else(|err| panic!("invalid JSON for var {}: {}", var_name, err));
7073
if is_secret {
7174
log::debug!("[db] set var: {} = <secret>", var_name)
7275
} else {
73-
log::debug!(
74-
"[db] set var: {} = {}",
75-
var_name,
76-
String::from_utf8_lossy(&value)
77-
)
76+
log::debug!("[db] set var: {} = {}", var_name, value)
7877
};
7978
let mut db = self.load_db();
80-
let existing = db.vars.insert(
81-
var_name.into(),
82-
(is_secret, serde_json::from_slice(&value).unwrap()),
83-
);
79+
let existing = db
80+
.vars
81+
.insert(var_name.into(), (is_secret, Cow::Borrowed(value)));
8482
assert!(existing.is_none()); // all vars are one-time-write
8583
self.file.set_len(0).unwrap();
8684
self.file.rewind().unwrap();

0 commit comments

Comments
 (0)