Skip to content

Commit

Permalink
✨ Added warning when pushing sensitive files (#73)
Browse files Browse the repository at this point in the history
* ✨ Added warning when pushing sensitive files, now it throws a warning for every `.dot` file
  • Loading branch information
Mario-SO committed Jun 30, 2024
1 parent 5f0550b commit 53996ea
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/dependency_downloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub async fn download_dependencies(
}))
.await
.into_iter()
.collect::<Result<_, _>>()?;
.collect::<Result<Vec<()>, DownloadError>>()?;

Ok(())
}
Expand Down
60 changes: 55 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ use crate::lock::{
lock_check,
write_lock,
};
use crate::utils::get_current_working_dir;
use crate::utils::{
check_dotfiles_recursive,
get_current_working_dir,
prompt_user_for_confirmation,
};
use crate::versioning::push_version;
use config::{
add_to_config,
Expand Down Expand Up @@ -271,6 +275,17 @@ pub async fn run(command: Subcommands) -> Result<(), SoldeerError> {
}
}
Subcommands::Push(push) => {
let path = push
.path
.unwrap_or(get_current_working_dir().to_str().unwrap().to_string());
let path_buf = PathBuf::from(&path);

// Check for sensitive files or directories
if check_dotfiles_recursive(&path_buf) && !prompt_user_for_confirmation() {
println!("{}", Paint::yellow("Push operation aborted by the user."));
return Ok(());
}

if push.dry_run.is_some() && push.dry_run.unwrap() {
println!(
"{}",
Expand All @@ -283,9 +298,6 @@ pub async fn run(command: Subcommands) -> Result<(), SoldeerError> {
push.dependency.split('~').collect::<Vec<&str>>()[0].to_string();
let dependency_version: String =
push.dependency.split('~').collect::<Vec<&str>>()[1].to_string();
let path = push
.path
.unwrap_or(get_current_working_dir().to_str().unwrap().to_string());
let regex = Regex::new(r"^[@|a-z0-9][a-z0-9-]*[a-z0-9]$").unwrap();

if !regex.is_match(&dependency_name) {
Expand Down Expand Up @@ -596,7 +608,6 @@ libs = ["dependencies"]
let archive = File::open(&path_dependency);
let archive = ZipArchive::new(archive.unwrap());
assert_eq!(archive.unwrap().len(), 2);
let _ = remove_file(&path_dependency);
clean_test_env(PathBuf::default());
}

Expand Down Expand Up @@ -640,4 +651,43 @@ libs = ["dependencies"]
env::set_var("config_file", path.clone().to_str().unwrap());
path
}

#[test]
#[serial]
fn push_prompts_user_on_sensitive_files() {
let _ = remove_dir_all(DEPENDENCY_DIR.clone());
let _ = remove_file(LOCK_FILE.clone());
let test_dir = env::current_dir().unwrap().join("test_push_sensitive");

// Create test directory
if !test_dir.exists() {
std::fs::create_dir(&test_dir).unwrap();
}

// Create a .env file in the test directory
let env_file_path = test_dir.join(".env");
let mut env_file = File::create(&env_file_path).unwrap();
writeln!(env_file, "SENSITIVE_DATA=secret").unwrap();

let command = Subcommands::Push(Push {
dependency: "@test~1.1".to_string(),
path: Some(test_dir.to_str().unwrap().to_string()),
dry_run: None,
});

match run(command) {
Ok(_) => {}
Err(_) => {
clean_test_env(PathBuf::default());
assert_eq!("Invalid State", "")
}
}

// Check if the .env file exists
assert!(env_file_path.exists());

// Clean up
let _ = remove_file(&env_file_path);
let _ = remove_dir_all(&test_dir);
}
}
51 changes: 51 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,54 @@ pub fn get_base_url() -> String {
"https://api.soldeer.xyz".to_string()
}
}

// Function to check for the presence of sensitive files or directories
pub fn check_dotfiles(path: &Path) -> bool {
if let Ok(entries) = fs::read_dir(path) {
for entry in entries.flatten() {
let file_name = entry.file_name();
let file_name_str = file_name.to_string_lossy();
if file_name_str.starts_with('.') {
return true;
}
}
}
false
}

// Function to recursively check for sensitive files or directories in a given path
pub fn check_dotfiles_recursive(path: &Path) -> bool {
if check_dotfiles(path) {
return true;
}

if path.is_dir() {
for entry in fs::read_dir(path).unwrap() {
let entry = entry.unwrap();
let entry_path = entry.path();
if check_dotfiles_recursive(&entry_path) {
return true;
}
}
}

false
}

// Function to prompt the user for confirmation
pub fn prompt_user_for_confirmation() -> bool {
println!("{}", Paint::yellow(
"You are about to include some sensitive files in this version. Are you sure you want to continue?"
));
println!("{}", Paint::cyan(
"If you are not sure what sensitive files, you can run the dry-run command to check what will be pushed."
));

print!("{}", Paint::green("Do you want to continue? (y/n): "));
std::io::stdout().flush().unwrap();

let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let input = input.trim().to_lowercase();
input == "y" || input == "yes"
}
2 changes: 1 addition & 1 deletion src/versioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fn zip_file(
}

for file_path in files_to_copy {
let file = File::open(&file_path.path.clone()).unwrap();
let file = File::open(file_path.path.clone()).unwrap();
let file_name = file_path.name.clone();
let path = Path::new(&file_path.path);
let mut buffer = Vec::new();
Expand Down

0 comments on commit 53996ea

Please sign in to comment.