diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2acf914..629758a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,16 +21,17 @@ jobs: - uses: actions/checkout@v7.0.1 - uses: dtolnay/rust-toolchain@v1 with: - toolchain: v1 + toolchain: stable + components: clippy, rustfmt - uses: Swatinem/rust-cache@v2.9.2 - name: Build run: cargo build --release - name: Unit + P2P tests run: cargo test --all -- --test-threads=1 - name: Clippy - run: cargo clippy --all -- -D warnings || true + run: cargo clippy --all --all-targets -- -D warnings - name: Format check - run: cargo fmt --all -- --check || true + run: cargo fmt --all -- --check benchmarks: name: Criterion Benchmarks @@ -39,6 +40,8 @@ jobs: steps: - uses: actions/checkout@v7.0.1 - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: stable - uses: Swatinem/rust-cache@v2.9.2 - name: Run benchmarks run: cargo bench -- --output-format bencher 2>/dev/null || echo "Benchmarks completed" @@ -50,6 +53,8 @@ jobs: steps: - uses: actions/checkout@v7.0.1 - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: stable - uses: Swatinem/rust-cache@v2.9.2 - name: Build release run: cargo build --release @@ -89,6 +94,8 @@ jobs: steps: - uses: actions/checkout@v7.0.1 - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: stable - name: Install panic-attack run: cargo install --git https://github.com/hyperpolymath/panic-attacker.git 2>/dev/null || echo "panic-attack unavailable" - name: Run assail scan diff --git a/benches/januskey_benchmarks.rs b/benches/januskey_benchmarks.rs index bee8f95..21ec34c 100644 --- a/benches/januskey_benchmarks.rs +++ b/benches/januskey_benchmarks.rs @@ -117,9 +117,8 @@ fn bench_transactions(c: &mut Criterion) { group.bench_function("begin_commit", |b| { b.iter(|| { - let mut active = false; // Begin - active = true; + let mut active = true; black_box(active); // Commit active = false; @@ -156,7 +155,7 @@ fn bench_key_derivation(c: &mut Criterion) { for _ in 0..1000 { let mut hasher = Sha256::new(); - hasher.update(&hash); + hasher.update(hash); hash.copy_from_slice(&hasher.finalize()); } black_box(hash); diff --git a/crates/januskey-cli/src/attestation.rs b/crates/januskey-cli/src/attestation.rs index daf7e46..1711955 100644 --- a/crates/januskey-cli/src/attestation.rs +++ b/crates/januskey-cli/src/attestation.rs @@ -200,11 +200,7 @@ impl AuditLog { /// Errors if no attestation key is set: an unkeyed attestation is /// forgeable and must never be silently produced (the previous /// `unwrap_or([0u8; 32])` all-zero-key fallback did exactly that). - fn compute_attestation( - &self, - data: &str, - previous_hash: &str, - ) -> std::io::Result { + fn compute_attestation(&self, data: &str, previous_hash: &str) -> std::io::Result { let key = self.attestation_key.ok_or_else(|| { std::io::Error::new( std::io::ErrorKind::PermissionDenied, @@ -213,8 +209,7 @@ impl AuditLog { ) })?; - let mut mac = >::new_from_slice(&key) - .expect("HMAC accepts keys of any length"); + let mut mac = >::new_from_slice(&key).map_err(std::io::Error::other)?; mac.update(Self::ATTESTATION_SCHEME.as_bytes()); mac.update(b"\x00"); mac.update(data.as_bytes()); diff --git a/crates/januskey-cli/src/keys.rs b/crates/januskey-cli/src/keys.rs index 19193dc..117f4a3 100644 --- a/crates/januskey-cli/src/keys.rs +++ b/crates/januskey-cli/src/keys.rs @@ -184,7 +184,7 @@ impl SecretKey { pub fn generate() -> Result { let mut bytes = [0u8; KEY_LENGTH]; - rand::thread_rng().fill_bytes(&mut bytes); + rand::rng().fill_bytes(&mut bytes); Ok(Self { bytes }) } } @@ -192,7 +192,6 @@ impl SecretKey { /// Key manager for JanusKey pub struct KeyManager { store_path: PathBuf, - root_path: PathBuf, kek: Option, audit_log: AuditLog, } @@ -204,7 +203,6 @@ impl KeyManager { let audit_log = AuditLog::new(root); Self { store_path, - root_path: root.to_path_buf(), kek: None, audit_log, } @@ -230,7 +228,7 @@ impl KeyManager { // Generate salt let mut salt = [0u8; SALT_LENGTH]; - rand::thread_rng().fill_bytes(&mut salt); + rand::rng().fill_bytes(&mut salt); // Derive KEK from passphrase let kek = derive_kek(passphrase, &salt)?; @@ -246,7 +244,7 @@ impl KeyManager { // Generate initial nonce let mut nonce = [0u8; NONCE_LENGTH]; - rand::thread_rng().fill_bytes(&mut nonce); + rand::rng().fill_bytes(&mut nonce); // Create empty key store let store = KeyStoreData { @@ -548,7 +546,7 @@ impl KeyManager { let path = self.store_path.join("keystore.jks"); let content = ({ use std::io::Read; - std::fs::File::open(&path).and_then(|mut f| { + std::fs::File::open(&path).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -607,7 +605,7 @@ fn derive_kek(passphrase: &str, salt: &[u8; SALT_LENGTH]) -> Result { /// Wrap (encrypt) key material fn wrap_key(kek: &SecretKey, key: &[u8], metadata: &KeyMetadata) -> Result { let mut nonce_bytes = [0u8; NONCE_LENGTH]; - rand::thread_rng().fill_bytes(&mut nonce_bytes); + rand::rng().fill_bytes(&mut nonce_bytes); let cipher = Aes256Gcm::new(kek.as_bytes().into()); let nonce = Nonce::from_slice(&nonce_bytes); diff --git a/crates/januskey-cli/src/keys_cli.rs b/crates/januskey-cli/src/keys_cli.rs index a9197c6..cd7833e 100644 --- a/crates/januskey-cli/src/keys_cli.rs +++ b/crates/januskey-cli/src/keys_cli.rs @@ -8,12 +8,12 @@ use clap::{Parser, Subcommand}; use colored::Colorize; use dialoguer::{Confirm, Password}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use uuid::Uuid; -mod attestation; -mod keys; use attestation::AuditEventType; +use januskey::attestation; +use januskey::keys; use keys::{KeyAlgorithm, KeyManager, KeyPurpose, KeyState}; #[derive(Parser)] @@ -293,9 +293,7 @@ fn cmd_generate( ) .into()) } - _ => { - return Err(format!("Unknown key type: {}. Use: aes256", key_type).into()) - } + _ => return Err(format!("Unknown key type: {}. Use: aes256", key_type).into()), }; let key_purpose = match purpose.to_lowercase().as_str() { @@ -447,7 +445,7 @@ fn cmd_revoke( Ok(()) } -fn cmd_backup(km: &mut KeyManager, output: &PathBuf) -> Result<(), Box> { +fn cmd_backup(km: &mut KeyManager, output: &Path) -> Result<(), Box> { unlock_store(km)?; if output.exists() { @@ -567,7 +565,7 @@ fn cmd_audit_show(km: &mut KeyManager, limit: usize) -> Result<(), Box 30 { format!("{}...", &reason[..27]) @@ -675,10 +673,7 @@ fn cmd_audit_verify(km: &mut KeyManager) -> Result<(), Box Result<(), Box> { +fn cmd_audit_export(km: &mut KeyManager, output: &Path) -> Result<(), Box> { unlock_store(km)?; if output.exists() { diff --git a/crates/januskey-cli/src/lib.rs b/crates/januskey-cli/src/lib.rs index 6157bf7..f7d39c0 100644 --- a/crates/januskey-cli/src/lib.rs +++ b/crates/januskey-cli/src/lib.rs @@ -76,14 +76,14 @@ impl Config { pub fn load(dir: &std::path::Path) -> Self { let config_path = dir.join(".januskey").join("config.json"); if config_path.exists() { - if let Ok(content) = ({ + if let Ok(content) = { use std::io::Read; - std::fs::File::open(&config_path).and_then(|mut f| { + std::fs::File::open(&config_path).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) }) - }) { + } { if let Ok(config) = serde_json::from_str(&content) { return config; } diff --git a/crates/januskey-cli/src/main.rs b/crates/januskey-cli/src/main.rs index 603392a..182bdc6 100644 --- a/crates/januskey-cli/src/main.rs +++ b/crates/januskey-cli/src/main.rs @@ -15,8 +15,7 @@ use januskey::{ transaction::TransactionPreview, JanusKey, }; -use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; #[derive(Parser)] #[command( @@ -217,7 +216,7 @@ fn main() -> Result<()> { } } -fn cmd_init(dir: &PathBuf) -> Result<()> { +fn cmd_init(dir: &Path) -> Result<()> { if JanusKey::is_initialized(dir) { println!( "{} JanusKey already initialized in {}", @@ -239,7 +238,7 @@ fn cmd_init(dir: &PathBuf) -> Result<()> { } fn cmd_delete( - dir: &PathBuf, + dir: &Path, paths: &[String], recursive: bool, dry_run: bool, @@ -360,7 +359,7 @@ fn cmd_delete( } fn cmd_modify( - dir: &PathBuf, + dir: &Path, pattern: &str, paths: &[String], dry_run: bool, @@ -394,7 +393,7 @@ fn cmd_modify( for file in &files { let content = ({ use std::io::Read; - std::fs::File::open(file).and_then(|mut f| { + std::fs::File::open(file).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -480,12 +479,12 @@ fn parse_sed_pattern(pattern: &str) -> Result<(String, String, bool)> { let search = parts[0].to_string(); let replace = parts[1].to_string(); - let global = parts.get(2).map_or(false, |f| f.contains('g')); + let global = parts.get(2).is_some_and(|f| f.contains('g')); Ok((search, replace, global)) } -fn cmd_move(dir: &PathBuf, source: &str, destination: &PathBuf, dry_run: bool) -> Result<()> { +fn cmd_move(dir: &Path, source: &str, destination: &PathBuf, dry_run: bool) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let source_path = if PathBuf::from(source).is_absolute() { @@ -536,7 +535,7 @@ fn cmd_move(dir: &PathBuf, source: &str, destination: &PathBuf, dry_run: bool) - Ok(()) } -fn cmd_copy(dir: &PathBuf, source: &PathBuf, destination: &PathBuf, dry_run: bool) -> Result<()> { +fn cmd_copy(dir: &Path, source: &PathBuf, destination: &PathBuf, dry_run: bool) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let source_path = if source.is_absolute() { @@ -592,7 +591,7 @@ fn cmd_copy(dir: &PathBuf, source: &PathBuf, destination: &PathBuf, dry_run: boo /// purge its operation-log entries (recording each shred in /// `.januskey/obliterations.json`); otherwise only the working files are /// shredded. -fn cmd_obliterate(dir: &PathBuf, paths: &[PathBuf], dry_run: bool, auto_yes: bool) -> Result<()> { +fn cmd_obliterate(dir: &Path, paths: &[PathBuf], dry_run: bool, auto_yes: bool) -> Result<()> { use januskey::obliteration::{ obliterate_file, obliterate_path, ObliterationManager, OBLITERATION_LOG_FILE, }; @@ -713,7 +712,7 @@ fn cmd_obliterate(dir: &PathBuf, paths: &[PathBuf], dry_run: bool, auto_yes: boo Ok(()) } -fn cmd_undo(dir: &PathBuf, count: usize, id: Option) -> Result<()> { +fn cmd_undo(dir: &Path, count: usize, id: Option) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; if let Some(op_id) = id { @@ -767,7 +766,7 @@ fn cmd_undo(dir: &PathBuf, count: usize, id: Option) -> Result<()> { Ok(()) } -fn cmd_begin(dir: &PathBuf, name: Option) -> Result<()> { +fn cmd_begin(dir: &Path, name: Option) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let tx = jk.transaction_manager.begin(name.clone())?; @@ -786,7 +785,7 @@ fn cmd_begin(dir: &PathBuf, name: Option) -> Result<()> { Ok(()) } -fn cmd_commit(dir: &PathBuf) -> Result<()> { +fn cmd_commit(dir: &Path) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let tx = jk.transaction_manager.commit()?; @@ -801,7 +800,7 @@ fn cmd_commit(dir: &PathBuf) -> Result<()> { Ok(()) } -fn cmd_rollback(dir: &PathBuf) -> Result<()> { +fn cmd_rollback(dir: &Path) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; // Get the active transaction's operation IDs before modifying state @@ -830,7 +829,7 @@ fn cmd_rollback(dir: &PathBuf) -> Result<()> { Ok(()) } -fn cmd_preview(dir: &PathBuf) -> Result<()> { +fn cmd_preview(dir: &Path) -> Result<()> { let jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let tx = jk @@ -843,7 +842,7 @@ fn cmd_preview(dir: &PathBuf) -> Result<()> { let name = preview .transaction_name .unwrap_or_else(|| tx.id[..8].to_string()); - println!("{} Transaction: {}", "📋".to_string(), name.cyan()); + println!("📋 Transaction: {}", name.cyan()); println!("Operations pending: {}", preview.operations.len()); println!(); @@ -887,7 +886,7 @@ fn cmd_preview(dir: &PathBuf) -> Result<()> { Ok(()) } -fn cmd_history(dir: &PathBuf, limit: usize, filter: Option) -> Result<()> { +fn cmd_history(dir: &Path, limit: usize, filter: Option) -> Result<()> { let jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let ops: Vec<_> = if let Some(ref filter_str) = filter { @@ -949,7 +948,7 @@ fn cmd_history(dir: &PathBuf, limit: usize, filter: Option) -> Result<() Ok(()) } -fn cmd_status(dir: &PathBuf) -> Result<()> { +fn cmd_status(dir: &Path) -> Result<()> { let jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; println!("{}", "JanusKey Status".bold()); @@ -965,7 +964,7 @@ fn cmd_status(dir: &PathBuf) -> Result<()> { if let Some(tx) = jk.transaction_manager.active() { let name = tx.name.clone().unwrap_or_else(|| tx.id[..8].to_string()); println!(); - println!("{} Active transaction: {}", "📝".to_string(), name.cyan()); + println!("📝 Active transaction: {}", name.cyan()); println!(" Started: {}", tx.started_at.format("%Y-%m-%d %H:%M:%S")); println!(" Operations: {}", tx.operation_ids.len()); } else { @@ -976,7 +975,7 @@ fn cmd_status(dir: &PathBuf) -> Result<()> { Ok(()) } -fn cmd_gc(dir: &PathBuf, keep: Option, _older_than: Option) -> Result<()> { +fn cmd_gc(dir: &Path, keep: Option, _older_than: Option) -> Result<()> { let mut jk = JanusKey::open(dir).context("Failed to open JanusKey directory")?; let keep_count = keep.unwrap_or(jk.config.max_history); diff --git a/crates/januskey-cli/src/obliteration.rs b/crates/januskey-cli/src/obliteration.rs index 546f0ba..c00f8fd 100644 --- a/crates/januskey-cli/src/obliteration.rs +++ b/crates/januskey-cli/src/obliteration.rs @@ -73,13 +73,13 @@ impl ObliterationProof { // Generate random nonce let mut nonce_bytes = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut nonce_bytes); + rand::rng().fill_bytes(&mut nonce_bytes); let nonce = hex::encode(nonce_bytes); // Generate commitment: H(content_hash || nonce || timestamp) let mut hasher = Sha256::new(); hasher.update(content_hash.raw_hash().as_bytes()); - hasher.update(&nonce_bytes); + hasher.update(nonce_bytes); hasher.update(timestamp.to_rfc3339().as_bytes()); let commitment = hex::encode(hasher.finalize()); @@ -163,7 +163,7 @@ impl ObliterationManager { let log = if log_path.exists() { let content = ({ use std::io::Read; - std::fs::File::open(&log_path).and_then(|mut f| { + std::fs::File::open(&log_path).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -342,7 +342,7 @@ fn secure_overwrite(path: &Path) -> Result { let buffer = if pass == OVERWRITE_PASSES - 1 { // Final pass: random data let mut random_buffer = vec![0u8; file_size.min(8192)]; - rand::thread_rng().fill_bytes(&mut random_buffer); + rand::rng().fill_bytes(&mut random_buffer); random_buffer } else { // Fixed pattern diff --git a/crates/januskey-cli/src/operations.rs b/crates/januskey-cli/src/operations.rs index 2813ca0..29803fe 100644 --- a/crates/januskey-cli/src/operations.rs +++ b/crates/januskey-cli/src/operations.rs @@ -500,7 +500,7 @@ mod tests { assert_eq!( ({ use std::io::Read; - std::fs::File::open(&test_file).and_then(|mut f| { + std::fs::File::open(&test_file).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -531,7 +531,7 @@ mod tests { assert_eq!( ({ use std::io::Read; - std::fs::File::open(&test_file).and_then(|mut f| { + std::fs::File::open(&test_file).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -548,7 +548,7 @@ mod tests { assert_eq!( ({ use std::io::Read; - std::fs::File::open(&test_file).and_then(|mut f| { + std::fs::File::open(&test_file).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) diff --git a/crates/januskey-cli/tests/aspect_test.rs b/crates/januskey-cli/tests/aspect_test.rs index a9fc372..e4cfa1a 100644 --- a/crates/januskey-cli/tests/aspect_test.rs +++ b/crates/januskey-cli/tests/aspect_test.rs @@ -9,7 +9,7 @@ // - Overwrite patterns applied correctly (3-pass DoD 5220.22-M) use std::fs; -use std::path::PathBuf; +use std::path::Path; use tempfile::TempDir; /// Helper: Create temp directory @@ -18,7 +18,7 @@ fn test_dir() -> TempDir { } /// Helper: Create jk directories -fn setup_jk_dirs(base: &PathBuf) -> std::io::Result<()> { +fn setup_jk_dirs(base: &Path) -> std::io::Result<()> { fs::create_dir_all(base.join(".jk/content"))?; fs::create_dir_all(base.join(".jk/obliteration"))?; fs::create_dir_all(base.join(".jk/keys"))?; @@ -26,7 +26,7 @@ fn setup_jk_dirs(base: &PathBuf) -> std::io::Result<()> { } /// Helper: Create a test key file and record -fn create_test_key(base: &PathBuf, key_id: &str, material: &[u8]) -> String { +fn create_test_key(base: &Path, key_id: &str, material: &[u8]) -> String { use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); @@ -143,13 +143,11 @@ fn obliterated_key_record_marked_revoked() { // Verify key record reflects revocation let key_content = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/keys").join(format!("{}.json", key_id))).and_then( - |mut f| { - let mut buf = String::new(); - f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; - Ok(buf) - }, - ) + std::fs::File::open(base.join(".jk/keys").join(format!("{}.json", key_id))).and_then(|f| { + let mut buf = String::new(); + f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; + Ok(buf) + }) }) .expect("Read key record"); assert!( diff --git a/crates/januskey-cli/tests/concurrency_test.rs b/crates/januskey-cli/tests/concurrency_test.rs index 81ba781..e4226e7 100644 --- a/crates/januskey-cli/tests/concurrency_test.rs +++ b/crates/januskey-cli/tests/concurrency_test.rs @@ -9,7 +9,7 @@ // - Race conditions in commit/rollback don't corrupt state use std::fs; -use std::path::PathBuf; +use std::path::Path; use std::sync::{Arc, Mutex}; use tempfile::TempDir; @@ -19,7 +19,7 @@ fn test_dir() -> TempDir { } /// Helper: Setup jk directories -fn setup_jk_dirs(base: &PathBuf) -> std::io::Result<()> { +fn setup_jk_dirs(base: &Path) -> std::io::Result<()> { fs::create_dir_all(base.join(".jk/content"))?; fs::create_dir_all(base.join(".jk/transactions"))?; fs::create_dir_all(base.join(".jk/operations"))?; @@ -60,7 +60,7 @@ fn concurrent_key_operations_no_deadlock() { // Write content fs::write(&content_path, material.as_bytes()) - .expect(&format!("Write failed for {}", key_id)); + .unwrap_or_else(|_| panic!("Write failed for {}", key_id)); // Record key let key_record = format!(r#"{{"id":"{}","hash":"{}","thread":{}}}"#, key_id, hash, i); @@ -68,10 +68,11 @@ fn concurrent_key_operations_no_deadlock() { base_clone.join(".jk/keys").join(format!("{}.json", key_id)), &key_record, ) - .expect(&format!("Key record failed for {}", key_id)); + .unwrap_or_else(|_| panic!("Key record failed for {}", key_id)); // Read back immediately - let read_back = fs::read(&content_path).expect(&format!("Read failed for {}", key_id)); + let read_back = + fs::read(&content_path).unwrap_or_else(|_| panic!("Read failed for {}", key_id)); assert_eq!( read_back, material.as_bytes(), @@ -127,12 +128,12 @@ fn transaction_isolation_uncommitted_invisible() { let ops_dir = base_clone.join(".jk/operations"); let ops: Vec<_> = fs::read_dir(&ops_dir) - .unwrap_or_else(|_| fs::read_dir(&base_clone.join(".jk")).unwrap()) + .unwrap_or_else(|_| fs::read_dir(base_clone.join(".jk")).unwrap()) .filter_map(Result::ok) .filter(|e| { e.file_name() .to_str() - .map_or(false, |n| n.contains(&tx_id_clone)) + .is_some_and(|n| n.contains(&tx_id_clone)) }) .collect(); @@ -159,7 +160,7 @@ fn transaction_isolation_uncommitted_invisible() { // but we verify the transaction itself is still "active" not "committed" let tx_read = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/transactions/001.json")).and_then(|mut f| { + std::fs::File::open(base.join(".jk/transactions/001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -388,7 +389,7 @@ fn concurrent_commit_rollback_no_corruption() { let entry = entry.expect("Dir entry"); let content = ({ use std::io::Read; - std::fs::File::open(entry.path()).and_then(|mut f| { + std::fs::File::open(entry.path()).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) diff --git a/crates/januskey-cli/tests/e2e_test.rs b/crates/januskey-cli/tests/e2e_test.rs index 9641a49..4566755 100644 --- a/crates/januskey-cli/tests/e2e_test.rs +++ b/crates/januskey-cli/tests/e2e_test.rs @@ -7,7 +7,7 @@ // Content roundtrip: write → hash → read → delete use std::fs; -use std::path::PathBuf; +use std::path::Path; use tempfile::TempDir; /// Helper: Create a temp directory for test isolation @@ -16,7 +16,7 @@ fn test_dir() -> TempDir { } /// Helper: Create jk directories -fn setup_jk_dirs(base: &PathBuf) -> std::io::Result<()> { +fn setup_jk_dirs(base: &Path) -> std::io::Result<()> { fs::create_dir_all(base.join(".jk/content"))?; fs::create_dir_all(base.join(".jk/metadata"))?; fs::create_dir_all(base.join(".jk/attestation"))?; @@ -85,7 +85,7 @@ fn full_key_lifecycle_single_key() { // Step 5: Verify attestation references the key let attest_read = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/attestation/0001.json")).and_then(|mut f| { + std::fs::File::open(base.join(".jk/attestation/0001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -104,7 +104,7 @@ fn full_key_lifecycle_single_key() { // Verify key record exists let key_read = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/keys/001.json")).and_then(|mut f| { + std::fs::File::open(base.join(".jk/keys/001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -134,7 +134,7 @@ fn full_key_lifecycle_multi_key_transaction() { for (i, (key_id, material)) in keys.iter().enumerate() { // Store content - let hash = sha256(*material); + let hash = sha256(material); let content_path = base.join(".jk/content").join(&hash); fs::write(&content_path, material).expect("Store content"); @@ -173,11 +173,7 @@ fn full_key_lifecycle_multi_key_transaction() { let op_files: Vec<_> = fs::read_dir(base.join(".jk/operations")) .expect("Read ops dir") .filter_map(Result::ok) - .filter(|e| { - e.file_name() - .to_str() - .map_or(false, |n| n.starts_with(tx_id)) - }) + .filter(|e| e.file_name().to_str().is_some_and(|n| n.starts_with(tx_id))) .collect(); assert_eq!(op_files.len(), 3, "Transaction must contain 3 operations"); @@ -188,7 +184,7 @@ fn full_key_lifecycle_multi_key_transaction() { // Verify transaction is committed let tx_read = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/transactions/001.json")).and_then(|mut f| { + std::fs::File::open(base.join(".jk/transactions/001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -239,13 +235,13 @@ fn delta_chain_full_history() { fs::write(base.join(".jk/metadata/delta-02.json"), &delta_2_to_3).expect("Write delta 2→3"); // Verify chain is intact: can read all versions - let read_v1 = fs::read(&base.join(".jk/content").join(&v1_hash)).expect("Read v1"); + let read_v1 = fs::read(base.join(".jk/content").join(&v1_hash)).expect("Read v1"); assert_eq!(read_v1, v1, "Version 1 must be recoverable"); - let read_v2 = fs::read(&base.join(".jk/content").join(&v2_hash)).expect("Read v2"); + let read_v2 = fs::read(base.join(".jk/content").join(&v2_hash)).expect("Read v2"); assert_eq!(read_v2, v2, "Version 2 must be recoverable"); - let read_v3 = fs::read(&base.join(".jk/content").join(&v3_hash)).expect("Read v3"); + let read_v3 = fs::read(base.join(".jk/content").join(&v3_hash)).expect("Read v3"); assert_eq!(read_v3, v3, "Version 3 must be recoverable"); // Verify chain links are recorded @@ -255,7 +251,7 @@ fn delta_chain_full_history() { .filter(|e| { e.file_name() .to_str() - .map_or(false, |n| n.starts_with("delta")) + .is_some_and(|n| n.starts_with("delta")) }) .collect(); assert_eq!(delta_files.len(), 2, "Delta chain must have 2 links"); @@ -377,7 +373,7 @@ fn corrupted_attestation_entry_detected() { // Attempt to read and parse let read_result = ({ use std::io::Read; - std::fs::File::open(base.join(".jk/attestation/0001.json")).and_then(|mut f| { + std::fs::File::open(base.join(".jk/attestation/0001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) diff --git a/crates/januskey-cli/tests/p2p_test.rs b/crates/januskey-cli/tests/p2p_test.rs index 7a5265c..e2a252d 100644 --- a/crates/januskey-cli/tests/p2p_test.rs +++ b/crates/januskey-cli/tests/p2p_test.rs @@ -103,7 +103,7 @@ fn key_operation_creates_attestation_entry() { // Verify attestation references the key let read_back = ({ use std::io::Read; - std::fs::File::open(attest_path.join("0001.json")).and_then(|mut f| { + std::fs::File::open(attest_path.join("0001.json")).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -143,7 +143,7 @@ fn attestation_chain_integrity() { .map(|i| { ({ use std::io::Read; - std::fs::File::open(attest_path.join(format!("{:04}.json", i))).and_then(|mut f| { + std::fs::File::open(attest_path.join(format!("{:04}.json", i))).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) @@ -195,11 +195,7 @@ fn transaction_groups_operations() { let op_files: Vec<_> = std::fs::read_dir(&ops_path) .unwrap() .filter_map(|e| e.ok()) - .filter(|e| { - e.file_name() - .to_str() - .map_or(false, |n| n.starts_with(tx_id)) - }) + .filter(|e| e.file_name().to_str().is_some_and(|n| n.starts_with(tx_id))) .collect(); assert_eq!(op_files.len(), 3, "Transaction must group all 3 operations"); } diff --git a/crates/reversible-core/src/manifest.rs b/crates/reversible-core/src/manifest.rs index 28799e8..26503a7 100644 --- a/crates/reversible-core/src/manifest.rs +++ b/crates/reversible-core/src/manifest.rs @@ -41,7 +41,7 @@ impl ManifestEmitter { // Header manifest.push_str("@manifest\n"); - manifest.push_str(&format!(" version = \"1.0\"\n")); + manifest.push_str(" version = \"1.0\"\n"); manifest.push_str(&format!(" subsystem = \"{}\"\n", subsystem)); manifest.push_str(&format!(" timestamp = \"{}\"\n", timestamp)); manifest.push_str(&format!( @@ -105,7 +105,7 @@ impl ManifestEmitter { }; let current = hasher.finalize_reset(); - hasher.update(¤t); + hasher.update(current); hasher.update(&op_hash); } diff --git a/crates/reversible-core/src/metadata.rs b/crates/reversible-core/src/metadata.rs index 7beb3a2..fe44d8a 100644 --- a/crates/reversible-core/src/metadata.rs +++ b/crates/reversible-core/src/metadata.rs @@ -263,7 +263,7 @@ impl MetadataStore { let log = if path.exists() { let content = ({ use std::io::Read; - std::fs::File::open(&path).and_then(|mut f| { + std::fs::File::open(&path).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) diff --git a/crates/reversible-core/src/transaction.rs b/crates/reversible-core/src/transaction.rs index 2f0ff6c..8f47601 100644 --- a/crates/reversible-core/src/transaction.rs +++ b/crates/reversible-core/src/transaction.rs @@ -123,7 +123,7 @@ impl TransactionManager { let log = if path.exists() { let content = ({ use std::io::Read; - std::fs::File::open(&path).and_then(|mut f| { + std::fs::File::open(&path).and_then(|f| { let mut buf = String::new(); f.take(10 * 1024 * 1024).read_to_string(&mut buf)?; Ok(buf) diff --git a/tests/aspect/cross_cutting_test.sh b/tests/aspect/cross_cutting_test.sh index 37cd574..7b3599f 100755 --- a/tests/aspect/cross_cutting_test.sh +++ b/tests/aspect/cross_cutting_test.sh @@ -52,10 +52,10 @@ check "No unsafe in reversible-core" "! grep -rh 'unsafe' '${JK_DIR}/crates/reve # --- Documentation --- echo "--- Documentation ---" check "README exists" "[ -f '${JK_DIR}/README.md' ] || [ -f '${JK_DIR}/README.adoc' ]" -check "SECURITY.md exists" "[ -f '${JK_DIR}/SECURITY.md' ]" -check "ARCHITECTURE.md exists" "[ -f '${JK_DIR}/ARCHITECTURE.md' ]" -check "PROOF-NEEDS.md exists" "[ -f '${JK_DIR}/PROOF-NEEDS.md' ]" -check "TOPOLOGY.md exists" "[ -f '${JK_DIR}/TOPOLOGY.md' ]" +check "SECURITY exists" "[ -f '${JK_DIR}/SECURITY.md' ] || [ -f '${JK_DIR}/SECURITY.adoc' ]" +check "ARCHITECTURE exists" "[ -f '${JK_DIR}/ARCHITECTURE.md' ] || [ -f '${JK_DIR}/ARCHITECTURE.adoc' ]" +check "PROOF-NEEDS exists" "[ -f '${JK_DIR}/PROOF-NEEDS.md' ] || [ -f '${JK_DIR}/PROOF-NEEDS.adoc' ]" +check "TOPOLOGY exists" "[ -f '${JK_DIR}/TOPOLOGY.md' ] || [ -f '${JK_DIR}/TOPOLOGY.adoc' ]" check "LICENSE directory exists" "[ -d '${JK_DIR}/LICENSES' ]" # --- Proofs ---