pass no_report to handlers

This commit is contained in:
Evgenii Alekseev 2021-09-08 02:45:20 +03:00
parent a061ea96e6
commit 16587306dd
60 changed files with 232 additions and 134 deletions

View File

@ -77,7 +77,7 @@
{% if auth_username is none %} {% if auth_username is none %}
<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#loginForm" style="text-decoration: none">login</button> <button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#loginForm" style="text-decoration: none">login</button>
{% else %} {% else %}
<form action="/logout" method="post"> <form action="/user-api/v1/logout" method="post">
<button type="submit" class="btn btn-link" style="text-decoration: none">logout ({{ auth_username }})</button> <button type="submit" class="btn btn-link" style="text-decoration: none">logout ({{ auth_username }})</button>
</form> </form>
{% endif %} {% endif %}
@ -88,19 +88,23 @@
<div id="loginForm" tabindex="-1" role="dialog" class="modal fade"> <div id="loginForm" tabindex="-1" role="dialog" class="modal fade">
<div class="modal-dialog modal-login"> <div class="modal-dialog modal-login">
<div class="modal-content"> <div class="modal-content">
<form action="/login" method="post"> <form action="/user-api/v1/login" method="post">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title">login</h4> <h4 class="modal-title">login</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group row">
<label for="username" class="col-form-label">username</label> <label for="username" class="col-sm-2 col-form-label">username</label>
<div class="col-sm-10">
<input id="username" type="text" class="form-control" placeholder="enter username" name="username" required> <input id="username" type="text" class="form-control" placeholder="enter username" name="username" required>
</div> </div>
<div class="form-group"> </div>
<label for="password" class="col-form-label">password</label> <div class="form-group row">
<input id="password" type="password" class="form-control" placeholder="enter username" name="password" required> <label for="password" class="col-sm-2 col-form-label">password</label>
<div class="col-sm-10">
<input id="password" type="password" class="form-control" placeholder="enter password" name="password" required>
</div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@ -76,7 +76,7 @@ def _parser() -> argparse.ArgumentParser:
_set_status_update_parser(subparsers) _set_status_update_parser(subparsers)
_set_sync_parser(subparsers) _set_sync_parser(subparsers)
_set_update_parser(subparsers) _set_update_parser(subparsers)
_set_web_parser(subparsers, parser) _set_web_parser(subparsers)
return parser return parser
@ -358,16 +358,15 @@ def _set_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
return parser return parser
def _set_web_parser(root: SubParserAction, parent: argparse.ArgumentParser) -> argparse.ArgumentParser: def _set_web_parser(root: SubParserAction) -> argparse.ArgumentParser:
""" """
add parser for web subcommand add parser for web subcommand
:param root: subparsers for the commands :param root: subparsers for the commands
:param parent: command line parser for the application
:return: created argument parser :return: created argument parser
""" """
parser = root.add_parser("web", help="start web server", description="start web server", parser = root.add_parser("web", help="start web server", description="start web server",
formatter_class=argparse.ArgumentDefaultsHelpFormatter) formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=parent) parser.set_defaults(handler=handlers.Web, lock=None, no_report=True, parser=_parser)
return parser return parser

View File

@ -40,16 +40,17 @@ class Application:
:ivar repository: repository instance :ivar repository: repository instance
""" """
def __init__(self, architecture: str, configuration: Configuration) -> None: def __init__(self, architecture: str, configuration: Configuration, no_report: bool) -> None:
""" """
default constructor default constructor
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
self.logger = logging.getLogger("root") self.logger = logging.getLogger("root")
self.configuration = configuration self.configuration = configuration
self.architecture = architecture self.architecture = architecture
self.repository = Repository(architecture, configuration) self.repository = Repository(architecture, configuration, no_report)
def _finalize(self, built_packages: Iterable[Package]) -> None: def _finalize(self, built_packages: Iterable[Package]) -> None:
""" """

View File

