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