opus refactoring

This commit is contained in:
2026-05-14 19:53:48 -05:00
parent 365e4bddcc
commit 4dd0c79b20
6 changed files with 53 additions and 54 deletions
+6 -12
View File
@@ -1,4 +1,4 @@
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use flate2::Compression;
use flate2::write::GzEncoder;
use clap::Parser;
@@ -20,9 +20,6 @@ impl Operation for CloseOperation {
validate_ssh_key(&self.key)?;
let target = self.target_path.as_ref().cloned()
.unwrap_or_else(|| default_target(&self.drawer_file, None));
if self.target_path.is_none() {
println!("(assuming from {})", target.display());
}
let meta = std::fs::metadata(&target)
.map_err(|_| DrawerError::TargetInvalid(target.clone()))?;
if !meta.is_dir() && !meta.is_file() {
@@ -33,11 +30,7 @@ impl Operation for CloseOperation {
}
let canon_target = target.canonicalize()
.unwrap_or_else(|_| target.clone());
let drawer_parent = match self.drawer_file.parent() {
None => Path::new("."),
Some(p) if p == Path::new("") => Path::new("."),
Some(p) => p,
};
let drawer_parent = parent_or_dot(&self.drawer_file);
let canon_drawer = drawer_parent.canonicalize()
.unwrap_or_else(|_| drawer_parent.to_path_buf())
.join(self.drawer_file.file_name().unwrap_or_default());
@@ -47,11 +40,12 @@ impl Operation for CloseOperation {
Ok(())
}
fn perform(&self) -> Result<(), DrawerError> {
self.validate()?;
fn execute(&self) -> Result<(), DrawerError> {
let target = self.target_path.as_ref().cloned()
.unwrap_or_else(|| default_target(&self.drawer_file, None));
if self.target_path.is_none() {
println!("(assuming from {})", target.display());
}
let mut buf: Vec<u8> = Vec::new();
{
+3 -10
View File
@@ -1,5 +1,4 @@
use std::path::PathBuf;
use flate2::read::GzDecoder;
use clap::Parser;
use crate::error::DrawerError;
use crate::operation::Operation;
@@ -18,9 +17,7 @@ enum ArchiveInfo {
}
fn archive_info(data: &[u8]) -> Result<ArchiveInfo, DrawerError> {
let cursor = std::io::Cursor::new(data);
let gz = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(gz);
let mut archive = open_archive(data);
let mut entries = archive.entries().map_err(|_| DrawerError::UntarFailed)?;
let first = entries.next()
@@ -34,9 +31,7 @@ fn archive_info(data: &[u8]) -> Result<ArchiveInfo, DrawerError> {
}
}
let cursor = std::io::Cursor::new(data);
let gz = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(gz);
let mut archive = open_archive(data);
let file_count = archive.entries()
.map_err(|_| DrawerError::UntarFailed)?
.filter_map(|e| e.ok())
@@ -53,9 +48,7 @@ impl Operation for InfoOperation {
Ok(())
}
fn perform(&self) -> Result<(), DrawerError> {
self.validate()?;
fn execute(&self) -> Result<(), DrawerError> {
let encrypted = std::fs::read(&self.drawer_file)
.map_err(|_| DrawerError::DrawerFileNotFound(self.drawer_file.clone()))?;
let decrypted = decrypt(encrypted, &self.key, &self.drawer_file)?;
+4 -9
View File
@@ -1,8 +1,9 @@
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use clap::Parser;
use ssh_key::{Algorithm, LineEnding, PrivateKey};
use crate::error::DrawerError;
use crate::operation::Operation;
use crate::utils::parent_or_dot;
#[derive(Parser, Debug, PartialEq)]
pub struct KeyOperation {
@@ -14,19 +15,13 @@ impl Operation for KeyOperation {
if self.filename.exists() {
return Err(DrawerError::KeyOutputFailed(self.filename.clone()));
}
let parent = match self.filename.parent() {
None => Path::new("."),
Some(p) if p == Path::new("") => Path::new("."),
Some(p) => p,
};
if !parent.exists() {
if !parent_or_dot(&self.filename).exists() {
return Err(DrawerError::KeyOutputFailed(self.filename.clone()));
}
Ok(())
}
fn perform(&self) -> Result<(), DrawerError> {
self.validate()?;
fn execute(&self) -> Result<(), DrawerError> {
let private_key = PrivateKey::random(&mut rand::rngs::OsRng, Algorithm::Ed25519)
.map_err(|_| DrawerError::KeyGenerateFailed)?;
let pem = private_key.to_openssh(LineEnding::LF)
+22 -22
View File
@@ -1,5 +1,4 @@
use std::path::PathBuf;
use flate2::read::GzDecoder;
use std::path::{Path, PathBuf};
use clap::Parser;
use crate::error::DrawerError;
use crate::operation::Operation;
@@ -16,9 +15,7 @@ pub struct OpenOperation {
}
fn single_file_entry(data: &[u8]) -> Option<PathBuf> {
let cursor = std::io::Cursor::new(data);
let gz = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(gz);
let mut archive = open_archive(data);
let mut entries = archive.entries().ok()?;
let entry = entries.next()?.ok()?;
if !entry.header().entry_type().is_file() {
@@ -30,6 +27,23 @@ fn single_file_entry(data: &[u8]) -> Option<PathBuf> {
Some(entry.path().ok()?.into_owned())
}
fn unpack_single_file(data: &[u8], target: &Path) -> Result<(), DrawerError> {
let mut archive = open_archive(data);
let mut entry = archive.entries()
.map_err(|_| DrawerError::UntarFailed)?
.next()
.ok_or(DrawerError::UntarFailed)?
.map_err(|_| DrawerError::UntarFailed)?;
entry.unpack(target).map_err(|_| DrawerError::UntarFailed)?;
Ok(())
}
fn unpack_directory(data: &[u8], target: &Path) -> Result<(), DrawerError> {
let mut archive = open_archive(data);
archive.unpack(target).map_err(|_| DrawerError::UntarFailed)?;
Ok(())
}
impl Operation for OpenOperation {
fn validate(&self) -> Result<(), DrawerError> {
validate_drawer_extension(&self.drawer_file)?;
@@ -38,9 +52,7 @@ impl Operation for OpenOperation {
Ok(())
}
fn perform(&self) -> Result<(), DrawerError> {
self.validate()?;
fn execute(&self) -> Result<(), DrawerError> {
let encrypted = std::fs::read(&self.drawer_file)
.map_err(|_| DrawerError::DrawerFileNotFound(self.drawer_file.clone()))?;
let decrypted = decrypt(encrypted, &self.key, &self.drawer_file)?;
@@ -65,21 +77,9 @@ impl Operation for OpenOperation {
}
if sf.is_some() {
let cursor = std::io::Cursor::new(&decrypted);
let gz = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(gz);
let mut entry = archive.entries()
.map_err(|_| DrawerError::UntarFailed)?
.next()
.ok_or(DrawerError::UntarFailed)?
.map_err(|_| DrawerError::UntarFailed)?;
entry.unpack(&target).map_err(|_| DrawerError::UntarFailed)?;
unpack_single_file(&decrypted, &target)
} else {
let cursor = std::io::Cursor::new(decrypted);
let gz = GzDecoder::new(cursor);
let mut archive = tar::Archive::new(gz);
archive.unpack(&target).map_err(|_| DrawerError::UntarFailed)?;
unpack_directory(&decrypted, &target)
}
Ok(())
}
}
+5 -1
View File
@@ -1,6 +1,10 @@
use crate::error::DrawerError;
pub trait Operation {
fn perform(&self) -> Result<(), DrawerError>;
fn validate(&self) -> Result<(), DrawerError>;
fn execute(&self) -> Result<(), DrawerError>;
fn perform(&self) -> Result<(), DrawerError> {
self.validate()?;
self.execute()
}
}
+13
View File
@@ -1,8 +1,21 @@
use std::io::Write;
use std::path::{Path, PathBuf};
use age::ssh::Identity;
use flate2::read::GzDecoder;
use crate::error::DrawerError;
pub fn parent_or_dot(p: &Path) -> &Path {
match p.parent() {
None => Path::new("."),
Some(p) if p == Path::new("") => Path::new("."),
Some(p) => p,
}
}
pub fn open_archive(data: &[u8]) -> tar::Archive<GzDecoder<std::io::Cursor<&[u8]>>> {
tar::Archive::new(GzDecoder::new(std::io::Cursor::new(data)))
}
pub fn key_path(key: &Option<PathBuf>) -> Result<PathBuf, DrawerError> {
if let Some(k) = key {
return Ok(k.clone());