From 2c5fbcc2fd1954c788c215f6c014b15913c81bc4 Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Sat, 29 Jan 2022 09:52:08 +0100 Subject: [PATCH] Encrypt the OBS password on first run This makes sure it is at least not stored in plaintext somewhere. --- oscbot/__init__.py | 61 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/oscbot/__init__.py b/oscbot/__init__.py index 43cc5a3..9c21962 100644 --- a/oscbot/__init__.py +++ b/oscbot/__init__.py @@ -1,10 +1,11 @@ # SPDX-FileCopyrightText: 2022 Luca Beltrame # SPDX-License-Identifier: AGPL-3.0-or-later -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import Optional, List, Type, Tuple import aiohttp +import cryptocode from lxml import objectify from jinja2 import BaseLoader, Environment @@ -46,7 +47,7 @@ class BuildResult: class BuildRepository: name: str arch: str - packages: List[BuildResult] + packages: List[BuildResult] = field(default_factory=list) class Config(BaseProxyConfig): @@ -56,8 +57,17 @@ class Config(BaseProxyConfig): helper.copy("instance_url") helper.copy("rebuild_token") helper.copy("trigger_token") + helper.copy("secret") + + password = self["password"] + if len(password) < 91 and not password.endswith("=="): + encrypted_password = cryptocode.encrypt(password, self["secret"]) + helper.base["password"] = encrypted_password + else: + helper.copy("password") + helper.copy("username") - helper.copy("password") + helper.copy("repo_aliases") class OSCBot(Plugin): @@ -76,6 +86,19 @@ class OSCBot(Plugin): def get_config_class(cls) -> Type[BaseProxyConfig]: return Config + def get_alias(self, project_alias: str) -> Tuple[str, str, str, str, str]: + data = self.config["repo_aliases"][project_alias] + # There is no concept of non-positional arguments in maubot + # So we just use "all" in case we want to skip something + package = data["package"] if data["package"] != "all" else None + repository = (data["repository"] if data["repository"] != "all" + else None) + arch = data["arch"] if data["arch"] != "all" else None + project = data["project"] + state = data["state"] if data["state"] != "all" else None + + return (project, package, repository, state, arch) + async def parse_rebuilpac( self, project: str, @@ -112,7 +135,8 @@ class OSCBot(Plugin): arch: Optional[str] = None) -> List[BuildRepository]: username = self.config["username"] - password = self.config["password"] + password = cryptocode.decrypt(self.config["password"], + self.config["secret"]) api_url = self.config["api_url"] api_call = f"{api_url}/build/{project}/_result" @@ -179,7 +203,7 @@ class OSCBot(Plugin): @osc.subcommand( "rebuildpac", aliases=("rb",), help="Rebuild a package or all packages in the repositories") - @command.argument("project", "project name") + @command.argument("project", "project name/alias") @command.argument("package", "package name (or \"all\" for all packages)") @command.argument("repository", "repository (optional)", required=False) @command.argument("arch", "architecture (optional)", required=False) @@ -189,12 +213,9 @@ class OSCBot(Plugin): repository: Optional[str] = None, arch: Optional[str] = None) -> None: - if package == "all": - package = None - if repository == "all": - repository = None - if arch == "all": - arch = None + package = None if package == "all" else package + repository = None if repository == "all" else repository + arch = None if arch == "all" else arch result, status = await self.parse_rebuilpac(project, package, repository, @@ -244,16 +265,14 @@ class OSCBot(Plugin): repository: Optional[str] = None, arch: Optional[str] = None) -> None: - # There is no concept of non-positional arguments in maubot - # So we just use "all" in case we want to skip something - if state == "all": - state = None - if package == "all": - package = None - if repository == "all": - repository = None - if arch == "all": - arch = None + if project in self.config["repo_aliases"]: + project, package, repository, state, arch = self.get_alias(project) + else: + # There is no concept of non-positional arguments in maubot + # So we just use "all" in case we want to skip something + package = None if package == "all" else package + repository = None if repository == "all" else repository + arch = None if arch == "all" else arch response = await self.parse_status(project, package, state=state, repo=repository, arch=arch)