disallow to create tree in case of unsafe run

This commit is contained in:
Evgenii Alekseev 2021-10-14 04:44:36 +03:00
parent a83f1d5aa5
commit 233b1f7f39
29 changed files with 114 additions and 59 deletions

View File

@ -21,7 +21,6 @@ from __future__ import annotations
import argparse import argparse
import logging import logging
import os
from pathlib import Path from pathlib import Path
from types import TracebackType from types import TracebackType
@ -29,8 +28,9 @@ from typing import Literal, Optional, Type
from ahriman import version from ahriman import version
from ahriman.core.configuration import Configuration 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.status.client import Client
from ahriman.core.util import check_user
from ahriman.models.build_status import BuildStatusEnum from ahriman.models.build_status import BuildStatusEnum
@ -105,10 +105,7 @@ class Lock:
""" """
if self.unsafe: if self.unsafe:
return return
current_uid = os.getuid() check_user(self.root)
root_uid = self.root.stat().st_uid
if current_uid != root_uid:
raise UnsafeRun(current_uid, root_uid)
def clear(self) -> None: def clear(self) -> None:
""" """

View File

@ -22,8 +22,10 @@ import logging
from ahriman.core.alpm.pacman import Pacman from ahriman.core.alpm.pacman import Pacman
from ahriman.core.alpm.repo import Repo from ahriman.core.alpm.repo import Repo
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import UnsafeRun
from ahriman.core.sign.gpg import GPG from ahriman.core.sign.gpg import GPG
from ahriman.core.status.client import Client from ahriman.core.status.client import Client
from ahriman.core.util import check_user
from ahriman.models.repository_paths import RepositoryPaths from ahriman.models.repository_paths import RepositoryPaths
@ -58,7 +60,11 @@ class Properties:
self.name = configuration.get("repository", "name") self.name = configuration.get("repository", "name")
self.paths = RepositoryPaths(configuration.getpath("repository", "root"), architecture) 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.ignore_list = configuration.getlist("build", "ignore_packages", fallback=[])
self.pacman = Pacman(configuration) self.pacman = Pacman(configuration)

View File

@ -18,6 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import datetime import datetime
import os
import subprocess import subprocess
import requests import requests
@ -25,7 +26,7 @@ from logging import Logger
from pathlib import Path from pathlib import Path
from typing import Generator, Optional, Union 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, 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 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: def exception_response_text(exception: requests.exceptions.HTTPError) -> str:
""" """
safe response exception text generation safe response exception text generation

View File

@ -17,7 +17,7 @@ def application(configuration: Configuration, mocker: MockerFixture) -> Applicat
:param mocker: mocker object :param mocker: mocker object
:return: application test instance :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) return Application("x86_64", configuration, no_report=True)

View File

@ -25,7 +25,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.add")
Add.run(args, "x86_64", configuration, True) 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 = _default_args(args)
args.now = True args.now = True
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.application.application.Application.add") 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") application_mock = mocker.patch("ahriman.application.application.Application.update")
updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") updates_mock = mocker.patch("ahriman.application.application.Application.get_updates")

View File

@ -25,7 +25,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.clean")
Clean.run(args, "x86_64", configuration, True) Clean.run(args, "x86_64", configuration, True)

View File

@ -10,7 +10,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
""" """
must run command 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") print_mock = mocker.patch("ahriman.application.handlers.dump.Dump._print")
application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump", application_mock = mocker.patch("ahriman.core.configuration.Configuration.dump",
return_value=configuration.dump()) return_value=configuration.dump())

View File

@ -10,6 +10,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
""" """
must run command must run command
""" """
mocker.patch("ahriman.core.repository.properties.check_user")
tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")

View File

@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.key_import")
KeyImport.run(args, "x86_64", configuration, True) KeyImport.run(args, "x86_64", configuration, True)

View File

@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
""" """
args = _default_args(args) args = _default_args(args)
args.action = Action.Update 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") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_create")
Patch.run(args, "x86_64", configuration, True) 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 = _default_args(args)
args.action = Action.List 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") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_list")
Patch.run(args, "x86_64", configuration, True) 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 = _default_args(args)
args.action = Action.Remove 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") application_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove")
Patch.run(args, "x86_64", configuration, True) 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 must create patch set for the package
""" """
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman) mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman)
remove_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove") remove_mock = mocker.patch("ahriman.application.handlers.patch.Patch.patch_set_remove")
create_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create") create_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch_create")

View File

