From 233b1f7f39b2bb116a824edf724ebc0945fc8a1b Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Thu, 14 Oct 2021 04:44:36 +0300 Subject: [PATCH] disallow to create tree in case of unsafe run --- src/ahriman/application/lock.py | 9 ++---- src/ahriman/core/repository/properties.py | 8 ++++- src/ahriman/core/util.py | 16 +++++++++- tests/ahriman/application/conftest.py | 2 +- .../application/handlers/test_handler_add.py | 4 +-- .../handlers/test_handler_clean.py | 2 +- .../application/handlers/test_handler_dump.py | 2 +- .../application/handlers/test_handler_init.py | 1 + .../handlers/test_handler_key_import.py | 2 +- .../handlers/test_handler_patch.py | 7 ++-- .../handlers/test_handler_rebuild.py | 6 ++-- .../handlers/test_handler_remove.py | 2 +- .../handlers/test_handler_remove_unknown.py | 4 +-- .../handlers/test_handler_report.py | 2 +- .../handlers/test_handler_setup.py | 2 +- .../application/handlers/test_handler_sign.py | 2 +- .../handlers/test_handler_status.py | 8 ++--- .../handlers/test_handler_status_update.py | 8 ++--- .../application/handlers/test_handler_sync.py | 2 +- .../handlers/test_handler_update.py | 4 +-- .../application/handlers/test_handler_user.py | 4 +-- .../application/handlers/test_handler_web.py | 2 +- tests/ahriman/application/test_lock.py | 11 ++----- tests/ahriman/conftest.py | 2 +- tests/ahriman/core/repository/conftest.py | 8 ++--- .../core/repository/test_properties.py | 13 ++++++++ tests/ahriman/core/status/test_watcher.py | 2 +- tests/ahriman/core/test_util.py | 32 +++++++++++++++++-- tests/ahriman/web/conftest.py | 6 ++-- 29 files changed, 114 insertions(+), 59 deletions(-) diff --git a/src/ahriman/application/lock.py b/src/ahriman/application/lock.py index a7c5bb6e..c92a3338 100644 --- a/src/ahriman/application/lock.py +++ b/src/ahriman/application/lock.py @@ -21,7 +21,6 @@ from __future__ import annotations import argparse import logging -import os from pathlib import Path from types import TracebackType @@ -29,8 +28,9 @@ from typing import Literal, Optional, Type from ahriman import version from ahriman.core.configuration import Configuration -from ahriman.core.exceptions import DuplicateRun, UnsafeRun +from ahriman.core.exceptions import DuplicateRun from ahriman.core.status.client import Client +from ahriman.core.util import check_user from ahriman.models.build_status import BuildStatusEnum @@ -105,10 +105,7 @@ class Lock: """ if self.unsafe: return - current_uid = os.getuid() - root_uid = self.root.stat().st_uid - if current_uid != root_uid: - raise UnsafeRun(current_uid, root_uid) + check_user(self.root) def clear(self) -> None: """ diff --git a/src/ahriman/core/repository/properties.py b/src/ahriman/core/repository/properties.py index bd0ff5ee..b60e181e 100644 --- a/src/ahriman/core/repository/properties.py +++ b/src/ahriman/core/repository/properties.py @@ -22,8 +22,10 @@ import logging from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.repo import Repo from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import UnsafeRun from ahriman.core.sign.gpg import GPG from ahriman.core.status.client import Client +from ahriman.core.util import check_user from ahriman.models.repository_paths import RepositoryPaths @@ -58,7 +60,11 @@ class Properties: self.name = configuration.get("repository", "name") self.paths = RepositoryPaths(configuration.getpath("repository", "root"), architecture) - self.paths.tree_create() + try: + check_user(self.paths.root) + self.paths.tree_create() + except UnsafeRun: + self.logger.exception("root owner differs from the current user, skipping tree creation") self.ignore_list = configuration.getlist("build", "ignore_packages", fallback=[]) self.pacman = Pacman(configuration) diff --git a/src/ahriman/core/util.py b/src/ahriman/core/util.py index 02f6f93b..125619c5 100644 --- a/src/ahriman/core/util.py +++ b/src/ahriman/core/util.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # import datetime +import os import subprocess import requests @@ -25,7 +26,7 @@ from logging import Logger from pathlib import Path from typing import Generator, Optional, Union -from ahriman.core.exceptions import InvalidOption +from ahriman.core.exceptions import InvalidOption, UnsafeRun def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] = None, @@ -54,6 +55,19 @@ def check_output(*args: str, exception: Optional[Exception], cwd: Optional[Path] raise exception or e +def check_user(root: Path) -> None: + """ + check if current user is the owner of the root + :param root: root directory (i.e. ahriman home) + """ + if not root.exists(): + return # no directory found, skip check + current_uid = os.getuid() + root_uid = root.stat().st_uid + if current_uid != root_uid: + raise UnsafeRun(current_uid, root_uid) + + def exception_response_text(exception: requests.exceptions.HTTPError) -> str: """ safe response exception text generation diff --git a/tests/ahriman/application/conftest.py b/tests/ahriman/application/conftest.py index 09529cf8..33ea7c4d 100644 --- a/tests/ahriman/application/conftest.py +++ b/tests/ahriman/application/conftest.py @@ -17,7 +17,7 @@ def application(configuration: Configuration, mocker: MockerFixture) -> Applicat :param mocker: mocker object :return: application test instance """ - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Application("x86_64", configuration, no_report=True) diff --git a/tests/ahriman/application/handlers/test_handler_add.py b/tests/ahriman/application/handlers/test_handler_add.py index 224d9fba..1dbaa15e 100644 --- a/tests/ahriman/application/handlers/test_handler_add.py +++ b/tests/ahriman/application/handlers/test_handler_add.py @@ -25,7 +25,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.add") Add.run(args, "x86_64", configuration, True) @@ -38,8 +38,8 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration """ args = _default_args(args) args.now = True - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.application.application.Application.add") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.update") updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") diff --git a/tests/ahriman/application/handlers/test_handler_clean.py b/tests/ahriman/application/handlers/test_handler_clean.py index c0416934..6b51eb01 100644 --- a/tests/ahriman/application/handlers/test_handler_clean.py +++ b/tests/ahriman/application/handlers/test_handler_clean.py @@ -25,7 +25,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.clean") Clean.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_dump.py b/tests/ahriman/application/handlers/test_handler_dump.py index a050c3b2..9c52bf01 100644 --- a/tests/ahriman/application/handlers/test_handler_dump.py +++ b/tests/ahriman/application/handlers/test_handler_dump.py @@ -10,7 +10,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ must run command """ - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") print_mock = mocker.patch("ahriman.application.handlers.dump.Dump._print") application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", return_value=configuration.dump()) diff --git a/tests/ahriman/application/handlers/test_handler_init.py b/tests/ahriman/application/handlers/test_handler_init.py index 6d66c4de..b54a2189 100644 --- a/tests/ahriman/application/handlers/test_handler_init.py +++ b/tests/ahriman/application/handlers/test_handler_init.py @@ -10,6 +10,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ must run command """ + mocker.patch("ahriman.core.repository.properties.check_user") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") diff --git a/tests/ahriman/application/handlers/test_handler_key_import.py b/tests/ahriman/application/handlers/test_handler_key_import.py index 5cde92c6..2a1f0356 100644 --- a/tests/ahriman/application/handlers/test_handler_key_import.py +++ b/tests/ahriman/application/handlers/test_handler_key_import.py @@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import") KeyImport.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_patch.py b/tests/ahriman/application/handlers/test_handler_patch.py index 007314d5..a884252f 100644 --- a/tests/ahriman/application/handlers/test_handler_patch.py +++ b/tests/ahriman/application/handlers/test_handler_patch.py @@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc """ args = _default_args(args) args.action = Action.Update - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create") Patch.run(args, "x86_64", configuration, True) @@ -41,7 +41,7 @@ def test_run_list(args: argparse.Namespace, configuration: Configuration, mocker """ args = _default_args(args) args.action = Action.List - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_list") Patch.run(args, "x86_64", configuration, True) @@ -54,7 +54,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock """ args = _default_args(args) args.action = Action.Remove - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove") Patch.run(args, "x86_64", configuration, True) @@ -91,6 +91,7 @@ def test_patch_set_create(application: Application, package_ahriman: Package, mo """ must create patch set for the package """ + mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman) remove_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove") create_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create") diff --git a/tests/ahriman/application/handlers/test_handler_rebuild.py b/tests/ahriman/application/handlers/test_handler_rebuild.py index 058ef306..6c759415 100644 --- a/tests/ahriman/application/handlers/test_handler_rebuild.py +++ b/tests/ahriman/application/handlers/test_handler_rebuild.py @@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages") application_mock = mocker.patch("ahriman.application.application.Application.update") @@ -39,9 +39,9 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration, """ args = _default_args(args) args.depends_on = ["python-aur"] - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman, package_python_schedule]) + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.update") Rebuild.run(args, "x86_64", configuration, True) @@ -55,9 +55,9 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati must run command for all packages if no filter supplied """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.repository.repository.Repository.packages", return_value=[package_ahriman, package_python_schedule]) + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.update") Rebuild.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_remove.py b/tests/ahriman/application/handlers/test_handler_remove.py index 556cafc3..7563c398 100644 --- a/tests/ahriman/application/handlers/test_handler_remove.py +++ b/tests/ahriman/application/handlers/test_handler_remove.py @@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.remove") Remove.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_remove_unknown.py b/tests/ahriman/application/handlers/test_handler_remove_unknown.py index b9cac3f4..64d34376 100644 --- a/tests/ahriman/application/handlers/test_handler_remove_unknown.py +++ b/tests/ahriman/application/handlers/test_handler_remove_unknown.py @@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.unknown") remove_mock = mocker.patch("ahriman.application.application.Application.remove") @@ -38,7 +38,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, pac """ args = _default_args(args) args.dry_run = True - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.unknown", return_value=[package_ahriman]) remove_mock = mocker.patch("ahriman.application.application.Application.remove") diff --git a/tests/ahriman/application/handlers/test_handler_report.py b/tests/ahriman/application/handlers/test_handler_report.py index c4b38340..0a2dcb9e 100644 --- a/tests/ahriman/application/handlers/test_handler_report.py +++ b/tests/ahriman/application/handlers/test_handler_report.py @@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.report") Report.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_setup.py b/tests/ahriman/application/handlers/test_handler_setup.py index 76dd923b..20841da6 100644 --- a/tests/ahriman/application/handlers/test_handler_setup.py +++ b/tests/ahriman/application/handlers/test_handler_setup.py @@ -32,7 +32,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") ahriman_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_ahriman") devtools_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_devtools") makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_makepkg") diff --git a/tests/ahriman/application/handlers/test_handler_sign.py b/tests/ahriman/application/handlers/test_handler_sign.py index f4500d96..1af2fd33 100644 --- a/tests/ahriman/application/handlers/test_handler_sign.py +++ b/tests/ahriman/application/handlers/test_handler_sign.py @@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.sign") Sign.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_status.py b/tests/ahriman/application/handlers/test_handler_status.py index 7b058daf..d31722bc 100644 --- a/tests/ahriman/application/handlers/test_handler_status.py +++ b/tests/ahriman/application/handlers/test_handler_status.py @@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.core.status.client.Client.get_self") packages_mock = mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), @@ -46,7 +46,7 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config """ args = _default_args(args) args.package = [package_ahriman.base] - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") packages_mock = mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) @@ -61,10 +61,10 @@ def test_run_by_status(args: argparse.Namespace, configuration: Configuration, p """ args = _default_args(args) args.status = BuildStatusEnum.Failed - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.status.client.Client.get", return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), (package_python_schedule, BuildStatus(BuildStatusEnum.Failed))]) + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") pretty_print_mock = mocker.patch("ahriman.models.package.Package.pretty_print") Status.run(args, "x86_64", configuration, True) @@ -76,7 +76,7 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio must create application object with native reporting """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") load_mock = mocker.patch("ahriman.core.status.client.Client.load") Status.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_status_update.py b/tests/ahriman/application/handlers/test_handler_status_update.py index 04593abd..bab4fca0 100644 --- a/tests/ahriman/application/handlers/test_handler_status_update.py +++ b/tests/ahriman/application/handlers/test_handler_status_update.py @@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") update_self_mock = mocker.patch("ahriman.core.status.client.Client.update_self") StatusUpdate.run(args, "x86_64", configuration, True) @@ -40,7 +40,7 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, pa """ args = _default_args(args) args.package = [package_ahriman.base] - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") update_mock = mocker.patch("ahriman.core.status.client.Client.update") StatusUpdate.run(args, "x86_64", configuration, True) @@ -55,7 +55,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, pack args = _default_args(args) args.package = [package_ahriman.base] args.action = Action.Remove - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") update_mock = mocker.patch("ahriman.core.status.client.Client.remove") StatusUpdate.run(args, "x86_64", configuration, True) @@ -67,7 +67,7 @@ def test_imply_with_report(args: argparse.Namespace, configuration: Configuratio must create application object with native reporting """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") load_mock = mocker.patch("ahriman.core.status.client.Client.load") StatusUpdate.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_sync.py b/tests/ahriman/application/handlers/test_handler_sync.py index 91190da7..191e8f12 100644 --- a/tests/ahriman/application/handlers/test_handler_sync.py +++ b/tests/ahriman/application/handlers/test_handler_sync.py @@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.sync") Sync.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_update.py b/tests/ahriman/application/handlers/test_handler_update.py index acc93766..bc634544 100644 --- a/tests/ahriman/application/handlers/test_handler_update.py +++ b/tests/ahriman/application/handlers/test_handler_update.py @@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") application_mock = mocker.patch("ahriman.application.application.Application.update") updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") @@ -41,7 +41,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, moc """ args = _default_args(args) args.dry_run = True - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") Update.run(args, "x86_64", configuration, True) diff --git a/tests/ahriman/application/handlers/test_handler_user.py b/tests/ahriman/application/handlers/test_handler_user.py index 8bb214d4..ed8c8087 100644 --- a/tests/ahriman/application/handlers/test_handler_user.py +++ b/tests/ahriman/application/handlers/test_handler_user.py @@ -33,7 +33,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get") create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") @@ -56,7 +56,7 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, mock """ args = _default_args(args) args.action = Action.Remove - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get") create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") diff --git a/tests/ahriman/application/handlers/test_handler_web.py b/tests/ahriman/application/handlers/test_handler_web.py index d3fbbcb4..c03442a1 100644 --- a/tests/ahriman/application/handlers/test_handler_web.py +++ b/tests/ahriman/application/handlers/test_handler_web.py @@ -21,8 +21,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc must run command """ args = _default_args(args) - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.spawn.Spawn.start") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") setup_mock = mocker.patch("ahriman.web.web.setup_service") run_mock = mocker.patch("ahriman.web.web.run_server") diff --git a/tests/ahriman/application/test_lock.py b/tests/ahriman/application/test_lock.py index 1e9abeef..d402581b 100644 --- a/tests/ahriman/application/test_lock.py +++ b/tests/ahriman/application/test_lock.py @@ -80,21 +80,16 @@ def test_check_user(lock: Lock, mocker: MockerFixture) -> None: """ must check user correctly """ - stat = Path.cwd().stat() - mocker.patch("pathlib.Path.stat", return_value=stat) - mocker.patch("os.getuid", return_value=stat.st_uid) - + check_user_patch = mocker.patch("ahriman.application.lock.check_user") lock.check_user() + check_user_patch.assert_called_once_with(lock.root) def test_check_user_exception(lock: Lock, mocker: MockerFixture) -> None: """ must raise exception if user differs """ - stat = Path.cwd().stat() - mocker.patch("pathlib.Path.stat") - mocker.patch("os.getuid", return_value=stat.st_uid + 1) - + mocker.patch("ahriman.application.lock.check_user", side_effect=UnsafeRun(0, 1)) with pytest.raises(UnsafeRun): lock.check_user() diff --git a/tests/ahriman/conftest.py b/tests/ahriman/conftest.py index 9c5c0a73..23fb8e69 100644 --- a/tests/ahriman/conftest.py +++ b/tests/ahriman/conftest.py @@ -225,5 +225,5 @@ def watcher(configuration: Configuration, mocker: MockerFixture) -> Watcher: :param mocker: mocker object :return: package status watcher test instance """ - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Watcher("x86_64", configuration) diff --git a/tests/ahriman/core/repository/conftest.py b/tests/ahriman/core/repository/conftest.py index 1e1057e4..e3f481dc 100644 --- a/tests/ahriman/core/repository/conftest.py +++ b/tests/ahriman/core/repository/conftest.py @@ -18,7 +18,7 @@ def cleaner(configuration: Configuration, mocker: MockerFixture) -> Cleaner: :param mocker: mocker object :return: cleaner test instance """ - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Cleaner("x86_64", configuration, no_report=True) @@ -30,12 +30,12 @@ def executor(configuration: Configuration, mocker: MockerFixture) -> Executor: :param mocker: mocker object :return: executor test instance """ - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_build") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Executor("x86_64", configuration, no_report=True) @@ -47,7 +47,7 @@ def repository(configuration: Configuration, mocker: MockerFixture) -> Repositor :param mocker: mocker object :return: repository test instance """ - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return Repository("x86_64", configuration, no_report=True) @@ -69,10 +69,10 @@ def update_handler(configuration: Configuration, mocker: MockerFixture) -> Updat :param mocker: mocker object :return: update handler test instance """ - mocker.patch("pathlib.Path.mkdir") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_build") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_chroot") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") return UpdateHandler("x86_64", configuration, no_report=True) diff --git a/tests/ahriman/core/repository/test_properties.py b/tests/ahriman/core/repository/test_properties.py index 262138cf..f39872cb 100644 --- a/tests/ahriman/core/repository/test_properties.py +++ b/tests/ahriman/core/repository/test_properties.py @@ -1,6 +1,7 @@ from pytest_mock import MockerFixture from ahriman.core.configuration import Configuration +from ahriman.core.exceptions import UnsafeRun from ahriman.core.repository.properties import Properties from ahriman.core.status.web_client import WebClient @@ -9,12 +10,24 @@ def test_create_tree_on_load(configuration: Configuration, mocker: MockerFixture """ must create tree on load """ + mocker.patch("ahriman.core.repository.properties.check_user") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") Properties("x86_64", configuration, True) tree_create_mock.assert_called_once() +def test_create_tree_on_load_unsafe(configuration: Configuration, mocker: MockerFixture) -> None: + """ + must not create tree on load in case if user differs from the root owner + """ + mocker.patch("ahriman.core.repository.properties.check_user", side_effect=UnsafeRun(0, 1)) + tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") + Properties("x86_64", configuration, True) + + tree_create_mock.assert_not_called() + + def test_create_dummy_report_client(configuration: Configuration, mocker: MockerFixture) -> None: """ must create dummy report client if report is disabled diff --git a/tests/ahriman/core/status/test_watcher.py b/tests/ahriman/core/status/test_watcher.py index 3a7cf764..5c7034c2 100644 --- a/tests/ahriman/core/status/test_watcher.py +++ b/tests/ahriman/core/status/test_watcher.py @@ -18,7 +18,7 @@ def test_force_no_report(configuration: Configuration, mocker: MockerFixture) -> must force dummy report client """ configuration.set_option("web", "port", "8080") - mocker.patch("pathlib.Path.mkdir") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") load_mock = mocker.patch("ahriman.core.status.client.Client.load") watcher = Watcher("x86_64", configuration) diff --git a/tests/ahriman/core/test_util.py b/tests/ahriman/core/test_util.py index d797531f..44d2f7ce 100644 --- a/tests/ahriman/core/test_util.py +++ b/tests/ahriman/core/test_util.py @@ -5,8 +5,8 @@ import subprocess from pathlib import Path from pytest_mock import MockerFixture -from ahriman.core.exceptions import InvalidOption -from ahriman.core.util import check_output, package_like, pretty_datetime, pretty_size, walk +from ahriman.core.exceptions import InvalidOption, UnsafeRun +from ahriman.core.util import check_output, check_user, package_like, pretty_datetime, pretty_size, walk from ahriman.models.package import Package @@ -51,6 +51,34 @@ def test_check_output_failure_log(mocker: MockerFixture) -> None: logger_mock.assert_called_once() +def test_check_user(mocker: MockerFixture) -> None: + """ + must check user correctly + """ + cwd = Path.cwd() + mocker.patch("os.getuid", return_value=cwd.stat().st_uid) + check_user(cwd) + + +def test_check_user_no_directory(mocker: MockerFixture) -> None: + """ + must not fail in case if no directory found + """ + mocker.patch("pathlib.Path.exists", return_value=False) + check_user(Path.cwd()) + + +def test_check_user_exception(mocker: MockerFixture) -> None: + """ + must raise exception if user differs + """ + cwd = Path.cwd() + mocker.patch("os.getuid", return_value=cwd.stat().st_uid + 1) + + with pytest.raises(UnsafeRun): + check_user(cwd) + + def test_package_like(package_ahriman: Package) -> None: """ package_like must return true for archives diff --git a/tests/ahriman/web/conftest.py b/tests/ahriman/web/conftest.py index 348cc93c..5d45e6e8 100644 --- a/tests/ahriman/web/conftest.py +++ b/tests/ahriman/web/conftest.py @@ -39,8 +39,8 @@ def application(configuration: Configuration, spawner: Spawn, mocker: MockerFixt :param mocker: mocker object :return: application test instance """ + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False) - mocker.patch("pathlib.Path.mkdir") return setup_service("x86_64", configuration, spawner) @@ -56,8 +56,8 @@ def application_with_auth(configuration: Configuration, user: User, spawner: Spa :return: application test instance """ configuration.set_option("auth", "target", "configuration") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True) - mocker.patch("pathlib.Path.mkdir") application = setup_service("x86_64", configuration, spawner) generated = User(user.username, user.hash_password(application["validator"].salt), user.access) @@ -78,6 +78,6 @@ def application_with_debug(configuration: Configuration, user: User, spawner: Sp :return: application test instance """ configuration.set_option("web", "debug", "yes") + mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False) - mocker.patch("pathlib.Path.mkdir") return setup_service("x86_64", configuration, spawner)