mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-26 09:47:58 +00:00
serve: add --restrict-to-repository
This commit is contained in:
parent
c77b758e74
commit
07fbba4ee9
3 changed files with 28 additions and 2 deletions
|
@ -215,6 +215,7 @@ def do_serve(self, args):
|
|||
"""Start in server mode. This command is usually not used manually."""
|
||||
return RepositoryServer(
|
||||
restrict_to_paths=args.restrict_to_paths,
|
||||
restrict_to_repositories=args.restrict_to_repositories,
|
||||
append_only=args.append_only,
|
||||
storage_quota=args.storage_quota,
|
||||
).serve()
|
||||
|
@ -2339,6 +2340,14 @@ def define_common_options(add_common_option):
|
|||
metavar='PATH', help='restrict repository access to PATH. '
|
||||
'Can be specified multiple times to allow the client access to several directories. '
|
||||
'Access to all sub-directories is granted implicitly; PATH doesn\'t need to directly point to a repository.')
|
||||
subparser.add_argument('--restrict-to-repository', dest='restrict_to_repositories', action='append',
|
||||
metavar='PATH', help='restrict repository access. Only the repository located at PATH (no sub-directories are considered) '
|
||||
'is accessible. '
|
||||
'Can be specified multiple times to allow the client access to several repositories. '
|
||||
'Unlike --restrict-to-path sub-directories are not accessible; '
|
||||
'PATH needs to directly point at a repository location. '
|
||||
'PATH may be an empty directory or the last element of PATH may not exist, in which case '
|
||||
'the client may initialize a repository there.')
|
||||
subparser.add_argument('--append-only', dest='append_only', action='store_true',
|
||||
help='only allow appending to repository segment files')
|
||||
subparser.add_argument('--storage-quota', dest='storage_quota', default=None,
|
||||
|
|
|
@ -178,9 +178,10 @@ class RepositoryServer: # pragma: no cover
|
|||
'inject_exception',
|
||||
)
|
||||
|
||||
def __init__(self, restrict_to_paths, append_only, storage_quota):
|
||||
def __init__(self, restrict_to_paths, restrict_to_repositories, append_only, storage_quota):
|
||||
self.repository = None
|
||||
self.restrict_to_paths = restrict_to_paths
|
||||
self.restrict_to_repositories = restrict_to_repositories
|
||||
# This flag is parsed from the serve command line via Archiver.do_serve,
|
||||
# i.e. it reflects local system policy and generally ranks higher than
|
||||
# whatever the client wants, except when initializing a new repository
|
||||
|
@ -348,17 +349,24 @@ def open(self, path, create=False, lock_wait=None, lock=True, exclusive=None, ap
|
|||
logging.debug('Resolving repository path %r', path)
|
||||
path = self._resolve_path(path)
|
||||
logging.debug('Resolved repository path to %r', path)
|
||||
path_with_sep = os.path.join(path, '') # make sure there is a trailing slash (os.sep)
|
||||
if self.restrict_to_paths:
|
||||
# if --restrict-to-path P is given, we make sure that we only operate in/below path P.
|
||||
# for the prefix check, it is important that the compared pathes both have trailing slashes,
|
||||
# so that a path /foobar will NOT be accepted with --restrict-to-path /foo option.
|
||||
path_with_sep = os.path.join(path, '') # make sure there is a trailing slash (os.sep)
|
||||
for restrict_to_path in self.restrict_to_paths:
|
||||
restrict_to_path_with_sep = os.path.join(os.path.realpath(restrict_to_path), '') # trailing slash
|
||||
if path_with_sep.startswith(restrict_to_path_with_sep):
|
||||
break
|
||||
else:
|
||||
raise PathNotAllowed(path)
|
||||
if self.restrict_to_repositories:
|
||||
for restrict_to_repository in self.restrict_to_repositories:
|
||||
restrict_to_repository_with_sep = os.path.join(os.path.realpath(restrict_to_repository), '')
|
||||
if restrict_to_repository_with_sep == path_with_sep:
|
||||
break
|
||||
else:
|
||||
raise PathNotAllowed(path)
|
||||
# "borg init" on "borg serve --append-only" (=self.append_only) does not create an append only repo,
|
||||
# while "borg init --append-only" (=append_only) does, regardless of the --append-only (self.append_only)
|
||||
# flag for serve.
|
||||
|
|
|
@ -2861,6 +2861,15 @@ def test_remote_repo_restrict_to_path(self):
|
|||
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-path', '/foo', '--restrict-to-path', path_prefix]):
|
||||
self.cmd('init', '--encryption=repokey', self.repository_location + '_3')
|
||||
|
||||
def test_remote_repo_restrict_to_repository(self):
|
||||
# restricted to repo directory itself:
|
||||
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-repository', self.repository_path]):
|
||||
self.cmd('init', '--encryption=repokey', self.repository_location)
|
||||
parent_path = os.path.join(self.repository_path, '..')
|
||||
with patch.object(RemoteRepository, 'extra_test_args', ['--restrict-to-repository', parent_path]):
|
||||
with pytest.raises(PathNotAllowed):
|
||||
self.cmd('init', '--encryption=repokey', self.repository_location)
|
||||
|
||||
@unittest.skip('only works locally')
|
||||
def test_debug_put_get_delete_obj(self):
|
||||
pass
|
||||
|
|
Loading…
Reference in a new issue