@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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_packages_mock = mocker.patch("ahriman.core.repository.repository.Repository.packages")
application_mock = mocker.patch("ahriman.application.application.Application.update") 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 = _default_args(args)
args.depends_on = ["python-aur"] args.depends_on = ["python-aur"]
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.core.repository.repository.Repository.packages", mocker.patch("ahriman.core.repository.repository.Repository.packages",
return_value=[package_ahriman, package_python_schedule]) 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") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration, True) 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 must run command for all packages if no filter supplied
""" """
args = _default_args(args) args = _default_args(args)
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.core.repository.repository.Repository.packages", mocker.patch("ahriman.core.repository.repository.Repository.packages",
return_value=[package_ahriman, package_python_schedule]) 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") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration, True) Rebuild.run(args, "x86_64", configuration, True)

View File

@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.remove")
Remove.run(args, "x86_64", configuration, True) Remove.run(args, "x86_64", configuration, True)

View File

@ -22,7 +22,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.unknown")
remove_mock = mocker.patch("ahriman.application.application.Application.remove") 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 = _default_args(args)
args.dry_run = True 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", application_mock = mocker.patch("ahriman.application.application.Application.unknown",
return_value=[package_ahriman]) return_value=[package_ahriman])
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")

View File

@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.report")
Report.run(args, "x86_64", configuration, True) Report.run(args, "x86_64", configuration, True)

View File

@ -32,7 +32,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") 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") 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") makepkg_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.configuration_create_makepkg")

View File

@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.sign")
Sign.run(args, "x86_64", configuration, True) Sign.run(args, "x86_64", configuration, True)

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.core.status.client.Client.get_self")
packages_mock = mocker.patch("ahriman.core.status.client.Client.get", packages_mock = mocker.patch("ahriman.core.status.client.Client.get",
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), 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 = _default_args(args)
args.package = [package_ahriman.base] 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", packages_mock = mocker.patch("ahriman.core.status.client.Client.get",
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success))]) 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 = _default_args(args)
args.status = BuildStatusEnum.Failed args.status = BuildStatusEnum.Failed
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.core.status.client.Client.get", mocker.patch("ahriman.core.status.client.Client.get",
return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)), return_value=[(package_ahriman, BuildStatus(BuildStatusEnum.Success)),
(package_python_schedule, BuildStatus(BuildStatusEnum.Failed))]) (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") pretty_print_mock = mocker.patch("ahriman.models.package.Package.pretty_print")
Status.run(args, "x86_64", configuration, True) 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 must create application object with native reporting
""" """
args = _default_args(args) 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") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
Status.run(args, "x86_64", configuration, True) Status.run(args, "x86_64", configuration, True)

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") update_self_mock = mocker.patch("ahriman.core.status.client.Client.update_self")
StatusUpdate.run(args, "x86_64", configuration, True) 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 = _default_args(args)
args.package = [package_ahriman.base] 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") update_mock = mocker.patch("ahriman.core.status.client.Client.update")
StatusUpdate.run(args, "x86_64", configuration, True) 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 = _default_args(args)
args.package = [package_ahriman.base] args.package = [package_ahriman.base]
args.action = Action.Remove 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") update_mock = mocker.patch("ahriman.core.status.client.Client.remove")
StatusUpdate.run(args, "x86_64", configuration, True) 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 must create application object with native reporting
""" """
args = _default_args(args) 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") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
StatusUpdate.run(args, "x86_64", configuration, True) StatusUpdate.run(args, "x86_64", configuration, True)

View File

@ -21,7 +21,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.sync")
Sync.run(args, "x86_64", configuration, True) Sync.run(args, "x86_64", configuration, True)

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") application_mock = mocker.patch("ahriman.application.application.Application.update")
updates_mock = mocker.patch("ahriman.application.application.Application.get_updates") 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 = _default_args(args)
args.dry_run = True 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") updates_mock = mocker.patch("ahriman.application.application.Application.get_updates")
Update.run(args, "x86_64", configuration, True) Update.run(args, "x86_64", configuration, True)

View File

@ -33,7 +33,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) 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") get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get")
create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create")
write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") 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 = _default_args(args)
args.action = Action.Remove 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") get_auth_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_get")
create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create") create_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_create")
write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write") write_configuration_mock = mocker.patch("ahriman.application.handlers.User.configuration_write")

View File

@ -21,8 +21,8 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
must run command must run command
""" """
args = _default_args(args) args = _default_args(args)
mocker.patch("pathlib.Path.mkdir")
mocker.patch("ahriman.core.spawn.Spawn.start") 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") setup_mock = mocker.patch("ahriman.web.web.setup_service")
run_mock = mocker.patch("ahriman.web.web.run_server") run_mock = mocker.patch("ahriman.web.web.run_server")

View File

