60c692cefc
Allows any authenticated user to update their own full_name, avatar, notification_channels, and password via the config YAML write path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
86 lines
3.3 KiB
Python
86 lines
3.3 KiB
Python
"""Tests for PUT /api/0/users/me logic."""
|
|
import pytest
|
|
from hbd.server import users as users_mod
|
|
|
|
|
|
def test_hash_password_roundtrip():
|
|
h = users_mod.hash_password("mysecret")
|
|
assert h.startswith("pbkdf2:sha256:")
|
|
assert users_mod.authenticate.__doc__ is not None # module loaded
|
|
|
|
|
|
def test_password_change_requires_correct_current(tmp_path):
|
|
cfg = tmp_path / ".hb.yaml"
|
|
initial_hash = users_mod.hash_password("oldpass")
|
|
cfg.write_text(
|
|
f"hbd_port: 50004\nusers:\n alice:\n full_name: Alice\n admin: true\n password: {initial_hash}\n"
|
|
)
|
|
users_mod.load_users({"users": {"alice": {"full_name": "Alice", "admin": True, "password": initial_hash}}})
|
|
|
|
# Correct current password authenticates
|
|
assert users_mod.authenticate("alice", "oldpass") is not None
|
|
# Wrong current password does not authenticate
|
|
assert users_mod.authenticate("alice", "wrongpass") is None
|
|
|
|
|
|
def test_put_users_me_writes_new_fields(tmp_path):
|
|
"""Simulate the write path: read config, update user, write back."""
|
|
initial_hash = users_mod.hash_password("secret")
|
|
yaml_content = (
|
|
"hbd_port: 50004\n"
|
|
f"users:\n alice:\n full_name: Old Name\n admin: true\n password: {initial_hash}\n"
|
|
)
|
|
cfg = tmp_path / ".hb.yaml"
|
|
cfg.write_text(yaml_content)
|
|
|
|
from hbd.server import configio
|
|
data = configio.read_roundtrip(str(cfg))
|
|
|
|
# Simulate handler updating full_name and avatar
|
|
user_entry = dict(data["users"]["alice"])
|
|
user_entry["full_name"] = "New Name"
|
|
user_entry["avatar"] = "/img/alice.png"
|
|
data["users"]["alice"] = user_entry
|
|
|
|
configio.write_config(str(cfg), data)
|
|
result = configio.read_roundtrip(str(cfg))
|
|
assert result["users"]["alice"]["full_name"] == "New Name"
|
|
assert result["users"]["alice"]["avatar"] == "/img/alice.png"
|
|
assert result["users"]["alice"]["password"] == initial_hash # unchanged
|
|
|
|
|
|
def test_put_users_me_changes_password(tmp_path):
|
|
initial_hash = users_mod.hash_password("oldpass")
|
|
cfg = tmp_path / ".hb.yaml"
|
|
cfg.write_text(
|
|
f"hbd_port: 50004\nusers:\n alice:\n full_name: Alice\n password: {initial_hash}\n"
|
|
)
|
|
from hbd.server import configio
|
|
data = configio.read_roundtrip(str(cfg))
|
|
|
|
new_hash = users_mod.hash_password("newpass")
|
|
data["users"]["alice"]["password"] = new_hash
|
|
configio.write_config(str(cfg), data)
|
|
|
|
result = configio.read_roundtrip(str(cfg))
|
|
# Load users from new config and authenticate with new password
|
|
new_config = {"users": dict(result["users"])}
|
|
users_mod.load_users(new_config)
|
|
assert users_mod.authenticate("alice", "newpass") is not None
|
|
assert users_mod.authenticate("alice", "oldpass") is None
|
|
|
|
|
|
def test_put_users_me_notification_channels(tmp_path):
|
|
cfg = tmp_path / ".hb.yaml"
|
|
cfg.write_text(
|
|
"hbd_port: 50004\n"
|
|
"notification_channels:\n pushover_ops:\n type: pushover\n"
|
|
"users:\n alice:\n full_name: Alice\n notification_channels: []\n"
|
|
)
|
|
from hbd.server import configio
|
|
data = configio.read_roundtrip(str(cfg))
|
|
data["users"]["alice"]["notification_channels"] = ["pushover_ops"]
|
|
configio.write_config(str(cfg), data)
|
|
result = configio.read_roundtrip(str(cfg))
|
|
assert result["users"]["alice"]["notification_channels"] == ["pushover_ops"]
|