mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-12 19:50:57 +05:00
192 lines
6.4 KiB
Python
192 lines
6.4 KiB
Python
from pathlib import Path
|
|
|
|
from archivebox.config.permissions import (
|
|
is_root_identity,
|
|
root_parent_can_grant_group_traversal,
|
|
root_should_handoff_data_dir,
|
|
select_archivebox_user,
|
|
)
|
|
|
|
|
|
def test_root_identity_includes_real_or_effective_root():
|
|
assert is_root_identity(0, 0)
|
|
assert is_root_identity(0, 911)
|
|
assert is_root_identity(1000, 0)
|
|
assert not is_root_identity(1000, 1000)
|
|
|
|
|
|
def test_root_uses_archivebox_account_for_root_owned_data_dir():
|
|
assert select_archivebox_user(
|
|
running_uid=0,
|
|
running_gid=0,
|
|
effective_uid=0,
|
|
effective_gid=0,
|
|
sudo_uid=0,
|
|
sudo_gid=0,
|
|
data_dir_uid=0,
|
|
data_dir_gid=0,
|
|
account_uid=911,
|
|
account_gid=911,
|
|
) == (911, 911)
|
|
|
|
|
|
def test_root_preserves_existing_non_root_data_dir_owner():
|
|
assert select_archivebox_user(
|
|
running_uid=0,
|
|
running_gid=0,
|
|
effective_uid=0,
|
|
effective_gid=0,
|
|
sudo_uid=0,
|
|
sudo_gid=0,
|
|
data_dir_uid=1001,
|
|
data_dir_gid=1002,
|
|
account_uid=911,
|
|
account_gid=911,
|
|
) == (1001, 1002)
|
|
|
|
|
|
def test_root_uses_owner_primary_group_for_mixed_user_root_data_dir():
|
|
assert select_archivebox_user(
|
|
running_uid=0,
|
|
running_gid=0,
|
|
effective_uid=0,
|
|
effective_gid=0,
|
|
sudo_uid=1001,
|
|
sudo_gid=1002,
|
|
data_dir_uid=1001,
|
|
data_dir_gid=0,
|
|
data_dir_owner_gid=1002,
|
|
account_uid=911,
|
|
account_gid=911,
|
|
) == (1001, 1002)
|
|
|
|
|
|
def test_root_uses_archivebox_account_for_unknown_data_dir_owner():
|
|
assert select_archivebox_user(
|
|
running_uid=0,
|
|
running_gid=0,
|
|
effective_uid=0,
|
|
effective_gid=0,
|
|
sudo_uid=0,
|
|
sudo_gid=0,
|
|
data_dir_uid=502,
|
|
data_dir_gid=20,
|
|
account_uid=911,
|
|
account_gid=911,
|
|
data_dir_owner_exists=False,
|
|
) == (911, 911)
|
|
|
|
|
|
def test_non_root_uses_current_effective_identity():
|
|
assert select_archivebox_user(
|
|
running_uid=501,
|
|
running_gid=20,
|
|
effective_uid=501,
|
|
effective_gid=20,
|
|
sudo_uid=0,
|
|
sudo_gid=0,
|
|
data_dir_uid=0,
|
|
data_dir_gid=0,
|
|
account_uid=None,
|
|
account_gid=None,
|
|
) == (501, 20)
|
|
|
|
|
|
def test_effective_root_drops_back_to_real_user():
|
|
assert select_archivebox_user(
|
|
running_uid=1001,
|
|
running_gid=1002,
|
|
effective_uid=0,
|
|
effective_gid=0,
|
|
sudo_uid=0,
|
|
sudo_gid=0,
|
|
data_dir_uid=0,
|
|
data_dir_gid=0,
|
|
account_uid=None,
|
|
account_gid=None,
|
|
) == (1001, 1002)
|
|
|
|
|
|
def test_root_hands_off_root_or_archivebox_owned_collection_boundaries():
|
|
assert root_should_handoff_data_dir(is_root=True, data_dir_uid=0, account_uid=911)
|
|
assert root_should_handoff_data_dir(is_root=True, data_dir_uid=911, account_uid=911)
|
|
assert not root_should_handoff_data_dir(is_root=True, data_dir_uid=1001, account_uid=911)
|
|
assert not root_should_handoff_data_dir(is_root=False, data_dir_uid=911, account_uid=911)
|
|
assert not root_should_handoff_data_dir(is_root=True, data_dir_uid=911, account_uid=None)
|
|
assert root_should_handoff_data_dir(
|
|
is_root=True,
|
|
data_dir_uid=502,
|
|
account_uid=911,
|
|
data_dir_owner_exists=False,
|
|
)
|
|
|
|
|
|
def test_root_setup_commands_hand_off_only_an_empty_data_dir(tmp_path):
|
|
from archivebox.config.permissions import root_data_dir_handoff_paths
|
|
|
|
setup_commands = (
|
|
["archivebox", "init"],
|
|
["archivebox", "install"],
|
|
["archivebox", "server", "--init"],
|
|
["archivebox", "server", "--quick-init"],
|
|
["archivebox", "add", "--init", "https://example.com"],
|
|
)
|
|
for argv in setup_commands:
|
|
assert root_data_dir_handoff_paths(tmp_path, argv) == (tmp_path,)
|
|
|
|
unrelated = tmp_path / "unrelated.txt"
|
|
unrelated.write_text("keep root ownership")
|
|
for argv in setup_commands:
|
|
assert root_data_dir_handoff_paths(tmp_path, argv) == ()
|
|
|
|
|
|
def test_existing_collection_handoff_is_bounded_to_known_top_level_paths(tmp_path):
|
|
from archivebox.config.permissions import root_data_dir_handoff_paths
|
|
|
|
database = tmp_path / "index.sqlite3"
|
|
archive = tmp_path / "archive"
|
|
custom_plugins = tmp_path / "custom_plugins"
|
|
custom_templates = tmp_path / "custom_templates"
|
|
nested = archive / "large-existing-snapshot"
|
|
errors_log = tmp_path / "logs" / "errors.log"
|
|
database.touch()
|
|
nested.mkdir(parents=True)
|
|
custom_plugins.mkdir()
|
|
custom_templates.mkdir()
|
|
errors_log.parent.mkdir()
|
|
errors_log.touch()
|
|
|
|
paths = root_data_dir_handoff_paths(tmp_path, ["archivebox", "status"])
|
|
|
|
assert paths == (tmp_path, database, archive, custom_plugins, custom_templates, errors_log.parent, errors_log)
|
|
assert nested not in paths
|
|
assert all(path == tmp_path or path.parent in (tmp_path, errors_log.parent) for path in paths)
|
|
|
|
|
|
def test_permission_repairs_avoid_recursive_collection_and_abxpkg_chown():
|
|
from archivebox.misc import checks
|
|
|
|
assert "chown -R" not in Path(checks.__file__).read_text(encoding="utf-8")
|
|
entrypoint = (Path(__file__).parents[2] / "bin" / "docker_entrypoint.sh").read_text(encoding="utf-8")
|
|
permission_error = entrypoint.partition("permission_error() {")[2].partition("\n}")[0]
|
|
abxpkg_repairs = entrypoint.partition('ensure_dir "$ABXPKG_LIB_DIR"')[2].partition("run_as_archivebox touch")[0]
|
|
|
|
assert 'for package_dir in "$provider_dir"/packages/*; do' in abxpkg_repairs
|
|
assert 'ensure_file_owner "$package_dir/derived.env"' in abxpkg_repairs
|
|
assert "chown -R" not in permission_error
|
|
assert "chown -R" not in abxpkg_repairs
|
|
|
|
|
|
def test_root_handoff_never_selects_filesystem_root():
|
|
from archivebox.config.permissions import root_data_dir_handoff_paths
|
|
|
|
assert root_data_dir_handoff_paths(Path("/"), ["archivebox", "init"]) == ()
|
|
|
|
|
|
def test_root_private_parent_grants_only_archivebox_group_traversal():
|
|
assert root_parent_can_grant_group_traversal(parent_uid=0, parent_gid=0, parent_mode=0o700, account_gid=911)
|
|
assert not root_parent_can_grant_group_traversal(parent_uid=0, parent_gid=0, parent_mode=0o701, account_gid=911)
|
|
assert not root_parent_can_grant_group_traversal(parent_uid=0, parent_gid=911, parent_mode=0o710, account_gid=911)
|
|
assert not root_parent_can_grant_group_traversal(parent_uid=0, parent_gid=100, parent_mode=0o750, account_gid=911)
|
|
assert not root_parent_can_grant_group_traversal(parent_uid=1000, parent_gid=1000, parent_mode=0o700, account_gid=911)
|