From 24877df9761a1d20abca631c1e016d6a4a90c380 Mon Sep 17 00:00:00 2001 From: Dmitrii Iurco Date: Mon, 11 May 2026 06:08:55 -0400 Subject: [PATCH] Fix setup wizard and installer for fresh-install flow - setup_manager: fall back to update_password if admin already exists (installer bootstrap creates admin; wizard now updates rather than fails) - install.sh: chown repo to SUDO_USER instead of pic user so the invoking operator can run make update without git safe.directory errors - test: update mock to also stub update_password when testing total auth failure Co-Authored-By: Claude Sonnet 4.6 --- api/setup_manager.py | 9 +++++++-- install.sh | 9 +++++---- tests/test_setup_manager.py | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/api/setup_manager.py b/api/setup_manager.py index dfb6855..fed16f7 100644 --- a/api/setup_manager.py +++ b/api/setup_manager.py @@ -168,14 +168,19 @@ class SetupManager: if self.is_setup_complete(): return {'success': False, 'errors': ['Setup has already been completed.']} - # ── create admin user ────────────────────────────────────────── + # ── create or update admin user ──────────────────────────────── + # The installer may have bootstrapped an admin account from a + # generated password. The wizard's job is to set the real password, + # so update it if the account already exists. ok = self.auth_manager.create_user( username='admin', password=password, role='admin', ) if not ok: - return {'success': False, 'errors': ['Failed to create admin user. The username may already exist.']} + ok = self.auth_manager.update_password('admin', password) + if not ok: + return {'success': False, 'errors': ['Failed to set admin password.']} # ── persist identity fields ──────────────────────────────────── self.config_manager.set_identity_field('cell_name', cell_name) diff --git a/install.sh b/install.sh index a1f1c0a..9a59ff3 100755 --- a/install.sh +++ b/install.sh @@ -245,10 +245,11 @@ else log_ok "Repository cloned to ${PIC_DIR}" fi -# Ensure the pic user owns the directory -chown -R "${PIC_USER}:${PIC_USER}" "$PIC_DIR" -# Allow any user to run git commands in this directory (installer runs as root, -# operators run as themselves — git safe.directory prevents ownership errors) +# Give the invoking user (or pic if run directly as root) ownership of the repo +# so they can run `make update` and other git commands without sudo. +REPO_OWNER="${SUDO_USER:-${PIC_USER}}" +chown -R "${REPO_OWNER}:${REPO_OWNER}" "$PIC_DIR" +# Allow all users to run git commands here regardless of who owns the files git config --system --add safe.directory "$PIC_DIR" 2>/dev/null || true # --------------------------------------------------------------------------- diff --git a/tests/test_setup_manager.py b/tests/test_setup_manager.py index 693df64..c21e55e 100644 --- a/tests/test_setup_manager.py +++ b/tests/test_setup_manager.py @@ -252,10 +252,11 @@ def test_complete_setup_returns_error_when_create_user_fails( setup_manager, mock_config_manager, mock_auth_manager, tmp_path): mock_config_manager.get_identity.return_value = {} mock_auth_manager.create_user.return_value = False + mock_auth_manager.update_password.return_value = False with patch.dict(os.environ, {'DATA_DIR': str(tmp_path)}): result = setup_manager.complete_setup(_valid_payload()) assert result['success'] is False - assert any('admin' in e.lower() or 'user' in e.lower() for e in result['errors']) + assert any('admin' in e.lower() or 'password' in e.lower() for e in result['errors']) # ── get_setup_status ──────────────────────────────────────────────────────────