From 45718aee39328634e1b929f85a430eb07b35ee1e Mon Sep 17 00:00:00 2001 From: Jenna Elwing Date: Wed, 27 Mar 2024 12:15:23 -0400 Subject: [PATCH] fixed epect error handling, set permissions in add --- src/cmd/add_cmd.rs | 7 ++-- src/internal/config/config.rs | 4 ++- src/internal/git/ignore.rs | 2 +- src/internal/meta/file.rs | 1 - src/internal/storage/add.rs | 63 ++++++++++++++++++++++++----------- src/internal/storage/copy.rs | 9 +---- src/internal/storage/init.rs | 2 +- 7 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/cmd/add_cmd.rs b/src/cmd/add_cmd.rs index df0f2d5..9191707 100644 --- a/src/cmd/add_cmd.rs +++ b/src/cmd/add_cmd.rs @@ -17,7 +17,10 @@ pub fn run_add_cmd(files: &Vec, message: &String) -> Result<(), std::io }; // load the config - let conf = config::read(&git_dir).expect("could not open yaml"); + let conf = match config::read(&git_dir) { + Ok(config) => config, + Err(_) => return Err(std::io::Error::other("config not readable")), + }; let mut queued_paths: Vec = Vec::new(); @@ -54,7 +57,7 @@ pub fn run_add_cmd(files: &Vec, message: &String) -> Result<(), std::io // add each file in queued_paths to storage for file in &queued_paths { - match add::add(file, &conf.storage_dir, &git_dir, &message) { + match add::add(file, &conf, &git_dir, &message) { Ok(_) => {} Err(e) => return Err(e), }; diff --git a/src/internal/config/config.rs b/src/internal/config/config.rs index 4558dff..b7510a8 100644 --- a/src/internal/config/config.rs +++ b/src/internal/config/config.rs @@ -4,7 +4,9 @@ use std::path::PathBuf; #[derive(Serialize, Deserialize, PartialEq, Debug)] pub struct Config { - pub storage_dir: PathBuf + pub storage_dir: PathBuf, + pub permissions: u32, + pub group: String } pub fn read(root_dir: &PathBuf) -> Result { diff --git a/src/internal/git/ignore.rs b/src/internal/git/ignore.rs index aef16f7..8621193 100644 --- a/src/internal/git/ignore.rs +++ b/src/internal/git/ignore.rs @@ -15,7 +15,7 @@ pub fn add_gitignore_entry(git_dir: &PathBuf, path: &PathBuf) -> Result<(), std: // open the gitignore file, creating one if it doesn't exist let ignore_file = git_dir.join(".gitignore"); if !ignore_file.exists() { - File::create(&ignore_file).expect("gitignore cannot be created"); + File::create(&ignore_file)?; } let contents = std::fs::read_to_string(&ignore_file).unwrap(); if !contents.contains(&ignore_entry) { diff --git a/src/internal/meta/file.rs b/src/internal/meta/file.rs index 58e1b00..bc17b34 100644 --- a/src/internal/meta/file.rs +++ b/src/internal/meta/file.rs @@ -11,7 +11,6 @@ pub struct Metadata { pub file_size: u64, pub time_stamp: SystemTime, pub message: String, - pub group: String, pub saved_by: String } diff --git a/src/internal/storage/add.rs b/src/internal/storage/add.rs index 1966b08..b1e7500 100644 --- a/src/internal/storage/add.rs +++ b/src/internal/storage/add.rs @@ -1,15 +1,17 @@ +use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; -use std::path::Path; use std::time::SystemTime; -use file_owner::PathExt; +use file_owner::{Group, PathExt}; +use std::fs::{self, Permissions}; +use crate::internal::config::config::Config; use crate::internal::file::hash; use crate::internal::storage::copy; use crate::internal::meta::file; use crate::internal::git::ignore; -pub fn add(local_path: &PathBuf, storage_dir: &PathBuf, git_dir: &PathBuf, message: &String) -> Result { +pub fn add(local_path: &PathBuf, conf: &Config, git_dir: &PathBuf, message: &String) -> Result { // get file hash let file_hash = match hash::hash_file_with_blake3(local_path) { Ok(file_hash) => { @@ -23,7 +25,11 @@ pub fn add(local_path: &PathBuf, storage_dir: &PathBuf, git_dir: &PathBuf, messa }; // get storage path - let dest_path = hash::get_storage_path(&storage_dir, &file_hash); + let storage_dir_abs = match conf.storage_dir.canonicalize() { + Ok(path) => path, + Err(e) => return Err(e), + }; + let dest_path = hash::get_storage_path(&storage_dir_abs, &file_hash); // Copy the file to the storage directory // if the destination already exists, skip copying @@ -31,6 +37,7 @@ pub fn add(local_path: &PathBuf, storage_dir: &PathBuf, git_dir: &PathBuf, messa // copy match copy::copy(&local_path, &dest_path) { Ok(_) => { + // json } Err(e) => { @@ -44,6 +51,33 @@ pub fn add(local_path: &PathBuf, storage_dir: &PathBuf, git_dir: &PathBuf, messa // json } + // set permissions + let mode = conf.permissions; + let permissions: Permissions = fs::Permissions::from_mode(mode); + match fs::set_permissions(&dest_path, permissions) { + Ok(_) => { + // json: success + }, + Err(e) => { + // json: fail + return Err(e) + } + }; + + // set group ownership + let group_name = conf.group.as_str(); + let group = match Group::from_name(group_name) { + Ok(group) => { + // json + group + } + Err(_) => return Err(std::io::Error::other("group name is invalid")) + }; + match dest_path.set_group(group) { + Ok(_) => {}, + Err(_) => return Err(std::io::Error::other("group name is invalid")) + }; + // get file size let local_path_data = match local_path.metadata() { Ok(data) => data, @@ -51,45 +85,34 @@ pub fn add(local_path: &PathBuf, storage_dir: &PathBuf, git_dir: &PathBuf, messa }; let file_size = local_path_data.len(); - // get user + // get user name let owner = match local_path.owner() { Ok(owner) => owner, Err(_) => return Err(std::io::Error::other("file owner not found")), }; - // get user name let owner_name = match owner.name() { Ok(name) => name.unwrap(), Err(_) => {return Err(std::io::Error::other("file owner not found"))}, }; - // get group - let group = match local_path.group() { - Ok(group) => group, - Err(_) => return Err(std::io::Error::other("file group not found")), - }; - // get group name - let group_name = match group.name() { - Ok(name) => name.unwrap(), - Err(_) => {return Err(std::io::Error::other("file group not found"))}, - }; - // create + write metadata file let metadata = file::Metadata{ file_hash: file_hash.clone(), file_size, time_stamp: SystemTime::now(), message: message.clone(), - group: group_name, saved_by: owner_name }; - match file::save(&metadata, &local_path) { Ok(_) => {}, Err(_) => return Err(std::io::Error::other("metadata file not created")) }; // Add file to gitignore - ignore::add_gitignore_entry(git_dir, local_path).expect("gitignore entry unable to be added"); + match ignore::add_gitignore_entry(git_dir, local_path) { + Ok(_) => {}, + Err(_) => return Err(std::io::Error::other("gitignore entry could not be created")) + }; return Ok(file_hash); } \ No newline at end of file diff --git a/src/internal/storage/copy.rs b/src/internal/storage/copy.rs index 9a55540..86ff041 100644 --- a/src/internal/storage/copy.rs +++ b/src/internal/storage/copy.rs @@ -1,8 +1,6 @@ use std::path::PathBuf; use std::fs::{create_dir_all, File}; -use std::os::unix::fs::PermissionsExt; use std::fs; -use std::fs::Permissions; pub fn copy(src_path: &PathBuf, dest_path: &PathBuf) -> Result<(), std::io::Error> { // Ignore .. and . paths @@ -41,13 +39,8 @@ pub fn copy(src_path: &PathBuf, dest_path: &PathBuf) -> Result<(), std::io::Erro Err(e) => return Err(e), }; - // Set destination file permissions - let mode: u32 = 0o664; - let permissions: Permissions = fs::Permissions::from_mode(mode); - fs::set_permissions(dest_path, permissions).expect("file unable to be copied, permissions denied"); - // Copy the file - fs::copy(src_path, dest_path).expect("file unable to be copied"); + fs::copy(src_path, dest_path)?; Ok(()) } \ No newline at end of file diff --git a/src/internal/storage/init.rs b/src/internal/storage/init.rs index 64b7725..bd637e7 100644 --- a/src/internal/storage/init.rs +++ b/src/internal/storage/init.rs @@ -79,7 +79,7 @@ pub fn init(root_dir: &PathBuf, storage_dir: &PathBuf, mode: &u32, group_name: & }; // write config - match config::write(&Config{storage_dir: storage_dir_abs.clone()}, &root_dir) { + match config::write(&Config{storage_dir: storage_dir_abs.clone(), permissions: mode.clone(), group: group_name.clone()}, &root_dir) { Ok(_) => { // json }