@ -80,21 +80,16 @@ def test_check_user(lock: Lock, mocker: MockerFixture) -> None:
""" """
must check user correctly must check user correctly
""" """
stat = Path.cwd().stat() check_user_patch = mocker.patch("ahriman.application.lock.check_user")
mocker.patch("pathlib.Path.stat", return_value=stat)
mocker.patch("os.getuid", return_value=stat.st_uid)
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: def test_check_user_exception(lock: Lock, mocker: MockerFixture) -> None:
""" """
must raise exception if user differs must raise exception if user differs
""" """
stat = Path.cwd().stat() mocker.patch("ahriman.application.lock.check_user", side_effect=UnsafeRun(0, 1))
mocker.patch("pathlib.Path.stat")
mocker.patch("os.getuid", return_value=stat.st_uid + 1)
with pytest.raises(UnsafeRun): with pytest.raises(UnsafeRun):
lock.check_user() lock.check_user()

View File

@ -225,5 +225,5 @@ def watcher(configuration: Configuration, mocker: MockerFixture) -> Watcher:
:param mocker: mocker object :param mocker: mocker object
:return: package status watcher test instance :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) return Watcher("x86_64", configuration)

View File

@ -18,7 +18,7 @@ def cleaner(configuration: Configuration, mocker: MockerFixture) -> Cleaner:
:param mocker: mocker object :param mocker: mocker object
:return: cleaner test instance :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) return Cleaner("x86_64", configuration, no_report=True)
@ -30,12 +30,12 @@ def executor(configuration: Configuration, mocker: MockerFixture) -> Executor:
:param mocker: mocker object :param mocker: mocker object
:return: executor test instance :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_build")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") 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_chroot")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") 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) return Executor("x86_64", configuration, no_report=True)
@ -47,7 +47,7 @@ def repository(configuration: Configuration, mocker: MockerFixture) -> Repositor
:param mocker: mocker object :param mocker: mocker object
:return: repository test instance :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) return Repository("x86_64", configuration, no_report=True)
@ -69,10 +69,10 @@ def update_handler(configuration: Configuration, mocker: MockerFixture) -> Updat
:param mocker: mocker object :param mocker: mocker object
:return: update handler test instance :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_build")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_cache") 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_chroot")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual") mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_manual")
mocker.patch("ahriman.core.repository.cleaner.Cleaner.clear_packages") 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) return UpdateHandler("x86_64", configuration, no_report=True)

View File

@ -1,6 +1,7 @@
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import UnsafeRun
from ahriman.core.repository.properties import Properties from ahriman.core.repository.properties import Properties
from ahriman.core.status.web_client import WebClient 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 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") tree_create_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
Properties("x86_64", configuration, True) Properties("x86_64", configuration, True)
tree_create_mock.assert_called_once() 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: def test_create_dummy_report_client(configuration: Configuration, mocker: MockerFixture) -> None:
""" """
must create dummy report client if report is disabled must create dummy report client if report is disabled

View File

@ -18,7 +18,7 @@ def test_force_no_report(configuration: Configuration, mocker: MockerFixture) ->
must force dummy report client must force dummy report client
""" """
configuration.set_option("web", "port", "8080") 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") load_mock = mocker.patch("ahriman.core.status.client.Client.load")
watcher = Watcher("x86_64", configuration) watcher = Watcher("x86_64", configuration)

View File

@ -5,8 +5,8 @@ import subprocess
from pathlib import Path from pathlib import Path
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from ahriman.core.exceptions import InvalidOption from ahriman.core.exceptions import InvalidOption, UnsafeRun
from ahriman.core.util import check_output, package_like, pretty_datetime, pretty_size, walk from ahriman.core.util import check_output, check_user, package_like, pretty_datetime, pretty_size, walk
from ahriman.models.package import Package from ahriman.models.package import Package
@ -51,6 +51,34 @@ def test_check_output_failure_log(mocker: MockerFixture) -> None:
logger_mock.assert_called_once() 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: def test_package_like(package_ahriman: Package) -> None:
""" """
package_like must return true for archives package_like must return true for archives

View File

@ -39,8 +39,8 @@ def application(configuration: Configuration, spawner: Spawn, mocker: MockerFixt
:param mocker: mocker object :param mocker: mocker object
:return: application test instance :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.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
mocker.patch("pathlib.Path.mkdir")
return setup_service("x86_64", configuration, spawner) 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 :return: application test instance
""" """
configuration.set_option("auth", "target", "configuration") 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.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True)
mocker.patch("pathlib.Path.mkdir")
application = setup_service("x86_64", configuration, spawner) application = setup_service("x86_64", configuration, spawner)
generated = User(user.username, user.hash_password(application["validator"].salt), user.access) 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 :return: application test instance
""" """
configuration.set_option("web", "debug", "yes") 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.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
mocker.patch("pathlib.Path.mkdir")
return setup_service("x86_64", configuration, spawner) return setup_service("x86_64", configuration, spawner)