Prevent source being within repository

This commit is contained in:
Cyryl Płotnicki 2019-09-07 15:08:47 +01:00
parent 66391862c1
commit a0bea5ef3e
4 changed files with 30 additions and 5 deletions

View file

@ -11,8 +11,11 @@ pub struct Engine<'a> {
} }
impl<'a> Engine<'a> { impl<'a> Engine<'a> {
pub fn new(source_path: &'a Path, repository: &'a mut Repository<'a>) -> Self { pub fn new(source_path: &'a Path, repository: &'a mut Repository<'a>) -> Result<Self, BakareError> {
Engine { source_path, repository } if source_path.ancestors().any(|a| a == repository.path()) {
return Err(BakareError::SourceSameAsRepository);
}
Ok(Engine { source_path, repository })
} }
pub fn backup(&mut self) -> Result<(), BakareError> { pub fn backup(&mut self) -> Result<(), BakareError> {

View file

@ -76,6 +76,10 @@ impl<'a> Repository<'a> {
} }
} }
pub fn path(&self) -> &Path {
&self.path
}
pub fn store(&mut self, source_path: &Path) -> Result<(), BakareError> { pub fn store(&mut self, source_path: &Path) -> Result<(), BakareError> {
if !source_path.is_absolute() { if !source_path.is_absolute() {
return Err(BakareError::PathToStoreNotAbsolute); return Err(BakareError::PathToStoreNotAbsolute);

View file

@ -6,10 +6,10 @@ use std::path::Path;
use tempfile::tempdir; use tempfile::tempdir;
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::{backup, restore};
use crate::error::BakareError; use crate::error::BakareError;
use crate::repository::{ItemVersion, Repository}; use crate::repository::{ItemVersion, Repository};
use crate::source::TempSource; use crate::source::TempSource;
use crate::{backup, restore};
pub fn assert_target_file_contents(restored_path: &Path, expected_contents: &str) -> Result<(), BakareError> { pub fn assert_target_file_contents(restored_path: &Path, expected_contents: &str) -> Result<(), BakareError> {
let mut actual_contents = String::new(); let mut actual_contents = String::new();
@ -29,7 +29,7 @@ pub fn assert_same_after_restore(source_path: &Path) -> Result<(), BakareError>
Repository::init(repository_path.as_path())?; Repository::init(repository_path.as_path())?;
{ {
let mut backup_repository = Repository::open(repository_path.as_path())?; let mut backup_repository = Repository::open(repository_path.as_path())?;
let mut backup_engine = backup::Engine::new(source_path, &mut backup_repository); let mut backup_engine = backup::Engine::new(source_path, &mut backup_repository)?;
backup_engine.backup()?; backup_engine.backup()?;
} }
{ {
@ -96,7 +96,7 @@ pub fn backup_file_with_contents(
) -> Result<(), BakareError> { ) -> Result<(), BakareError> {
{ {
let mut backup_repository = Repository::open(repository_path)?; let mut backup_repository = Repository::open(repository_path)?;
let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository); let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository)?;
source.write_text_to_file(source_file_relative_path, contents)?; source.write_text_to_file(source_file_relative_path, contents)?;
backup_engine.backup()?; backup_engine.backup()?;
Ok(()) Ok(())

View file

@ -1,5 +1,6 @@
use tempfile::tempdir; use tempfile::tempdir;
use bakare::backup;
use bakare::error::BakareError; use bakare::error::BakareError;
use bakare::repository::Repository; use bakare::repository::Repository;
use bakare::source::TempSource; use bakare::source::TempSource;
@ -56,6 +57,23 @@ fn restore_older_version_of_file() -> Result<(), BakareError> {
assert_restored_from_version_has_contents(&repository_path, &source_file_full_path, old_contents, &old_version) assert_restored_from_version_has_contents(&repository_path, &source_file_full_path, old_contents, &old_version)
} }
#[test]
fn forbid_backup_of_paths_within_repository() -> Result<(), BakareError> {
let repository_path = &tempdir()?.into_path();
Repository::init(repository_path)?;
let mut repository = Repository::open(repository_path)?;
if let Err(e) = backup::Engine::new(repository_path, &mut repository) {
let correct_error = match e {
BakareError::SourceSameAsRepository => true,
_ => false,
};
assert!(correct_error);
} else {
panic!("Expected error");
}
Ok(())
}
// TODO: restore latest version by default // TODO: restore latest version by default
// TODO: deduplicate data // TODO: deduplicate data
// TODO: test that index is stored separately from data // TODO: test that index is stored separately from data