@ -32,14 +32,16 @@ class Add(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
application = Application(architecture, configuration) application = Application(architecture, configuration, no_report)
application.add(args.package, args.without_dependencies) application.add(args.package, args.without_dependencies)
if not args.now: if not args.now:
return return

View File

@ -32,12 +32,14 @@ class Clean(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).clean(args.no_build, args.no_cache, args.no_chroot, Application(architecture, configuration, no_report).clean(args.no_build, args.no_cache, args.no_chroot,
args.no_manual, args.no_packages) args.no_manual, args.no_packages)

View File

@ -34,12 +34,14 @@ class CreateUser(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
salt = CreateUser.get_salt(configuration) salt = CreateUser.get_salt(configuration)
user = CreateUser.create_user(args) user = CreateUser.create_user(args)

View File

@ -33,12 +33,14 @@ class Dump(Handler):
_print = print _print = print
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
dump = configuration.dump() dump = configuration.dump()
for section, values in sorted(dump.items()): for section, values in sorted(dump.items()):

View File

@ -47,7 +47,7 @@ class Handler:
try: try:
configuration = Configuration.from_path(args.configuration, architecture, not args.no_log) configuration = Configuration.from_path(args.configuration, architecture, not args.no_log)
with Lock(args, architecture, configuration): with Lock(args, architecture, configuration):
cls.run(args, architecture, configuration) cls.run(args, architecture, configuration, args.no_report)
return True return True
except Exception: except Exception:
logging.getLogger("root").exception("process exception") logging.getLogger("root").exception("process exception")
@ -88,11 +88,13 @@ class Handler:
return architectures return architectures
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
raise NotImplementedError raise NotImplementedError

View File

@ -32,11 +32,13 @@ class Init(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).repository.repo.init() Application(architecture, configuration, no_report).repository.repo.init()

View File

@ -32,11 +32,13 @@ class KeyImport(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).repository.sign.import_key(args.key_server, args.key) Application(architecture, configuration, no_report).repository.sign.import_key(args.key_server, args.key)

View File

@ -32,16 +32,18 @@ class Rebuild(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
depends_on = set(args.depends_on) if args.depends_on else None depends_on = set(args.depends_on) if args.depends_on else None
application = Application(architecture, configuration) application = Application(architecture, configuration, no_report)
packages = [ packages = [
package package
for package in application.repository.packages() for package in application.repository.packages()

View File

@ -32,11 +32,13 @@ class Remove(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).remove(args.package) Application(architecture, configuration, no_report).remove(args.package)

View File

@ -33,14 +33,16 @@ class RemoveUnknown(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
application = Application(architecture, configuration) application = Application(architecture, configuration, no_report)
unknown_packages = application.unknown() unknown_packages = application.unknown()
if args.dry_run: if args.dry_run:
for package in unknown_packages: for package in unknown_packages:

View File

@ -32,11 +32,13 @@ class Report(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).report(args.target, []) Application(architecture, configuration, no_report).report(args.target, [])

View File

@ -32,12 +32,14 @@ class Search(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
search = " ".join(args.search) search = " ".join(args.search)
packages = aur.search(search) packages = aur.search(search)

View File

@ -43,14 +43,16 @@ class Setup(Handler):
SUDOERS_PATH = Path("/etc/sudoers.d/ahriman") SUDOERS_PATH = Path("/etc/sudoers.d/ahriman")
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
application = Application(architecture, configuration) application = Application(architecture, configuration, no_report)
Setup.create_makepkg_configuration(args.packager, application.repository.paths) Setup.create_makepkg_configuration(args.packager, application.repository.paths)
Setup.create_executable(args.build_command, architecture) Setup.create_executable(args.build_command, architecture)
Setup.create_devtools_configuration(args.build_command, architecture, args.from_configuration, Setup.create_devtools_configuration(args.build_command, architecture, args.from_configuration,

View File

@ -32,11 +32,13 @@ class Sign(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).sign(args.package) Application(architecture, configuration, no_report).sign(args.package)

View File

@ -34,24 +34,27 @@ class Status(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
application = Application(architecture, configuration) # we are using reporter here
client = Application(architecture, configuration, no_report=False).repository.reporter
if args.ahriman: if args.ahriman:
ahriman = application.repository.reporter.get_self() ahriman = client.get_self()
print(ahriman.pretty_print()) print(ahriman.pretty_print())
print() print()
if args.package: if args.package:
packages: Iterable[Tuple[Package, BuildStatus]] = sum( packages: Iterable[Tuple[Package, BuildStatus]] = sum(
[application.repository.reporter.get(base) for base in args.package], [client.get(base) for base in args.package],
start=[]) start=[])
else: else:
packages = application.repository.reporter.get(None) packages = client.get(None)
for package, package_status in sorted(packages, key=lambda item: item[0].base): for package, package_status in sorted(packages, key=lambda item: item[0].base):
print(package.pretty_print()) print(package.pretty_print())
print(f"\t{package.version}") print(f"\t{package.version}")

View File

@ -32,14 +32,17 @@ class StatusUpdate(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
client = Application(architecture, configuration).repository.reporter # we are using reporter here
client = Application(architecture, configuration, no_report=False).repository.reporter
callback: Callable[[str], None] = lambda p: client.remove(p) if args.remove else client.update(p, args.status) callback: Callable[[str], None] = lambda p: client.remove(p) if args.remove else client.update(p, args.status)
if args.package: if args.package:
# update packages statuses # update packages statuses

View File

@ -32,11 +32,13 @@ class Sync(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
Application(architecture, configuration).sync(args.target, []) Application(architecture, configuration, no_report).sync(args.target, [])

View File

@ -32,14 +32,16 @@ class Update(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
application = Application(architecture, configuration) application = Application(architecture, configuration, no_report)
packages = application.get_updates(args.package, args.no_aur, args.no_manual, args.no_vcs, packages = application.get_updates(args.package, args.no_aur, args.no_manual, args.no_vcs,
Update.log_fn(application, args.dry_run)) Update.log_fn(application, args.dry_run))
if args.dry_run: if args.dry_run:

View File

@ -32,17 +32,19 @@ class Web(Handler):
""" """
@classmethod @classmethod
def run(cls: Type[Handler], args: argparse.Namespace, architecture: str, configuration: Configuration) -> None: def run(cls: Type[Handler], args: argparse.Namespace, architecture: str,
configuration: Configuration, no_report: bool) -> None:
""" """
callback for command line callback for command line
:param args: command line args :param args: command line args
:param architecture: repository architecture :param architecture: repository architecture
:param configuration: configuration instance :param configuration: configuration instance
:param no_report: force disable reporting
""" """
# we are using local import for optional dependencies # we are using local import for optional dependencies
from ahriman.web.web import run_server, setup_service from ahriman.web.web import run_server, setup_service
spawner = Spawn(args.parser, architecture, configuration) spawner = Spawn(args.parser(), architecture, configuration)
spawner.start() spawner.start()
application = setup_service(architecture, configuration, spawner) application = setup_service(architecture, configuration, spawner)

View File

@ -19,7 +19,7 @@
# #
from __future__ import annotations from __future__ import annotations
from typing import Optional, Set, Type from typing import Optional, Type
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.models.auth_settings import AuthSettings from ahriman.models.auth_settings import AuthSettings
@ -36,8 +36,8 @@ class Auth:
:cvar ALLOWED_PATHS_GROUPS: URI paths prefixes which can be accessed without authorization, predefined :cvar ALLOWED_PATHS_GROUPS: URI paths prefixes which can be accessed without authorization, predefined
""" """
ALLOWED_PATHS = {"/", "/favicon.ico", "/index.html", "/login", "/logout"} ALLOWED_PATHS = {"/", "/favicon.ico", "/index.html"}
ALLOWED_PATHS_GROUPS: Set[str] = set() ALLOWED_PATHS_GROUPS = {"/user-api"}
def __init__(self, configuration: Configuration, provider: AuthSettings = AuthSettings.Disabled) -> None: def __init__(self, configuration: Configuration, provider: AuthSettings = AuthSettings.Disabled) -> None:
""" """

View File

@ -43,7 +43,13 @@ class Properties:
:ivar sign: GPG wrapper instance :ivar sign: GPG wrapper instance
""" """
def __init__(self, architecture: str, configuration: Configuration) -> None: def __init__(self, architecture: str, configuration: Configuration, no_report: bool) -> None:
"""
default constructor
:param architecture: repository architecture
:param configuration: configuration instance
:param no_report: force disable reporting
"""
self.logger = logging.getLogger("builder") self.logger = logging.getLogger("builder")
self.architecture = architecture self.architecture = architecture
self.configuration = configuration self.configuration = configuration
@ -58,4 +64,4 @@ class Properties:
self.pacman = Pacman(configuration) self.pacman = Pacman(configuration)
self.sign = GPG(architecture, configuration) self.sign = GPG(architecture, configuration)
self.repo = Repo(self.name, self.paths, self.sign.repository_sign_args) self.repo = Repo(self.name, self.paths, self.sign.repository_sign_args)
self.reporter = Client.load(configuration) self.reporter = Client() if no_report else Client.load(configuration)

View File

@ -49,7 +49,7 @@ class Watcher:
self.logger = logging.getLogger("http") self.logger = logging.getLogger("http")
self.architecture = architecture self.architecture = architecture
self.repository = Repository(architecture, configuration) self.repository = Repository(architecture, configuration, no_report=True)
self.known: Dict[str, Tuple[Package, BuildStatus]] = {} self.known: Dict[str, Tuple[Package, BuildStatus]] = {}
self.status = BuildStatus() self.status = BuildStatus()

View File

@ -65,7 +65,7 @@ class WebClient(Client):
""" """
:return: full url for web service to login :return: full url for web service to login
""" """
return f"{self.address}/login" return f"{self.address}/user-api/v1/login"
@property @property
def _status_url(self) -> str: def _status_url(self) -> str:

View File

@ -51,7 +51,7 @@ class User:
""" """
if username is None or password is None: if username is None or password is None:
return None return None
return cls(username, password, UserAccess.Status) return cls(username, password, UserAccess.Read)
@staticmethod @staticmethod
def generate_password(length: int) -> str: def generate_password(length: int) -> str:

View File

@ -25,9 +25,7 @@ class UserAccess(Enum):
web user access enumeration web user access enumeration
:cvar Read: user can read status page :cvar Read: user can read status page
:cvar Write: user can modify task and package list :cvar Write: user can modify task and package list
:cvar Status: user can update statuses via API
""" """
Read = "read" Read = "read"
Write = "write" Write = "write"
Status = "status"

View File

@ -73,9 +73,7 @@ def auth_handler(validator: Auth) -> MiddlewareType:
""" """
@middleware @middleware
async def handle(request: Request, handler: HandlerType) -> StreamResponse: async def handle(request: Request, handler: HandlerType) -> StreamResponse:
if request.path.startswith("/status-api"): if request.method in ("GET", "HEAD", "OPTIONS"):
permission = UserAccess.Status
elif request.method in ("GET", "HEAD", "OPTIONS"):
permission = UserAccess.Read permission = UserAccess.Read
else: else:
permission = UserAccess.Write permission = UserAccess.Write

View File

@ -37,8 +37,8 @@ def setup_routes(application: Application) -> None:
GET / get build status page GET / get build status page
GET /index.html same as above GET /index.html same as above
POST /login login to service POST /user-api/v1/login login to service
POST /logout logout from service POST /user-api/v1/logout logout from service
GET /status-api/v1/ahriman get current service status GET /status-api/v1/ahriman get current service status
POST /status-api/v1/ahriman update service status POST /status-api/v1/ahriman update service status
@ -57,8 +57,8 @@ def setup_routes(application: Application) -> None:
application.router.add_get("/", IndexView, allow_head=True) application.router.add_get("/", IndexView, allow_head=True)
application.router.add_get("/index.html", IndexView, allow_head=True) application.router.add_get("/index.html", IndexView, allow_head=True)
application.router.add_post("/login", LoginView) application.router.add_post("/user-api/v1/login", LoginView)
application.router.add_post("/logout", LogoutView) application.router.add_post("/user-api/v1/logout", LogoutView)
application.router.add_get("/status-api/v1/ahriman", AhrimanView, allow_head=True) application.router.add_get("/status-api/v1/ahriman", AhrimanView, allow_head=True)
application.router.add_post("/status-api/v1/ahriman", AhrimanView) application.router.add_post("/status-api/v1/ahriman", AhrimanView)

View File

@ -20,7 +20,7 @@ def application(configuration: Configuration, mocker: MockerFixture) -> Applicat
:return: application test instance :return: application test instance
""" """
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
return Application("x86_64", configuration) return Application("x86_64", configuration, no_report=True)
@pytest.fixture @pytest.fixture

View File

@ -94,4 +94,4 @@ def test_run(args: argparse.Namespace, configuration: Configuration) -> None:
must raise NotImplemented for missing method must raise NotImplemented for missing method
""" """
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
Handler.run(args, "x86_64", configuration) Handler.run(args, "x86_64", configuration, True)

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.add") application_mock = mocker.patch("ahriman.application.application.Application.add")
Add.run(args, "x86_64", configuration) Add.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
@ -41,6 +41,6 @@ def test_run_with_updates(args: argparse.Namespace, configuration: Configuration
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")
Add.run(args, "x86_64", configuration) Add.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
updates_mock.assert_called_once() updates_mock.assert_called_once()

View File

@ -28,5 +28,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.clean") application_mock = mocker.patch("ahriman.application.application.Application.clean")
Clean.run(args, "x86_64", configuration) Clean.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -19,7 +19,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
""" """
args.username = "user" args.username = "user"
args.password = "pa55w0rd" args.password = "pa55w0rd"
args.role = UserAccess.Status args.role = UserAccess.Read
args.as_service = False args.as_service = False
return args return args
@ -34,7 +34,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
create_user = mocker.patch("ahriman.application.handlers.CreateUser.create_user") create_user = mocker.patch("ahriman.application.handlers.CreateUser.create_user")
get_salt_mock = mocker.patch("ahriman.application.handlers.CreateUser.get_salt") get_salt_mock = mocker.patch("ahriman.application.handlers.CreateUser.get_salt")
CreateUser.run(args, "x86_64", configuration) CreateUser.run(args, "x86_64", configuration, True)
get_auth_configuration_mock.assert_called_once() get_auth_configuration_mock.assert_called_once()
create_configuration_mock.assert_called_once() create_configuration_mock.assert_called_once()
create_user.assert_called_once() create_user.assert_called_once()

View File

@ -15,6 +15,6 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
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())
Dump.run(args, "x86_64", configuration) Dump.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
print_mock.assert_called() print_mock.assert_called()

View File

@ -13,6 +13,6 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
create_tree_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree") create_tree_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree")
init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init") init_mock = mocker.patch("ahriman.core.alpm.repo.Repo.init")
Init.run(args, "x86_64", configuration) Init.run(args, "x86_64", configuration, True)
create_tree_mock.assert_called_once() create_tree_mock.assert_called_once()
init_mock.assert_called_once() init_mock.assert_called_once()

View File

@ -25,5 +25,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.import_key") application_mock = mocker.patch("ahriman.core.sign.gpg.GPG.import_key")
KeyImport.run(args, "x86_64", configuration) KeyImport.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
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")
Rebuild.run(args, "x86_64", configuration) Rebuild.run(args, "x86_64", configuration, True)
application_packages_mock.assert_called_once() application_packages_mock.assert_called_once()
application_mock.assert_called_once() application_mock.assert_called_once()
@ -44,7 +44,7 @@ def test_run_filter(args: argparse.Namespace, configuration: Configuration,
return_value=[package_ahriman, package_python_schedule]) return_value=[package_ahriman, package_python_schedule])
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration) Rebuild.run(args, "x86_64", configuration, True)
application_mock.assert_called_with([package_ahriman]) application_mock.assert_called_with([package_ahriman])
@ -60,5 +60,5 @@ def test_run_without_filter(args: argparse.Namespace, configuration: Configurati
return_value=[package_ahriman, package_python_schedule]) return_value=[package_ahriman, package_python_schedule])
application_mock = mocker.patch("ahriman.application.application.Application.update") application_mock = mocker.patch("ahriman.application.application.Application.update")
Rebuild.run(args, "x86_64", configuration) Rebuild.run(args, "x86_64", configuration, True)
application_mock.assert_called_with([package_ahriman, package_python_schedule]) application_mock.assert_called_with([package_ahriman, package_python_schedule])

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.remove") application_mock = mocker.patch("ahriman.application.application.Application.remove")
Remove.run(args, "x86_64", configuration) Remove.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
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")
RemoveUnknown.run(args, "x86_64", configuration) RemoveUnknown.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
remove_mock.assert_called_once() remove_mock.assert_called_once()
@ -44,7 +44,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, pac
remove_mock = mocker.patch("ahriman.application.application.Application.remove") remove_mock = mocker.patch("ahriman.application.application.Application.remove")
log_fn_mock = mocker.patch("ahriman.application.handlers.remove_unknown.RemoveUnknown.log_fn") log_fn_mock = mocker.patch("ahriman.application.handlers.remove_unknown.RemoveUnknown.log_fn")
RemoveUnknown.run(args, "x86_64", configuration) RemoveUnknown.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
remove_mock.assert_not_called() remove_mock.assert_not_called()
log_fn_mock.assert_called_with(package_ahriman) log_fn_mock.assert_called_with(package_ahriman)

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.report") application_mock = mocker.patch("ahriman.application.application.Application.report")
Report.run(args, "x86_64", configuration) Report.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -26,7 +26,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, aur_package
mocker.patch("aur.search", return_value=[aur_package_ahriman]) mocker.patch("aur.search", return_value=[aur_package_ahriman])
log_mock = mocker.patch("ahriman.application.handlers.search.Search.log_fn") log_mock = mocker.patch("ahriman.application.handlers.search.Search.log_fn")
Search.run(args, "x86_64", configuration) Search.run(args, "x86_64", configuration, True)
log_mock.assert_called_once() log_mock.assert_called_once()
@ -38,7 +38,7 @@ def test_run_multiple_search(args: argparse.Namespace, configuration: Configurat
args.search = ["ahriman", "is", "cool"] args.search = ["ahriman", "is", "cool"]
search_mock = mocker.patch("aur.search") search_mock = mocker.patch("aur.search")
Search.run(args, "x86_64", configuration) Search.run(args, "x86_64", configuration, True)
search_mock.assert_called_with(" ".join(args.search)) search_mock.assert_called_with(" ".join(args.search))
@ -51,5 +51,5 @@ def test_log_fn(args: argparse.Namespace, configuration: Configuration, aur_pack
mocker.patch("aur.search", return_value=[aur_package_ahriman]) mocker.patch("aur.search", return_value=[aur_package_ahriman])
print_mock = mocker.patch("builtins.print") print_mock = mocker.patch("builtins.print")
Search.run(args, "x86_64", configuration) Search.run(args, "x86_64", configuration, True)
print_mock.assert_called() # we don't really care about call details tbh print_mock.assert_called() # we don't really care about call details tbh

View File

@ -39,7 +39,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_sudo_configuration") sudo_configuration_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_sudo_configuration")
executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_executable") executable_mock = mocker.patch("ahriman.application.handlers.setup.Setup.create_executable")
Setup.run(args, "x86_64", configuration) Setup.run(args, "x86_64", configuration, True)
ahriman_configuration_mock.assert_called_once() ahriman_configuration_mock.assert_called_once()
devtools_configuration_mock.assert_called_once() devtools_configuration_mock.assert_called_once()
makepkg_configuration_mock.assert_called_once() makepkg_configuration_mock.assert_called_once()

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.sign") application_mock = mocker.patch("ahriman.application.application.Application.sign")
Sign.run(args, "x86_64", configuration) Sign.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -30,7 +30,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, package_ahr
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())]) return_value=[(package_ahriman, BuildStatus())])
Status.run(args, "x86_64", configuration) Status.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
packages_mock.assert_called_once() packages_mock.assert_called_once()
@ -46,5 +46,17 @@ def test_run_with_package_filter(args: argparse.Namespace, configuration: Config
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())]) return_value=[(package_ahriman, BuildStatus())])
Status.run(args, "x86_64", configuration) Status.run(args, "x86_64", configuration, True)
packages_mock.assert_called_once() packages_mock.assert_called_once()
def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must create application object with native reporting
"""
args = _default_args(args)
mocker.patch("pathlib.Path.mkdir")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
Status.run(args, "x86_64", configuration, True)
load_mock.assert_called_once()

View File

@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
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) StatusUpdate.run(args, "x86_64", configuration, True)
update_self_mock.assert_called_once() update_self_mock.assert_called_once()
@ -42,7 +42,7 @@ def test_run_packages(args: argparse.Namespace, configuration: Configuration, pa
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
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) StatusUpdate.run(args, "x86_64", configuration, True)
update_mock.assert_called_once() update_mock.assert_called_once()
@ -57,5 +57,17 @@ def test_run_remove(args: argparse.Namespace, configuration: Configuration, pack
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
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) StatusUpdate.run(args, "x86_64", configuration, True)
update_mock.assert_called_once() update_mock.assert_called_once()
def test_imply_with_report(args: argparse.Namespace, configuration: Configuration, mocker: MockerFixture) -> None:
"""
must create application object with native reporting
"""
args = _default_args(args)
mocker.patch("pathlib.Path.mkdir")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
StatusUpdate.run(args, "x86_64", configuration, True)
load_mock.assert_called_once()

View File

@ -24,5 +24,5 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
application_mock = mocker.patch("ahriman.application.application.Application.sync") application_mock = mocker.patch("ahriman.application.application.Application.sync")
Sync.run(args, "x86_64", configuration) Sync.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()

View File

@ -30,7 +30,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
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")
Update.run(args, "x86_64", configuration) Update.run(args, "x86_64", configuration, True)
application_mock.assert_called_once() application_mock.assert_called_once()
updates_mock.assert_called_once() updates_mock.assert_called_once()
@ -44,7 +44,7 @@ def test_run_dry_run(args: argparse.Namespace, configuration: Configuration, moc
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
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) Update.run(args, "x86_64", configuration, True)
updates_mock.assert_called_once() updates_mock.assert_called_once()

View File

@ -12,7 +12,7 @@ def _default_args(args: argparse.Namespace) -> argparse.Namespace:
:param args: command line arguments fixture :param args: command line arguments fixture
:return: generated arguments for these test cases :return: generated arguments for these test cases
""" """
args.parser = True args.parser = lambda: True
return args return args
@ -26,6 +26,6 @@ def test_run(args: argparse.Namespace, configuration: Configuration, mocker: Moc
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")
Web.run(args, "x86_64", configuration) Web.run(args, "x86_64", configuration, True)
setup_mock.assert_called_once() setup_mock.assert_called_once()
run_mock.assert_called_once() run_mock.assert_called_once()

View File

@ -265,7 +265,7 @@ def test_subparsers_web(parser: argparse.ArgumentParser) -> None:
args = parser.parse_args(["-a", "x86_64", "web"]) args = parser.parse_args(["-a", "x86_64", "web"])
assert args.lock is None assert args.lock is None
assert args.no_report assert args.no_report
assert args.parser == parser assert args.parser is not None and args.parser()
def test_run(args: argparse.Namespace, mocker: MockerFixture) -> None: def test_run(args: argparse.Namespace, mocker: MockerFixture) -> None:

View File

@ -188,7 +188,7 @@ def user() -> User:
fixture for user descriptor fixture for user descriptor
:return: user descriptor instance :return: user descriptor instance
""" """
return User("user", "pa55w0rd", UserAccess.Status) return User("user", "pa55w0rd", UserAccess.Read)
@pytest.fixture @pytest.fixture

View File

@ -46,8 +46,8 @@ def test_is_safe_request(auth: Auth) -> None:
must validate safe request must validate safe request
""" """
# login and logout are always safe # login and logout are always safe
assert auth.is_safe_request("/login", UserAccess.Write) assert auth.is_safe_request("/user-api/v1/login", UserAccess.Write)
assert auth.is_safe_request("/logout", UserAccess.Write) assert auth.is_safe_request("/user-api/v1/logout", UserAccess.Write)
auth.allowed_paths.add("/safe") auth.allowed_paths.add("/safe")
auth.allowed_paths_groups.add("/unsafe/safe") auth.allowed_paths_groups.add("/unsafe/safe")

View File

@ -19,7 +19,7 @@ def cleaner(configuration: Configuration, mocker: MockerFixture) -> Cleaner:
:return: cleaner test instance :return: cleaner test instance
""" """
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
return Cleaner("x86_64", configuration) return Cleaner("x86_64", configuration, no_report=True)
@pytest.fixture @pytest.fixture
@ -36,7 +36,7 @@ def executor(configuration: Configuration, mocker: MockerFixture) -> Executor:
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")
return Executor("x86_64", configuration) return Executor("x86_64", configuration, no_report=True)
@pytest.fixture @pytest.fixture
@ -48,7 +48,7 @@ def repository(configuration: Configuration, mocker: MockerFixture) -> Repositor
:return: repository test instance :return: repository test instance
""" """
mocker.patch("pathlib.Path.mkdir") mocker.patch("pathlib.Path.mkdir")
return Repository("x86_64", configuration) return Repository("x86_64", configuration, no_report=True)
@pytest.fixture @pytest.fixture
@ -58,7 +58,7 @@ def properties(configuration: Configuration) -> Properties:
:param configuration: configuration fixture :param configuration: configuration fixture
:return: properties test instance :return: properties test instance
""" """
return Properties("x86_64", configuration) return Properties("x86_64", configuration, no_report=True)
@pytest.fixture @pytest.fixture
@ -75,4 +75,4 @@ def update_handler(configuration: Configuration, mocker: MockerFixture) -> Updat
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")
return UpdateHandler("x86_64", configuration) return UpdateHandler("x86_64", configuration, no_report=True)

View File

@ -2,6 +2,7 @@ from pytest_mock import MockerFixture
from ahriman.core.configuration import Configuration from ahriman.core.configuration import Configuration
from ahriman.core.repository.properties import Properties from ahriman.core.repository.properties import Properties
from ahriman.core.status.web_client import WebClient
def test_create_tree_on_load(configuration: Configuration, mocker: MockerFixture) -> None: def test_create_tree_on_load(configuration: Configuration, mocker: MockerFixture) -> None:
@ -9,6 +10,29 @@ def test_create_tree_on_load(configuration: Configuration, mocker: MockerFixture
must create tree on load must create tree on load
""" """
create_tree_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree") create_tree_mock = mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree")
Properties("x86_64", configuration) Properties("x86_64", configuration, True)
create_tree_mock.assert_called_once() create_tree_mock.assert_called_once()
def test_create_dummy_report_client(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must create dummy report client if report is disabled
"""
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
properties = Properties("x86_64", configuration, True)
load_mock.assert_not_called()
assert not isinstance(properties.reporter, WebClient)
def test_create_full_report_client(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must create load report client if report is enabled
"""
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.create_tree")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
Properties("x86_64", configuration, False)
load_mock.assert_called_once()

View File

@ -5,12 +5,28 @@ from pathlib import Path
from pytest_mock import MockerFixture from pytest_mock import MockerFixture
from unittest.mock import PropertyMock from unittest.mock import PropertyMock
from ahriman.core.configuration import Configuration
from ahriman.core.exceptions import UnknownPackage from ahriman.core.exceptions import UnknownPackage
from ahriman.core.status.watcher import Watcher from ahriman.core.status.watcher import Watcher
from ahriman.core.status.web_client import WebClient
from ahriman.models.build_status import BuildStatus, BuildStatusEnum from ahriman.models.build_status import BuildStatus, BuildStatusEnum
from ahriman.models.package import Package from ahriman.models.package import Package
def test_force_no_report(configuration: Configuration, mocker: MockerFixture) -> None:
"""
must force dummy report client
"""
configuration.set_option("web", "port", "8080")
mocker.patch("pathlib.Path.mkdir")
load_mock = mocker.patch("ahriman.core.status.client.Client.load")
watcher = Watcher("x86_64", configuration)
load_mock.assert_not_called()
assert not isinstance(watcher.repository.reporter, WebClient)
def test_cache_load(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None: def test_cache_load(watcher: Watcher, package_ahriman: Package, mocker: MockerFixture) -> None:
""" """
must load state from cache must load state from cache

View File

@ -7,7 +7,7 @@ def test_from_option(user: User) -> None:
must generate user from options must generate user from options
""" """
assert User.from_option(user.username, user.password) == user assert User.from_option(user.username, user.password) == user
# default is status access # default is read access
user.access = UserAccess.Write user.access = UserAccess.Write
assert User.from_option(user.username, user.password) != user assert User.from_option(user.username, user.password) != user
@ -52,17 +52,6 @@ def test_verify_access_read(user: User) -> None:
user.access = UserAccess.Read user.access = UserAccess.Read
assert user.verify_access(UserAccess.Read) assert user.verify_access(UserAccess.Read)
assert not user.verify_access(UserAccess.Write) assert not user.verify_access(UserAccess.Write)
assert not user.verify_access(UserAccess.Status)
def test_verify_access_status(user: User) -> None:
"""
user with status access must be able to only request status
"""
user.access = UserAccess.Status
assert not user.verify_access(UserAccess.Read)
assert not user.verify_access(UserAccess.Write)
assert user.verify_access(UserAccess.Status)
def test_verify_access_write(user: User) -> None: def test_verify_access_write(user: User) -> None:
@ -72,4 +61,3 @@ def test_verify_access_write(user: User) -> None:
user.access = UserAccess.Write user.access = UserAccess.Write
assert user.verify_access(UserAccess.Read) assert user.verify_access(UserAccess.Read)
assert user.verify_access(UserAccess.Write) assert user.verify_access(UserAccess.Write)
assert user.verify_access(UserAccess.Status)

View File

@ -41,7 +41,7 @@ async def test_auth_handler_api(auth: Auth, mocker: MockerFixture) -> None:
handler = auth_handler(auth) handler = auth_handler(auth)
await handler(aiohttp_request, request_handler) await handler(aiohttp_request, request_handler)
check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Status, aiohttp_request.path) check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Read, aiohttp_request.path)
async def test_auth_handler_api_post(auth: Auth, mocker: MockerFixture) -> None: async def test_auth_handler_api_post(auth: Auth, mocker: MockerFixture) -> None:
@ -55,7 +55,7 @@ async def test_auth_handler_api_post(auth: Auth, mocker: MockerFixture) -> None:
handler = auth_handler(auth) handler = auth_handler(auth)
await handler(aiohttp_request, request_handler) await handler(aiohttp_request, request_handler)
check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Status, aiohttp_request.path) check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Write, aiohttp_request.path)
async def test_auth_handler_read(auth: Auth, mocker: MockerFixture) -> None: async def test_auth_handler_read(auth: Auth, mocker: MockerFixture) -> None:

View File

@ -11,10 +11,10 @@ async def test_post(client_with_auth: TestClient, user: User, mocker: MockerFixt
payload = {"username": user.username, "password": user.password} payload = {"username": user.username, "password": user.password}
remember_mock = mocker.patch("aiohttp_security.remember") remember_mock = mocker.patch("aiohttp_security.remember")
post_response = await client_with_auth.post("/login", json=payload) post_response = await client_with_auth.post("/user-api/v1/login", json=payload)
assert post_response.status == 200 assert post_response.status == 200
post_response = await client_with_auth.post("/login", data=payload) post_response = await client_with_auth.post("/user-api/v1/login", data=payload)
assert post_response.status == 200 assert post_response.status == 200
remember_mock.assert_called() remember_mock.assert_called()
@ -25,7 +25,7 @@ async def test_post_skip(client: TestClient, user: User) -> None:
must process if no auth configured must process if no auth configured
""" """
payload = {"username": user.username, "password": user.password} payload = {"username": user.username, "password": user.password}
post_response = await client.post("/login", json=payload) post_response = await client.post("/user-api/v1/login", json=payload)
assert post_response.status == 200 assert post_response.status == 200
@ -36,6 +36,6 @@ async def test_post_unauthorized(client_with_auth: TestClient, user: User, mocke
payload = {"username": user.username, "password": ""} payload = {"username": user.username, "password": ""}
remember_mock = mocker.patch("aiohttp_security.remember") remember_mock = mocker.patch("aiohttp_security.remember")
post_response = await client_with_auth.post("/login", json=payload) post_response = await client_with_auth.post("/user-api/v1/login", json=payload)
assert post_response.status == 401 assert post_response.status == 401
remember_mock.assert_not_called() remember_mock.assert_not_called()

View File

@ -10,7 +10,7 @@ async def test_post(client_with_auth: TestClient, mocker: MockerFixture) -> None
mocker.patch("aiohttp_security.check_authorized") mocker.patch("aiohttp_security.check_authorized")
forget_mock = mocker.patch("aiohttp_security.forget") forget_mock = mocker.patch("aiohttp_security.forget")
post_response = await client_with_auth.post("/logout") post_response = await client_with_auth.post("/user-api/v1/logout")
assert post_response.status == 200 assert post_response.status == 200
forget_mock.assert_called_once() forget_mock.assert_called_once()
@ -22,7 +22,7 @@ async def test_post_unauthorized(client_with_auth: TestClient, mocker: MockerFix
mocker.patch("aiohttp_security.check_authorized", side_effect=HTTPUnauthorized()) mocker.patch("aiohttp_security.check_authorized", side_effect=HTTPUnauthorized())
forget_mock = mocker.patch("aiohttp_security.forget") forget_mock = mocker.patch("aiohttp_security.forget")
post_response = await client_with_auth.post("/logout") post_response = await client_with_auth.post("/user-api/v1/logout")
assert post_response.status == 401 assert post_response.status == 401
forget_mock.assert_not_called() forget_mock.assert_not_called()
@ -31,5 +31,5 @@ async def test_post_disabled(client: TestClient) -> None:
""" """
must raise exception if auth is disabled must raise exception if auth is disabled
""" """
post_response = await client.post("/logout") post_response = await client.post("/user-api/v1/logout")
assert post_response.status == 200 assert post_response.status == 200