Example #1
0
 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')
Example #2
0
 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')
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
 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)
Example #6
0
 def test_set_encoding(self):
     self.repo.set_encoding("cp1252")
     self.repo = RdiffRepo(self.temp_dir, 'testcases')
     self.assertEqual("cp1252", self.repo.get_encoding())
Example #7
0
 def test_init_with_invalid(self):
     with self.assertRaises(DoesNotExistError):
         RdiffRepo(self.temp_dir, '/invalid')
Example #8
0
 def test_init_with_absolute(self):
     self.repo = RdiffRepo(self.temp_dir, '/testcases')
     self.assertEqual('testcases', self.repo.display_name)
Example #9
0
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'))
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
 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)
Example #13
0
 def test_set_encoding(self):
     self.repo.set_encoding("cp1252")
     self.repo = RdiffRepo(self.temp_dir, 'testcases')
     self.assertEqual("cp1252", self.repo.get_encoding())
Example #14
0
 def test_init_with_absolute(self):
     self.repo = RdiffRepo(self.temp_dir, '/testcases')
     self.assertEqual('testcases', self.repo.display_name)
Example #15
0
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'))