def setUp(self): # Extract 'testcases.tar.gz' testcases = pkg_resources.resource_filename( 'rdiffweb.tests', 'testcases.tar.gz') # @UndefinedVariable self.temp_dir = tempfile.mkdtemp(prefix='rdiffweb_tests_') tarfile.open(testcases).extractall(native_str(self.temp_dir)) # Define location of testcases self.testcases_dir = os.path.normpath( os.path.join(self.temp_dir, 'testcases')) self.testcases_dir = self.testcases_dir.encode('utf8') self.repo = RdiffRepo(self.temp_dir, b'testcases')
def setUp(self): # Extract 'testcases.tar.gz' testcases = pkg_resources.resource_filename('rdiffweb.tests', 'testcases.tar.gz') # @UndefinedVariable self.temp_dir = tempfile.mkdtemp(prefix='rdiffweb_tests_') tarfile.open(testcases).extractall(native_str(self.temp_dir)) # Define location of testcases self.testcases_dir = os.path.normpath(os.path.join(self.temp_dir, 'testcases')) self.testcases_dir = self.testcases_dir.encode('utf8') self.repo = RdiffRepo(self.temp_dir, b'testcases')
def validate_user_path(self, path_b): ''' Takes a path relative to the user's root dir and validates that it is valid and within the user's root. Uses bytes path to avoid any data lost in encoding/decoding. ''' assert isinstance(path_b, bytes) # Add a ending slash (/) to avoid matching wrong repo. Ref #56 path_b = normpath(path_b) # NOTE: a blank path is allowed, since the user root directory might be # a repository. logger.debug("checking user access to path %r", path_b) # Get reference to user repos (as bytes) user_repos = [ normpath(encodefilename(r)) for r in self.app.currentuser.repos ] # Check if any of the repos matches the given path. repo_b = next( (user_repo for user_repo in user_repos if path_b.startswith(user_repo)), None) if repo_b is None: # No repo matches logger.error("user doesn't have access to [%r]", path_b) raise DoesNotExistError(path_b) # Get reference to user_root user_root_b = encodefilename(self.app.currentuser.user_root) # Get reference to the repository (this ensure the repository does # exists and is valid.) repo_obj = RdiffRepo(user_root_b, repo_b) # Get reference to the path. path_b = path_b[len(repo_b):] path_obj = repo_obj.get_path(path_b) return (repo_obj, path_obj)
def validate_user_path(self, path_b): ''' Takes a path relative to the user's root dir and validates that it is valid and within the user's root. Uses bytes path to avoid any data lost in encoding/decoding. ''' assert isinstance(path_b, bytes) # Add a ending slash (/) to avoid matching wrong repo. Ref #56 path_b = normpath(path_b) # NOTE: a blank path is allowed, since the user root directory might be # a repository. logger.debug("checking user access to path %r", path_b) # Get reference to user repos (as bytes) user_repos = [ normpath(encodefilename(r)) for r in self.app.currentuser.repos] # Check if any of the repos matches the given path. repo_b = next(( user_repo for user_repo in user_repos if path_b.startswith(user_repo)), None) if repo_b is None: # No repo matches logger.error("user doesn't have access to [%r]", path_b) raise DoesNotExistError(path_b) # Get reference to user_root user_root_b = encodefilename(self.app.currentuser.user_root) # Get reference to the repository (this ensure the repository does # exists and is valid.) repo_obj = RdiffRepo(user_root_b, repo_b) # Get reference to the path. path_b = path_b[len(repo_b):] path_obj = repo_obj.get_path(path_b) return (repo_obj, path_obj)
def __init__(self): p = bytes(pkg_resources.resource_filename('rdiffweb', 'tests'), encoding='utf-8') # @UndefinedVariable RdiffRepo.__init__(self, os.path.dirname(p), os.path.basename(p)) self.root_path = MockDirEntry(self)
def test_set_encoding(self): self.repo.set_encoding("cp1252") self.repo = RdiffRepo(self.temp_dir, 'testcases') self.assertEqual("cp1252", self.repo.get_encoding())
def test_init_with_invalid(self): with self.assertRaises(DoesNotExistError): RdiffRepo(self.temp_dir, '/invalid')
def test_init_with_absolute(self): self.repo = RdiffRepo(self.temp_dir, '/testcases') self.assertEqual('testcases', self.repo.display_name)
class RdiffRepoTest(unittest.TestCase): def setUp(self): # Extract 'testcases.tar.gz' testcases = pkg_resources.resource_filename( 'rdiffweb.tests', 'testcases.tar.gz') # @UndefinedVariable self.temp_dir = tempfile.mkdtemp(prefix='rdiffweb_tests_') tarfile.open(testcases).extractall(native_str(self.temp_dir)) # Define location of testcases self.testcases_dir = os.path.normpath( os.path.join(self.temp_dir, 'testcases')) self.testcases_dir = self.testcases_dir.encode('utf8') self.repo = RdiffRepo(self.temp_dir, b'testcases') def tearDown(self): shutil.rmtree(self.temp_dir.encode('utf8'), True) def test_extract_date(self): self.assertEqual( RdiffTime(1414967021), self.repo._extract_date( b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz')) # Check if date with quoted characther are proerply parsed. # On NTFS, colon (:) are not supported. self.assertEqual( RdiffTime(1483443123), self.repo._extract_date( b'my_filename.txt.2017-01-03T06;05832;05803-05;05800.diff.gz')) def test_init(self): self.assertEqual('testcases', self.repo.display_name) def test_init_with_absolute(self): self.repo = RdiffRepo(self.temp_dir, '/testcases') self.assertEqual('testcases', self.repo.display_name) def test_init_with_invalid(self): with self.assertRaises(DoesNotExistError): RdiffRepo(self.temp_dir, '/invalid') def test_get_path_root(self): dir_entry = self.repo.get_path(b"/") self.assertEqual('', dir_entry.display_name) self.assertEqual(b'', dir_entry.path) self.assertEqual(self.testcases_dir, dir_entry.full_path) self.assertEqual(True, dir_entry.isdir) self.assertTrue(len(dir_entry.dir_entries) > 0) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_subdirectory(self): dir_entry = self.repo.get_path(b"Subdirectory") self.assertEqual('Subdirectory', dir_entry.display_name) self.assertEqual(b'Subdirectory', dir_entry.path) self.assertEqual(os.path.join(self.testcases_dir, b'Subdirectory'), dir_entry.full_path) self.assertEqual(True, dir_entry.isdir) self.assertTrue(len(dir_entry.dir_entries) > 0) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_subfile(self): dir_entry = self.repo.get_path(b"Revisions/Data") self.assertEqual('Data', dir_entry.display_name) self.assertEqual(b'Revisions/Data', dir_entry.path) self.assertEqual(os.path.join(self.testcases_dir, b'Revisions/Data'), dir_entry.full_path) self.assertEqual(False, dir_entry.isdir) self.assertEqual([], dir_entry.dir_entries) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_rdiff_backup_data(self): with self.assertRaises(AccessDeniedError): self.repo.get_path(b'rdiff-backup-data') def test_get_path_invalid(self): with self.assertRaises(DoesNotExistError): self.repo.get_path(b'invalide') def test_get_path_broken_symlink(self): with self.assertRaises(DoesNotExistError): self.repo.get_path(b'BrokenSymlink') def test_status(self): status = self.repo.status self.assertEqual('ok', status[0]) self.assertEqual('', status[1]) def test_restore_file(self): filename, stream = self.repo.restore(b"Revisions/Data", restore_date=1454448640, kind='zip') self.assertEqual('Data', filename) data = stream.read() self.assertEqual(b'Version3\n', data) def test_restore_direntry(self): entry = self.repo.get_path(b"Revisions/Data") filename, stream = self.repo.restore(entry, restore_date=1454448640, kind='zip') self.assertEqual('Data', filename) data = stream.read() self.assertEqual(b'Version3\n', data) def test_restore_subdirectory(self): filename, stream = self.repo.restore(b"Revisions/", restore_date=1454448640, kind='zip') self.assertEqual('Revisions.zip', filename) data = stream.read() self.assertTrue(data) def test_restore_root(self): filename, stream = self.repo.restore(b"/", restore_date=1454448640, kind='zip') self.assertEqual('testcases.zip', filename) data = stream.read() self.assertTrue(data) def test_set_encoding(self): self.repo.set_encoding("cp1252") self.repo = RdiffRepo(self.temp_dir, 'testcases') self.assertEqual("cp1252", self.repo.get_encoding()) def test_unquote(self): self.assertEqual(b'Char ;090 to quote', self.repo.unquote(b'Char ;059090 to quote'))
def validate_user_path(self, path_b): ''' Takes a path relative to the user's root dir and validates that it is valid and within the user's root. Uses bytes path to avoid any data lost in encoding/decoding. ''' assert isinstance(path_b, bytes) # Add a ending slash (/) to avoid matching wrong repo. Ref #56 path_b = normpath(path_b) # NOTE: a blank path is allowed, since the user root directory might be # a repository. logger.debug("checking user access to path %r", path_b) # Get reference to user repos (as bytes) user_repos = [ normpath(encodefilename(r)) for r in self.app.currentuser.repos ] # Check if any of the repos matches the given path. repo_b = next( (user_repo for user_repo in user_repos if path_b.startswith(user_repo)), None) if repo_b is None: # No repo matches logger.error("user doesn't have access to [%r]", path_b) raise cherrypy.HTTPError(404) # Get reference to user_root user_root_b = encodefilename(self.app.currentuser.user_root) # Check path vs real path value full_path_b = os.path.join(user_root_b, path_b.lstrip(b'/')).rstrip(b"/") real_path_b = os.path.realpath(full_path_b).rstrip(b"/") if full_path_b != real_path_b: # We can safely assume the realpath contains a symbolic link. If # the symbolic link is valid, we display the content of the "real" # path. if real_path_b.startswith(os.path.join(user_root_b, repo_b)): path_b = os.path.relpath(real_path_b, user_root_b) else: logger.warning("access is denied [%r] vs [%r]", full_path_b, real_path_b) raise cherrypy.HTTPError(404) try: # Get reference to the repository (this ensure the repository does # exists and is valid.) repo_obj = RdiffRepo(user_root_b, repo_b) # Get reference to the path. path_b = path_b[len(repo_b):] path_obj = repo_obj.get_path(path_b) return (repo_obj, path_obj) except AccessDeniedError as e: logger.warning("access is denied", exc_info=1) raise cherrypy.HTTPError(404) except DoesNotExistError as e: logger.warning("doesn't exists", exc_info=1) raise cherrypy.HTTPError(404)
def validate_user_path(self, path_b): ''' Takes a path relative to the user's root dir and validates that it is valid and within the user's root. Uses bytes path to avoid any data lost in encoding/decoding. ''' assert isinstance(path_b, bytes) # Add a ending slash (/) to avoid matching wrong repo. Ref #56 path_b = normpath(path_b) # NOTE: a blank path is allowed, since the user root directory might be # a repository. logger.debug("checking user access to path %r", path_b) # Get reference to user repos (as bytes) user_repos = [ normpath(encodefilename(r)) for r in self.app.currentuser.repos] # Check if any of the repos matches the given path. repo_b = next(( user_repo for user_repo in user_repos if path_b.startswith(user_repo)), None) if repo_b is None: # No repo matches logger.error("user doesn't have access to [%r]", path_b) raise cherrypy.HTTPError(404) # Get reference to user_root user_root_b = encodefilename(self.app.currentuser.user_root) # Check path vs real path value full_path_b = os.path.join(user_root_b, path_b.lstrip(b'/')).rstrip(b"/") real_path_b = os.path.realpath(full_path_b).rstrip(b"/") if full_path_b != real_path_b: # We can safely assume the realpath contains a symbolic link. If # the symbolic link is valid, we display the content of the "real" # path. if real_path_b.startswith(os.path.join(user_root_b, repo_b)): path_b = os.path.relpath(real_path_b, user_root_b) else: logger.warning("access is denied [%r] vs [%r]", full_path_b, real_path_b) raise cherrypy.HTTPError(404) try: # Get reference to the repository (this ensure the repository does # exists and is valid.) repo_obj = RdiffRepo(user_root_b, repo_b) # Get reference to the path. path_b = path_b[len(repo_b):] path_obj = repo_obj.get_path(path_b) return (repo_obj, path_obj) except AccessDeniedError as e: logger.warning("access is denied", exc_info=1) raise cherrypy.HTTPError(404) except DoesNotExistError as e: logger.warning("doesn't exists", exc_info=1) raise cherrypy.HTTPError(404)
class RdiffRepoTest(unittest.TestCase): def setUp(self): # Extract 'testcases.tar.gz' testcases = pkg_resources.resource_filename('rdiffweb.tests', 'testcases.tar.gz') # @UndefinedVariable self.temp_dir = tempfile.mkdtemp(prefix='rdiffweb_tests_') tarfile.open(testcases).extractall(native_str(self.temp_dir)) # Define location of testcases self.testcases_dir = os.path.normpath(os.path.join(self.temp_dir, 'testcases')) self.testcases_dir = self.testcases_dir.encode('utf8') self.repo = RdiffRepo(self.temp_dir, b'testcases') def tearDown(self): shutil.rmtree(self.temp_dir.encode('utf8'), True) def test_extract_date(self): self.assertEqual(RdiffTime(1414967021), self.repo._extract_date(b'my_filename.txt.2014-11-02T17:23:41-05:00.diff.gz')) # Check if date with quoted characther are proerply parsed. # On NTFS, colon (:) are not supported. self.assertEqual(RdiffTime(1483443123), self.repo._extract_date(b'my_filename.txt.2017-01-03T06;05832;05803-05;05800.diff.gz')) def test_init(self): self.assertEqual('testcases', self.repo.display_name) def test_init_with_absolute(self): self.repo = RdiffRepo(self.temp_dir, '/testcases') self.assertEqual('testcases', self.repo.display_name) def test_init_with_invalid(self): with self.assertRaises(DoesNotExistError): RdiffRepo(self.temp_dir, '/invalid') def test_get_path_root(self): dir_entry = self.repo.get_path(b"/") self.assertEqual('', dir_entry.display_name) self.assertEqual(b'', dir_entry.path) self.assertEqual(self.testcases_dir, dir_entry.full_path) self.assertEqual(True, dir_entry.isdir) self.assertTrue(len(dir_entry.dir_entries) > 0) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_subdirectory(self): dir_entry = self.repo.get_path(b"Subdirectory") self.assertEqual('Subdirectory', dir_entry.display_name) self.assertEqual(b'Subdirectory', dir_entry.path) self.assertEqual(os.path.join(self.testcases_dir, b'Subdirectory'), dir_entry.full_path) self.assertEqual(True, dir_entry.isdir) self.assertTrue(len(dir_entry.dir_entries) > 0) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_subfile(self): dir_entry = self.repo.get_path(b"Revisions/Data") self.assertEqual('Data', dir_entry.display_name) self.assertEqual(b'Revisions/Data', dir_entry.path) self.assertEqual(os.path.join(self.testcases_dir, b'Revisions/Data'), dir_entry.full_path) self.assertEqual(False, dir_entry.isdir) self.assertEqual([], dir_entry.dir_entries) self.assertTrue(len(dir_entry.change_dates) > 1) def test_get_path_rdiff_backup_data(self): with self.assertRaises(AccessDeniedError): self.repo.get_path(b'rdiff-backup-data') def test_get_path_invalid(self): with self.assertRaises(DoesNotExistError): self.repo.get_path(b'invalide') def test_get_path_broken_symlink(self): with self.assertRaises(DoesNotExistError): self.repo.get_path(b'BrokenSymlink') def test_status(self): status = self.repo.status self.assertEqual('ok', status[0]) self.assertEqual('', status[1]) def test_restore_file(self): filename, stream = self.repo.restore(b"Revisions/Data", restore_date=1454448640, kind='zip') self.assertEqual('Data', filename) data = stream.read() self.assertEqual(b'Version3\n', data) def test_restore_direntry(self): entry = self.repo.get_path(b"Revisions/Data") filename, stream = self.repo.restore(entry, restore_date=1454448640, kind='zip') self.assertEqual('Data', filename) data = stream.read() self.assertEqual(b'Version3\n', data) def test_restore_subdirectory(self): filename, stream = self.repo.restore(b"Revisions/", restore_date=1454448640, kind='zip') self.assertEqual('Revisions.zip', filename) data = stream.read() self.assertTrue(data) def test_restore_root(self): filename, stream = self.repo.restore(b"/", restore_date=1454448640, kind='zip') self.assertEqual('testcases.zip', filename) data = stream.read() self.assertTrue(data) def test_set_encoding(self): self.repo.set_encoding("cp1252") self.repo = RdiffRepo(self.temp_dir, 'testcases') self.assertEqual("cp1252", self.repo.get_encoding()) def test_unquote(self): self.assertEqual(b'Char ;090 to quote', self.repo.unquote(b'Char ;059090 to quote'))