Skip to content

Commit

Permalink
Implement error generation macro into codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
duckysmacky committed Jan 16, 2025
1 parent 3b42dc9 commit e6796ff
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 53 deletions.
27 changes: 14 additions & 13 deletions src/cli/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{Error, options, log_error, log_success, log_warn, log_info};
use crate::core::error::ProfileErrorKind;
use super::prompts;


pub fn handle_box(g_args: &ArgMatches, args: &ArgMatches) -> (u32, u32) {
let mut total_files: u32 = 0;
let mut error_files: u32 = 0;
Expand Down Expand Up @@ -44,7 +43,7 @@ pub fn handle_box(g_args: &ArgMatches, args: &ArgMatches) -> (u32, u32) {
Ok(_) => log_success!("Successfully encrypted {:?}", file_name),
Err(err) => {
log_error!("Unable to encrypt \"{}\"", file_name.to_string_lossy());
handle_error(err, false);
handle_error(err);
error_files += 1;
}
}
Expand Down Expand Up @@ -87,7 +86,7 @@ pub fn handle_unbox(g_args: &ArgMatches, args: &ArgMatches) -> (u32, u32) {
Ok(_) => log_success!("Successfully decrypted {:?}", path.file_name().unwrap().to_os_string()),
Err(err) => {
log_error!("Unable to encrypt \"{}\"", file_name.to_string_lossy());
handle_error(err, false);
handle_error(err);
error_files += 1;
}
}
Expand All @@ -108,7 +107,7 @@ pub fn handle_profile_create(g_args: &ArgMatches, args: &ArgMatches) {
Ok(_) => log_success!("Successfully created new profile \"{}\"", name),
Err(err) => {
log_error!("Unable to create a new profile named \"{}\"", name);
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -125,7 +124,7 @@ pub fn handle_profile_delete(g_args: &ArgMatches, args: &ArgMatches) {
Ok(_) => log_success!("Successfully deleted profile \"{}\"", name),
Err(err) => {
log_error!("Unable to delete profile \"{}\"", name);
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -142,7 +141,7 @@ pub fn handle_profile_set(g_args: &ArgMatches, args: &ArgMatches) {
Ok(_) => log_success!("Successfully set current profile to \"{}\"", name),
Err(err) => {
log_error!("Unable to switch to profile \"{}\"", name);
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -152,7 +151,7 @@ pub fn handle_profile_get(_g_args: &ArgMatches, _args: &ArgMatches) {
Ok(name) => log_success!("Currently selected profile: {}", name),
Err(err) => {
log_error!("Unable to get currently selected profile");
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -162,7 +161,7 @@ pub fn handle_profile_list(_g_args: &ArgMatches, _args: &ArgMatches) {

let profiles = profiles.unwrap_or_else(|err| {
log_error!("Unable to get a list of all profiles");
handle_error(err, false);
handle_error(err);
vec![]
});
let count = profiles.len();
Expand All @@ -189,7 +188,7 @@ pub fn handle_key_new(g_args: &ArgMatches, _args: &ArgMatches) {
Ok(_) => log_success!("Successfully generated new encryption key for the current profile"),
Err(err) => {
log_error!("Unable to generate a new encryption key");
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -211,7 +210,7 @@ pub fn handle_key_get(g_args: &ArgMatches, args: &ArgMatches) {
}
Err(err) => {
log_error!("Unable to get an encryption key for the current profile");
handle_error(err, true);
handle_error(err);
}
}
}
Expand All @@ -228,11 +227,12 @@ pub fn handle_key_set(g_args: &ArgMatches, args: &ArgMatches) {
Ok(_) => log_success!("Successfully set a new encryption key for the current profile"),
Err(err) => {
log_error!("Unable to set an encryption key for the current profile");
handle_error(err, true);
handle_error(err);
}
}
}

/// Converts from the passed arguments strings to vector of paths
fn get_path_vec(args: &ArgMatches, arg_id: &str) -> Option<Vec<PathBuf>> {
if let Some(strings) = args.get_many::<String>(arg_id) {
return Some(strings
Expand All @@ -243,6 +243,7 @@ fn get_path_vec(args: &ArgMatches, arg_id: &str) -> Option<Vec<PathBuf>> {
None
}

/// Converts from the passed arguments strings to deque of paths
fn get_path_deque(args: &ArgMatches, arg_id: &str) -> Option<VecDeque<PathBuf>> {
if let Some(strings) = args.get_many::<String>(arg_id) {
let mut deque = VecDeque::new();
Expand All @@ -257,7 +258,7 @@ fn get_path_deque(args: &ArgMatches, arg_id: &str) -> Option<VecDeque<PathBuf>>
}

/// Handles the error and acts according to each error
fn handle_error(err: Error, always_exit: bool) {
fn handle_error(err: Error) {
log_error!("{}", err);
match &err {
Error::ProfileError(kind) => {
Expand All @@ -273,7 +274,7 @@ fn handle_error(err: Error, always_exit: bool) {
_ => {}
}

if always_exit || err.should_exit() {
if err.should_exit() {
exit(err.exit_code());
}
}
5 changes: 2 additions & 3 deletions src/core/data/auth.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Contains functions related to user authentication and password
use crate::{Result, Error};
use crate::core::error::EncryptionErrorKind;
use crate::{Result, new_err};
use argon2::{self, Config};
use rand::random;

Expand All @@ -10,7 +9,7 @@ pub fn hash_password(password: &str) -> Result<(String, [u8; 16])> {
let salt: [u8; 16] = random();
let config = Config::default();
let hashed_password = argon2::hash_encoded(password.as_bytes(), &salt, &config)
.map_err(|err| Error::EncryptionError(EncryptionErrorKind::HashError(err.to_string())))?;
.map_err(|err| new_err!(EncryptionError: HashError, err))?;
Ok((hashed_password, salt))
}

Expand Down
7 changes: 3 additions & 4 deletions src/core/data/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
use std::path::PathBuf;
use std::{env, fs};
use crate::{Error, Result};
use crate::core::error::OSErrorKind;
use crate::{new_err, Result};

/// Returns the application data directory based on the OS. Used for storing profiles and other
/// information for program's functionality which is not meant to be edited by the user
Expand Down Expand Up @@ -44,7 +43,7 @@ pub fn get_config_dir() -> Result<PathBuf> {
Ok(config_dir)
}

/// Returns the "Home" environment variable based on the OS for later file storage. For windows it
/// Returns the "Home" environment variable based on the OS for later file storage. For windows, it
/// is $APPDATA, for others it is $HOME
fn get_env_home() -> Result<PathBuf> {
let env = {
Expand All @@ -56,7 +55,7 @@ fn get_env_home() -> Result<PathBuf> {
};

let home_path = env::var(env)
.map_err(|_| Error::OSError(OSErrorKind::EnvVariableUnavailable(env.to_string())))?;
.map_err(|_| new_err!(OSError: EnvVariableUnavailable, env))?;

let config_dir = PathBuf::from(home_path);
Ok(config_dir)
Expand Down
11 changes: 5 additions & 6 deletions src/core/data/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
use super::auth;
use super::io::{read_file, write_file};
use crate::core::encryption::cipher;
use crate::{log_debug, log_info, Error, Key, Result};
use crate::core::error::ProfileErrorKind;
use crate::{log_debug, log_info, new_err, Key, Result};
use serde::{Deserialize, Serialize};
use std::io::{self};
use std::path::PathBuf;
Expand Down Expand Up @@ -77,7 +76,7 @@ impl LockboxProfiles {
let current_profile = self.current_profile.clone();

let profile = match current_profile {
None => return Err(Error::ProfileError(ProfileErrorKind::NotSelected)),
None => return Err(new_err!(ProfileError: NotSelected)),
Some(profile_name) => {
self.find_profile(&profile_name)?
}
Expand Down Expand Up @@ -123,7 +122,7 @@ impl LockboxProfiles {
}
}

Err(Error::ProfileError(ProfileErrorKind::NotFound(profile_name.to_string())))
Err(new_err!(ProfileError: NotFound, profile_name))
}

/// Saves provided profile data to profiles file. Updates existing profile or creates a new one,
Expand Down Expand Up @@ -162,7 +161,7 @@ impl LockboxProfiles {

let profile_name = profile.name.clone();
if self.find_profile(&profile_name).is_ok() {
return Err(Error::ProfileError(ProfileErrorKind::AlreadyExists(profile_name)));
return Err(new_err!(ProfileError: AlreadyExists, profile_name));
}
self.profiles.push(profile);

Expand All @@ -180,7 +179,7 @@ impl LockboxProfiles {
}
}

Err(Error::ProfileError(ProfileErrorKind::NotFound(profile_name.to_string())))
Err(new_err!(ProfileError: NotFound, profile_name))
}

/// Writes to the profile data file. Overwrites old data
Expand Down
7 changes: 3 additions & 4 deletions src/core/encryption/cipher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
use chacha20poly1305::{aead::{Aead, KeyInit}, AeadCore, ChaCha20Poly1305};
use rand::rngs::OsRng;
use crate::{Error, Key, Nonce, Result};
use crate::core::error::EncryptionErrorKind;
use crate::{new_err, Key, Nonce, Result};

/// Generates a new random 32-byte encryption key
pub fn generate_key() -> Key {
Expand All @@ -21,7 +20,7 @@ pub fn encrypt(key: &Key, nonce: &Nonce, data: &[u8]) -> Result<Vec<u8>> {
let cipher = ChaCha20Poly1305::new(key.into());

let ciphertext = cipher.encrypt(nonce.into(), data)
.map_err(|err| Error::EncryptionError(EncryptionErrorKind::DataEncryptionError(err.to_string())))?;
.map_err(|err| new_err!(EncryptionError: CipherError, err))?;
Ok(ciphertext)
}

Expand All @@ -32,6 +31,6 @@ pub fn decrypt(key: &Key, nonce: &Nonce, data: &[u8]) -> Result<Vec<u8>> {
let cipher = ChaCha20Poly1305::new(key.into());

let plaintext = cipher.decrypt(nonce.into(), data)
.map_err(|err| Error::EncryptionError(EncryptionErrorKind::DataDecryptionError(err.to_string())))?;
.map_err(|err| new_err!(EncryptionError: CipherError, err))?;
Ok(plaintext)
}
13 changes: 6 additions & 7 deletions src/core/encryption/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
use std::fs;
use std::path::{Path, PathBuf};
use crate::{log_warn, Error, Result};
use crate::{log_warn, new_err, Result};
use crate::core::data;
use crate::core::error::{InvalidDataErrorKind, ProfileErrorKind};
use crate::options;
use crate::log_debug;
use super::data::{io, keys};
Expand All @@ -21,12 +20,12 @@ pub fn encrypt(password: &str, input_path: &Path, opts: &mut options::Encryption
let profile = profiles.get_current_profile()?;

if !profile.verify_password(password) {
return Err(Error::ProfileError(ProfileErrorKind::AuthenticationFailed))
return Err(new_err!(ProfileError: AuthenticationFailed))
}

if let Some(extension) = input_path.extension() {
if extension == "box" {
return Err(Error::InvalidDataError(InvalidDataErrorKind::FileAlreadyEncrypted(input_path.file_name().unwrap().to_os_string())))
return Err(new_err!(InvalidData: FileAlreadyEncrypted, os input_path.file_name().unwrap()))
}
}

Expand Down Expand Up @@ -73,15 +72,15 @@ pub fn decrypt(password: &str, input_path: &Path, opts: &mut options::Decryption
let profile = profiles.get_current_profile()?;

if !profile.verify_password(password) {
return Err(Error::ProfileError(ProfileErrorKind::AuthenticationFailed))
return Err(new_err!(ProfileError: AuthenticationFailed))
}

if let Some(extension) = input_path.extension() {
if extension != "box" {
return Err(Error::InvalidDataError(InvalidDataErrorKind::FileNotEncrypted(input_path.file_name().unwrap().to_os_string())))
return Err(new_err!(InvalidData: FileNotSupported, os input_path.file_name().unwrap()))
}
} else {
return Err(Error::InvalidDataError(InvalidDataErrorKind::FileNotEncrypted(input_path.file_name().unwrap().to_os_string())))
return Err(new_err!(InvalidData: FileNotSupported, os input_path.file_name().unwrap()))
}

let mut path_buffer = PathBuf::from(input_path);
Expand Down
7 changes: 3 additions & 4 deletions src/core/file/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use crate::{Result, Error};
use crate::core::error::SerializeErrorKind;
use crate::{Result, new_err};
use super::{BoxFile, BoxHeader};

/// Reads the `.box` file at the provided file and returns parsed information
Expand All @@ -17,7 +16,7 @@ pub fn parse_file(path: &Path) -> Result<BoxFile> {
file.read(&mut buffer)?;

let box_file: BoxFile = bincode::deserialize(&buffer)
.map_err(|err| Error::SerializeError(SerializeErrorKind::BOXParseError(err.to_string())))?;
.map_err(|err| new_err!(SerializeError: BOXParseError, err))?;
Ok(box_file)
}

Expand All @@ -27,7 +26,7 @@ pub fn write_file(path: &Path, header: BoxHeader, body: Vec<u8>) -> Result<()> {

let box_file = BoxFile {header, body};
let box_data = bincode::serialize(&box_file)
.map_err(|err| Error::SerializeError(SerializeErrorKind::BOXParseError(err.to_string())))?;
.map_err(|err| new_err!(SerializeError: BOXParseError, err))?;

file.write_all(&box_data)?;

Expand Down
7 changes: 3 additions & 4 deletions src/core/utils/hex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Contains HEX manipulation functions for parsing custom types
use crate::{Result, Error, Key};
use crate::core::error::InvalidDataErrorKind;
use crate::{Result, Key, new_err};

/// Transforms `Key` type into HEX string
/// (e.g. \[1, 40, 174, 16, 5, ...\] into "0128AE1005...")
Expand All @@ -21,7 +20,7 @@ pub fn hex_string_to_key(hex: String) -> Result<Key> {
let safe_chars: &str = "0123456789ABCDEF";

if hex.len() != 64 {
return Err(Error::InvalidDataError(InvalidDataErrorKind::InvalidHexNumber("Invalid length".to_string())))
return Err(new_err!(InvalidData: InvalidHexNumber, "Invalid length"))
}

let mut i: usize = 0;
Expand All @@ -31,7 +30,7 @@ pub fn hex_string_to_key(hex: String) -> Result<Key> {
let c2: char = hex.chars().nth(i + 1).unwrap();

if !safe_chars.contains(c1) || !safe_chars.contains(c2) {
return Err(Error::InvalidDataError(InvalidDataErrorKind::InvalidHexNumber(format!("Invalid byte \"{}{}\"", c1, c2))))
return Err(new_err!(InvalidData: InvalidHexNumber, format!("Invalid byte \"{}{}\"", c1, c2)))
}

// we can just unwrap this too since we sanity-checked the characters beforehand
Expand Down
15 changes: 10 additions & 5 deletions tests/common/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ use std::path::PathBuf;
use super::PASSWORD;

fn base_command() -> Command {
if cfg!(target_os = "windows") {
Command::new("target/debug/lockbox.exe")
} else {
Command::new("target/debug/lockbox")
}
let mut executable_path = PathBuf::from("target/debug");
executable_path.push({
if cfg!(target_os = "windows") {
"lockbox.exe"
} else {
"lockbox"
}
});

Command::new(executable_path)
}

pub fn run_box(path: &PathBuf, extra_args: &[&str]) -> Output {
Expand Down
6 changes: 3 additions & 3 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ pub const TEST_DIR: &str = "files/test";
pub fn setup() {
lockbox::create_profile(PASSWORD, PROFILE_NAME)
.unwrap_or_else(|err| match err {
Error::ProfileError(_) => {},
Error::ProfileError(_) => println!("{}", err),
_ => panic!("Unable to create test profile: {}", err)
});

lockbox::select_profile(PASSWORD, PROFILE_NAME)
.unwrap_or_else(|err| match err {
Error::ProfileError(e) => println!("{}", e),
Error::ProfileError(_) => println!("{}", err),
_ => panic!("Unable to select test profile: {}", err)
});

Expand All @@ -33,7 +33,7 @@ pub fn setup() {
pub fn cleanup() {
lockbox::delete_profile(PASSWORD, PROFILE_NAME)
.unwrap_or_else(|err| match err {
Error::ProfileError(_) => {},
Error::ProfileError(_) => println!("{}", err),
_ => panic!("Unable to delete test profile: {}", err)
});

Expand Down

0 comments on commit e6796ff

Please sign in to comment.