refactor(cli): apply simplify findings (Plan B Phases 4-6 polish)
- session.rs: drop save_manifest_raw — its only caller was after_manifest_change itself; the pub(crate) advertised the exact bypass-the-cache-refresh footgun the wrapper exists to eliminate. Inline the encrypt + atomic_write pair. - session.rs: into_kdf_params(self) → to_kdf_params(&self). Body just copies three u32s; the consume-self had no ownership benefit and forced the round-trip test to rebuild a ParamsFile field-by-field. - helpers.rs: add git_rm(repo, paths, context) wrapper around git_run + the load-bearing --ignore-unmatch flag. Replaces two near-identical three-line "build rm_args, extend, git_run" blocks in trash.rs. - trash.rs: purge_item_filesystem drops the if x.exists() pre-checks (TOCTOU + redundant stat per item per trash-empty iteration). Uses ErrorKind::NotFound swallow on remove_file/remove_dir_all instead. - basic_flows.rs: trim trash_empty_batches_into_one_commit's sleep comment to just the WHY.
This commit is contained in:
@@ -74,19 +74,12 @@ impl UnlockedVault {
|
||||
/// changes the manifest goes through this method, so cache freshness is
|
||||
/// a compile-time invariant rather than a discipline rule.
|
||||
pub fn after_manifest_change(&self, manifest: &Manifest) -> Result<()> {
|
||||
self.save_manifest_raw(manifest)?;
|
||||
let bytes = encrypt_manifest(manifest, &self.master_key)?;
|
||||
atomic_write(&self.manifest_path(), &bytes)?;
|
||||
crate::helpers::refresh_groups_cache(&self.root, manifest);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Encrypt the manifest and atomically write it. Most callers want
|
||||
/// `after_manifest_change` instead — this method skips the groups.cache
|
||||
/// refresh, leaving shell completion stale until the next mutation.
|
||||
pub(crate) fn save_manifest_raw(&self, manifest: &Manifest) -> Result<()> {
|
||||
let bytes = encrypt_manifest(manifest, &self.master_key)?;
|
||||
atomic_write(&self.manifest_path(), &bytes)
|
||||
}
|
||||
|
||||
pub fn load_settings(&self) -> Result<VaultSettings> {
|
||||
let bytes = fs::read(self.settings_path()).context("failed to read settings.enc")?;
|
||||
Ok(decrypt_settings(&bytes, &self.master_key)?)
|
||||
@@ -152,7 +145,7 @@ impl ParamsFile {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_kdf_params(self) -> KdfParams {
|
||||
pub fn to_kdf_params(&self) -> KdfParams {
|
||||
KdfParams {
|
||||
argon2_m: self.kdf.argon2_m,
|
||||
argon2_t: self.kdf.argon2_t,
|
||||
@@ -165,7 +158,7 @@ fn read_params(root: &Path) -> Result<KdfParams> {
|
||||
let s = fs::read_to_string(root.join(".relicario").join("params.json"))
|
||||
.context("failed to read .relicario/params.json")?;
|
||||
let pf: ParamsFile = serde_json::from_str(&s).context("failed to parse params.json")?;
|
||||
Ok(pf.into_kdf_params())
|
||||
Ok(pf.to_kdf_params())
|
||||
}
|
||||
|
||||
/// Locate the reference image path via `RELICARIO_IMAGE` env var or interactive prompt.
|
||||
@@ -225,18 +218,7 @@ mod tests {
|
||||
assert_eq!(pf.aead, "xchacha20poly1305");
|
||||
assert_eq!(pf.salt_path, ".relicario/salt");
|
||||
|
||||
let kdf = ParamsFile {
|
||||
format_version: pf.format_version,
|
||||
kdf: ParamsKdf {
|
||||
algorithm: pf.kdf.algorithm.clone(),
|
||||
argon2_m: pf.kdf.argon2_m,
|
||||
argon2_t: pf.kdf.argon2_t,
|
||||
argon2_p: pf.kdf.argon2_p,
|
||||
},
|
||||
aead: pf.aead.clone(),
|
||||
salt_path: pf.salt_path.clone(),
|
||||
}
|
||||
.into_kdf_params();
|
||||
let kdf = pf.to_kdf_params();
|
||||
assert_eq!(kdf.argon2_m, 65536);
|
||||
assert_eq!(kdf.argon2_t, 3);
|
||||
assert_eq!(kdf.argon2_p, 4);
|
||||
|
||||
Reference in New Issue
Block a user