use crate::utils::{
EmbedExt, TestResources, archive::for_each_entry_with_password, diff::assert_dirs_equal, setup,
};
use clap::Parser;
use portable_network_archive::cli;
use std::{fs, io::prelude::*, time};
const DURATION_24_HOURS: time::Duration = time::Duration::from_secs(24 * 60 * 60);
#[test]
fn update_encrypted_archive() {
setup();
let _ = fs::remove_dir_all("update_encrypted");
TestResources::extract_in("raw/", "update_encrypted/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted/archive.pna",
"--overwrite",
"update_encrypted/in/",
"--password",
"testpass",
"--aes",
"ctr",
])
.unwrap()
.execute()
.unwrap();
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted/in/raw/text.txt")
.unwrap();
file.write_all(b"updated content for encryption test")
.unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted/archive.pna",
"update_encrypted/in/",
"--password",
"testpass",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal("update_encrypted/in/", "update_encrypted/out/");
}
#[test]
fn update_encrypted_add_entry() {
setup();
let _ = fs::remove_dir_all("update_encrypted_add");
TestResources::extract_in("raw/", "update_encrypted_add/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_add/archive.pna",
"--overwrite",
"update_encrypted_add/in/",
"--password",
"testpass",
"--aes",
"ctr",
])
.unwrap()
.execute()
.unwrap();
fs::write(
"update_encrypted_add/in/raw/new_file.txt",
"new file content",
)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_add/archive.pna",
"update_encrypted_add/in/",
"--password",
"testpass",
])
.unwrap()
.execute()
.unwrap();
let mut found_new_file = false;
for_each_entry_with_password("update_encrypted_add/archive.pna", "testpass", |entry| {
if entry.header().path().as_str().ends_with("new_file.txt") {
found_new_file = true;
}
})
.unwrap();
assert!(found_new_file, "new_file.txt should be in the archive");
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_add/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_add/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal("update_encrypted_add/in/", "update_encrypted_add/out/");
}
#[test]
fn update_encrypted_keep_unchanged() {
setup();
let _ = fs::remove_dir_all("update_encrypted_keep");
TestResources::extract_in("raw/", "update_encrypted_keep/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_keep/archive.pna",
"--overwrite",
"update_encrypted_keep/in/",
"--password",
"testpass",
"--aes",
"ctr",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted_keep/in/raw/text.txt")
.unwrap();
file.write_all(b"modified text content").unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_keep/archive.pna",
"update_encrypted_keep/in/",
"--password",
"testpass",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_keep/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_keep/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal("update_encrypted_keep/in/", "update_encrypted_keep/out/");
}
#[test]
fn update_encrypted_aes_cbc() {
setup();
let _ = fs::remove_dir_all("update_encrypted_aes_cbc");
TestResources::extract_in("raw/", "update_encrypted_aes_cbc/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_aes_cbc/archive.pna",
"--overwrite",
"update_encrypted_aes_cbc/in/",
"--password",
"testpass",
"--aes",
"cbc",
])
.unwrap()
.execute()
.unwrap();
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted_aes_cbc/in/raw/text.txt")
.unwrap();
file.write_all(b"updated with aes-cbc").unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_aes_cbc/archive.pna",
"update_encrypted_aes_cbc/in/",
"--password",
"testpass",
"--aes",
"cbc",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_aes_cbc/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_aes_cbc/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal(
"update_encrypted_aes_cbc/in/",
"update_encrypted_aes_cbc/out/",
);
}
#[test]
fn update_encrypted_camellia_ctr() {
setup();
let _ = fs::remove_dir_all("update_encrypted_camellia");
TestResources::extract_in("raw/", "update_encrypted_camellia/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_camellia/archive.pna",
"--overwrite",
"update_encrypted_camellia/in/",
"--password",
"testpass",
"--camellia",
"ctr",
])
.unwrap()
.execute()
.unwrap();
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted_camellia/in/raw/text.txt")
.unwrap();
file.write_all(b"updated with camellia-ctr").unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_camellia/archive.pna",
"update_encrypted_camellia/in/",
"--password",
"testpass",
"--camellia",
"ctr",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_camellia/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_camellia/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal(
"update_encrypted_camellia/in/",
"update_encrypted_camellia/out/",
);
}
#[test]
fn update_encrypted_pbkdf2() {
setup();
let _ = fs::remove_dir_all("update_encrypted_pbkdf2");
TestResources::extract_in("raw/", "update_encrypted_pbkdf2/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_pbkdf2/archive.pna",
"--overwrite",
"update_encrypted_pbkdf2/in/",
"--password",
"testpass",
"--aes",
"ctr",
"--pbkdf2",
])
.unwrap()
.execute()
.unwrap();
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted_pbkdf2/in/raw/text.txt")
.unwrap();
file.write_all(b"updated with pbkdf2").unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_pbkdf2/archive.pna",
"update_encrypted_pbkdf2/in/",
"--password",
"testpass",
"--aes",
"ctr",
"--pbkdf2",
"--keep-timestamp",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_pbkdf2/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_pbkdf2/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
assert_dirs_equal(
"update_encrypted_pbkdf2/in/",
"update_encrypted_pbkdf2/out/",
);
}
#[test]
fn update_encrypted_content_verify() {
setup();
let _ = fs::remove_dir_all("update_encrypted_content");
TestResources::extract_in("raw/", "update_encrypted_content/in/").unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"c",
"update_encrypted_content/archive.pna",
"--overwrite",
"update_encrypted_content/in/",
"--password",
"testpass",
"--aes",
"ctr",
])
.unwrap()
.execute()
.unwrap();
let expected_content = b"SPECIFIC_CONTENT_FOR_VERIFICATION_12345";
let mut file = fs::File::options()
.write(true)
.truncate(true)
.open("update_encrypted_content/in/raw/text.txt")
.unwrap();
file.write_all(expected_content).unwrap();
file.set_modified(time::SystemTime::now() + DURATION_24_HOURS)
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"experimental",
"update",
"-f",
"update_encrypted_content/archive.pna",
"update_encrypted_content/in/",
"--password",
"testpass",
])
.unwrap()
.execute()
.unwrap();
cli::Cli::try_parse_from([
"pna",
"--quiet",
"x",
"update_encrypted_content/archive.pna",
"--overwrite",
"--out-dir",
"update_encrypted_content/out/",
"--password",
"testpass",
"--strip-components",
"2",
])
.unwrap()
.execute()
.unwrap();
let extracted_content = fs::read("update_encrypted_content/out/raw/text.txt").unwrap();
assert_eq!(
extracted_content.as_slice(),
expected_content,
"Extracted content should match the modified source"
);
}