From ced83a31e999f17382ae70fe052a50f2842e525d Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Mon, 15 Sep 2025 17:59:26 -0700 Subject: [PATCH] zoph: Fix cases when CLI user is set to "autodetect" Closes: #2538 Tests: - Without the patch, set the Zoph CLI User to "autodetect" and notice the failure to load Zoph page. - With the patch, set user to "autodetect" and access the app page. It is updated to the first admin user in Zoph DB. - Try with updating Zoph configuration. - Try with re-running Zoph setup. Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/db/mariadb.py | 17 ++++++++++++ plinth/modules/zoph/privileged.py | 45 ++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 plinth/db/mariadb.py diff --git a/plinth/db/mariadb.py b/plinth/db/mariadb.py new file mode 100644 index 000000000..d7680c34e --- /dev/null +++ b/plinth/db/mariadb.py @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Utilities to help with MariaDB/MySQL databases. + +Uses utilities from 'mysql-client' package such as 'mysql' and 'mysqldump'. +""" + +import subprocess + + +def run_query(database_name: str, query: str) -> subprocess.CompletedProcess: + """Run a database query using 'root' user. + + Does not ensure that the database server is running. + """ + return subprocess.run( + ['mysql', '--user=root', '--database', database_name], + input=query.encode('utf-8'), check=True) diff --git a/plinth/modules/zoph/privileged.py b/plinth/modules/zoph/privileged.py index 72ee20209..6ed2eefe8 100644 --- a/plinth/modules/zoph/privileged.py +++ b/plinth/modules/zoph/privileged.py @@ -9,6 +9,7 @@ import subprocess from plinth import action_utils from plinth.actions import privileged +from plinth.db import mariadb APACHE_CONF = '/etc/apache2/conf-available/zoph.conf' DB_CONF = pathlib.Path('/etc/zoph.ini') @@ -31,8 +32,17 @@ def pre_install(): def get_configuration() -> dict[str, str]: """Return the current configuration.""" configuration = {} - process = subprocess.run(['zoph', '--dump-config'], stdout=subprocess.PIPE, - check=True) + try: + process = subprocess.run(['zoph', '--dump-config'], + stdout=subprocess.PIPE, check=True) + except subprocess.CalledProcessError as exception: + if exception.returncode != 96: + raise + + _zoph_setup_cli_user() + process = subprocess.run(['zoph', '--dump-config'], + stdout=subprocess.PIPE, check=True) + for line in process.stdout.decode().splitlines(): name, value = line.partition(':')[::2] configuration[name.strip()] = value[1:] @@ -40,9 +50,38 @@ def get_configuration() -> dict[str, str]: return configuration +def _zoph_setup_cli_user() -> None: + """Ensure that Zoph cli user is not set to 'autodetect'. + + When set to 'autodetect', all command line commands will fail unless a user + name 'root' exists in zoph database and is an admin user. + """ + query = ''' +UPDATE + zoph_conf +SET + value=( + SELECT user_id + FROM zoph_users + WHERE user_class="0" + ORDER BY user_id + LIMIT 1) +WHERE + conf_id='interface.user.cli';''' + database_name = _get_db_config()['db_name'] + mariadb.run_query(database_name, query) + + def _zoph_configure(key, value): """Set a configure value in Zoph.""" - subprocess.run(['zoph', '--config', key, value], check=True) + try: + subprocess.run(['zoph', '--config', key, value], check=True) + except subprocess.CalledProcessError as exception: + if exception.returncode != 96: + raise + + _zoph_setup_cli_user() + subprocess.run(['zoph', '--config', key, value], check=True) @privileged