From 0e6ad1c4430bf8a32900d6bd6fc49ee56a5ffdb3 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Thu, 14 May 2026 01:13:46 +0800 Subject: [PATCH] feat: cli supports ASTRBOT_DASHBOARD_INITIAL_PASSWORD env --- astrbot/cli/commands/cmd_init.py | 15 +++++++++ tests/test_cli_init.py | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tests/test_cli_init.py diff --git a/astrbot/cli/commands/cmd_init.py b/astrbot/cli/commands/cmd_init.py index e7e047cca..502999c43 100644 --- a/astrbot/cli/commands/cmd_init.py +++ b/astrbot/cli/commands/cmd_init.py @@ -1,4 +1,5 @@ import asyncio +import os from pathlib import Path import click @@ -6,6 +7,18 @@ from filelock import FileLock, Timeout from ..utils import check_dashboard, get_astrbot_root +DASHBOARD_INITIAL_PASSWORD_ENV = "ASTRBOT_DASHBOARD_INITIAL_PASSWORD" + + +def _initialize_config_from_env(astrbot_root: Path) -> None: + if DASHBOARD_INITIAL_PASSWORD_ENV not in os.environ: + return + + from astrbot.core.config.astrbot_config import AstrBotConfig + + AstrBotConfig(config_path=str(astrbot_root / "data" / "cmd_config.json")) + click.echo("Initialized data/cmd_config.json with dashboard initial password.") + async def initialize_astrbot(astrbot_root: Path) -> None: """Execute AstrBot initialization logic""" @@ -31,6 +44,8 @@ async def initialize_astrbot(astrbot_root: Path) -> None: path.mkdir(parents=True, exist_ok=True) click.echo(f"{'Created' if not path.exists() else 'Directory exists'}: {path}") + _initialize_config_from_env(astrbot_root) + await check_dashboard(astrbot_root / "data") diff --git a/tests/test_cli_init.py b/tests/test_cli_init.py new file mode 100644 index 000000000..f68ddf059 --- /dev/null +++ b/tests/test_cli_init.py @@ -0,0 +1,54 @@ +import json + +import pytest + +from astrbot.cli.commands import cmd_init +from astrbot.core.utils.auth_password import verify_dashboard_password + + +@pytest.mark.asyncio +async def test_init_without_initial_password_env_does_not_create_config( + monkeypatch, + tmp_path, +): + async def fake_check_dashboard(_data_path): + return None + + monkeypatch.delenv(cmd_init.DASHBOARD_INITIAL_PASSWORD_ENV, raising=False) + monkeypatch.setattr(cmd_init, "check_dashboard", fake_check_dashboard) + (tmp_path / ".astrbot").touch() + + await cmd_init.initialize_astrbot(tmp_path) + + assert not (tmp_path / "data" / "cmd_config.json").exists() + + +@pytest.mark.asyncio +async def test_init_uses_initial_password_env_to_create_config( + monkeypatch, + tmp_path, +): + async def fake_check_dashboard(_data_path): + return None + + initial_password = "AstrBotInitialPassword123" + monkeypatch.setenv(cmd_init.DASHBOARD_INITIAL_PASSWORD_ENV, initial_password) + monkeypatch.setattr(cmd_init, "check_dashboard", fake_check_dashboard) + (tmp_path / ".astrbot").touch() + + await cmd_init.initialize_astrbot(tmp_path) + + config_path = tmp_path / "data" / "cmd_config.json" + config = json.loads(config_path.read_text(encoding="utf-8-sig")) + dashboard_config = config["dashboard"] + + assert verify_dashboard_password( + dashboard_config["pbkdf2_password"], + initial_password, + ) + assert verify_dashboard_password( + dashboard_config["password"], + initial_password, + ) + assert dashboard_config["password_change_required"] is True + assert dashboard_config["password_storage_upgraded"] is True