Skip to content

Commit

Permalink
feat: add command line arguments to parallel decryptor example
Browse files Browse the repository at this point in the history
Enhanced the parallel streaming decryptor example with proper CLI handling:

- Added required command line arguments for:
  - Data map file path (-d, --data-map)
  - Chunks directory path (-c, --chunks-dir)
  - Output file path (-o, --output)
- Added comprehensive path validation:
  - Checks data map file exists and is readable
  - Verifies chunks directory exists and is a directory
  - Validates output directory exists and is writable
- Added clap dependency with derive features
- Improved error messages and user feedback

The example now provides a more robust CLI interface with proper
validation before attempting decryption operations.
  • Loading branch information
dirvine committed Nov 29, 2024
1 parent 5794755 commit 709713c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ features = ["rt"]
[dev-dependencies]
criterion = "~0.3"
docopt = "~0.9.0"
clap = { version = "4.4", features = ["derive"] }

[dev-dependencies.tokio]
version = "1.34.0"
Expand Down
82 changes: 77 additions & 5 deletions examples/parallel_streaming_decryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,88 @@ use rayon::prelude::*;
use self_encryption::{deserialize, streaming_decrypt_from_storage, DataMap, Error, Result};
use std::{fs::File, io::Read, path::Path};
use xor_name::XorName;
use clap::{Parser, error::ErrorKind};

/// Parallel streaming decryptor for self-encrypted files
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Path to the data map file
#[arg(short, long, required = true)]
data_map: String,

/// Directory containing the encrypted chunks
#[arg(short, long, required = true)]
chunks_dir: String,

/// Path where the decrypted file should be written
#[arg(short, long, required = true)]
output: String,
}

fn validate_paths(args: &Args) -> Result<()> {
// Check data map file exists and is readable
if !Path::new(&args.data_map).exists() {
return Err(Error::Generic(format!(
"Data map file does not exist: {}",
args.data_map
)));
}

// Check chunks directory exists and is readable
let chunks_dir = Path::new(&args.chunks_dir);
if !chunks_dir.exists() {
return Err(Error::Generic(format!(
"Chunks directory does not exist: {}",
args.chunks_dir
)));
}
if !chunks_dir.is_dir() {
return Err(Error::Generic(format!(
"Chunks path is not a directory: {}",
args.chunks_dir
)));
}

// Check output parent directory exists and is writable
let output_path = Path::new(&args.output);
if let Some(parent) = output_path.parent() {
if !parent.exists() {
return Err(Error::Generic(format!(
"Output directory does not exist: {}",
parent.display()
)));
}
// Try to verify write permissions
if !parent.metadata()
.map(|m| m.permissions().readonly())
.unwrap_or(true)
{
return Err(Error::Generic(format!(
"Output directory is not writable: {}",
parent.display()
)));
}
}

Ok(())
}

fn main() -> Result<()> {
// Load the data map from file or another source
let data_map = load_data_map("path/to/data_map")?;
let args = Args::parse();

// Validate all paths before proceeding
validate_paths(&args)?;

// Load the data map from file
let data_map = load_data_map(&args.data_map)?;

// Implement the parallel chunk retrieval function
let get_chunk_parallel = |hashes: &[XorName]| -> Result<Vec<Bytes>> {
hashes
.par_iter()
.map(|hash| {
// Simulate network retrieval with local file read
let chunk_path = Path::new("chunks").join(hex::encode(hash));
let chunk_path = Path::new(&args.chunks_dir).join(hex::encode(hash));
let mut chunk_data = Vec::new();
File::open(&chunk_path)
.and_then(|mut file| file.read_to_end(&mut chunk_data))
Expand All @@ -25,7 +95,9 @@ fn main() -> Result<()> {
};

// Use the streaming decryption function
streaming_decrypt_from_storage(&data_map, Path::new("output_file.dat"), get_chunk_parallel)?;
streaming_decrypt_from_storage(&data_map, Path::new(&args.output), get_chunk_parallel)?;

println!("Successfully decrypted file to: {}", args.output);

Ok(())
}
Expand Down

0 comments on commit 709713c

Please sign in to comment.