mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix: validate dashboard account username updates (#9175)
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
This commit is contained in:
@@ -369,6 +369,12 @@ class AuthService:
|
||||
if not new_pwd and not new_username:
|
||||
return self.error("新用户名和新密码不能同时为空")
|
||||
|
||||
username_to_save = None
|
||||
if new_username is not None and new_username != "":
|
||||
if not isinstance(new_username, str) or len(new_username.strip()) < 3:
|
||||
return self.error("用户名长度至少3位")
|
||||
username_to_save = new_username.strip()
|
||||
|
||||
if new_pwd:
|
||||
if not isinstance(new_pwd, str):
|
||||
return self.error("新密码无效")
|
||||
@@ -384,8 +390,8 @@ class AuthService:
|
||||
await set_password_change_required(self.db, self.config, False)
|
||||
if is_totp_enabled(self.config):
|
||||
await revoke_user_trusted_devices(self.db)
|
||||
if new_username:
|
||||
self.config["dashboard"]["username"] = new_username
|
||||
if username_to_save:
|
||||
self.config["dashboard"]["username"] = username_to_save
|
||||
|
||||
self.config.save_config()
|
||||
|
||||
|
||||
@@ -1360,6 +1360,105 @@ async def test_generated_password_requires_password_change_until_changed(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("endpoint", "method"),
|
||||
[
|
||||
("/api/auth/account/edit", "post"),
|
||||
("/api/v1/auth/account", "patch"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("new_username", ["ab", " "])
|
||||
async def test_account_edit_rejects_invalid_username(
|
||||
app: FastAPIAppAdapter,
|
||||
core_lifecycle_td: AstrBotCoreLifecycle,
|
||||
endpoint: str,
|
||||
method: str,
|
||||
new_username: str,
|
||||
):
|
||||
original_dashboard_config = copy.deepcopy(
|
||||
core_lifecycle_td.astrbot_config["dashboard"]
|
||||
)
|
||||
test_client = app.test_client()
|
||||
current_username = core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
current_password = _resolve_dashboard_password(core_lifecycle_td)
|
||||
|
||||
try:
|
||||
login_response = await test_client.post(
|
||||
"/api/auth/login",
|
||||
json={"username": current_username, "password": current_password},
|
||||
)
|
||||
login_data = await login_response.get_json()
|
||||
assert login_data["status"] == "ok"
|
||||
headers = {"Authorization": f"Bearer {login_data['data']['token']}"}
|
||||
|
||||
payload = {
|
||||
"password": current_password,
|
||||
"new_password": "",
|
||||
"confirm_password": "",
|
||||
"new_username": new_username,
|
||||
}
|
||||
request = getattr(test_client, method)
|
||||
response = await request(endpoint, headers=headers, json=payload)
|
||||
data = await response.get_json()
|
||||
|
||||
assert data["status"] == "error"
|
||||
assert data["message"] == "用户名长度至少3位"
|
||||
assert (
|
||||
core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
== (original_dashboard_config["username"])
|
||||
)
|
||||
finally:
|
||||
await _restore_dashboard_password_state(
|
||||
core_lifecycle_td,
|
||||
original_dashboard_config,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_account_edit_trims_valid_username(
|
||||
app: FastAPIAppAdapter,
|
||||
core_lifecycle_td: AstrBotCoreLifecycle,
|
||||
):
|
||||
original_dashboard_config = copy.deepcopy(
|
||||
core_lifecycle_td.astrbot_config["dashboard"]
|
||||
)
|
||||
test_client = app.test_client()
|
||||
current_username = core_lifecycle_td.astrbot_config["dashboard"]["username"]
|
||||
current_password = _resolve_dashboard_password(core_lifecycle_td)
|
||||
|
||||
try:
|
||||
login_response = await test_client.post(
|
||||
"/api/auth/login",
|
||||
json={"username": current_username, "password": current_password},
|
||||
)
|
||||
login_data = await login_response.get_json()
|
||||
assert login_data["status"] == "ok"
|
||||
headers = {"Authorization": f"Bearer {login_data['data']['token']}"}
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/auth/account/edit",
|
||||
headers=headers,
|
||||
json={
|
||||
"password": current_password,
|
||||
"new_password": "",
|
||||
"confirm_password": "",
|
||||
"new_username": " astrbot-admin ",
|
||||
},
|
||||
)
|
||||
data = await response.get_json()
|
||||
|
||||
assert data["status"] == "ok"
|
||||
assert core_lifecycle_td.astrbot_config["dashboard"]["username"] == (
|
||||
"astrbot-admin"
|
||||
)
|
||||
finally:
|
||||
await _restore_dashboard_password_state(
|
||||
core_lifecycle_td,
|
||||
original_dashboard_config,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_local_setup_can_skip_default_password_auth(
|
||||
app: FastAPIAppAdapter,
|
||||
|
||||
Reference in New Issue
Block a user