From a5982941df4340aa3e0423d2214d6daf62e5f415 Mon Sep 17 00:00:00 2001 From: mwiegand Date: Mon, 11 May 2026 21:45:03 +0200 Subject: [PATCH] auth: validate_new_password helper (min length 8) Single source of truth for the password policy, to be reused by the upcoming /profile/password endpoint and (optionally) the create-user CLI. Co-Authored-By: Claude Opus 4.7 (1M context) --- l4d2web/auth.py | 11 +++++++++++ l4d2web/tests/test_auth.py | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/l4d2web/auth.py b/l4d2web/auth.py index 718c8d8..8518c94 100644 --- a/l4d2web/auth.py +++ b/l4d2web/auth.py @@ -21,6 +21,17 @@ def verify_password(raw: str, digest: str) -> bool: return check_password_hash(digest, raw) +MIN_PASSWORD_LENGTH = 8 + + +def validate_new_password(raw: str) -> str | None: + if raw == "": + return "password must not be empty" + if len(raw) < MIN_PASSWORD_LENGTH: + return f"password must be at least {MIN_PASSWORD_LENGTH} characters" + return None + + def load_current_user() -> None: user_id = session.get("user_id") if user_id is None: diff --git a/l4d2web/tests/test_auth.py b/l4d2web/tests/test_auth.py index 3101dbb..375970f 100644 --- a/l4d2web/tests/test_auth.py +++ b/l4d2web/tests/test_auth.py @@ -163,6 +163,22 @@ def test_create_user_cli_rejects_empty_environment_password(tmp_path, monkeypatc assert "password must not be empty" in result.output +def test_validate_new_password_rejects_empty(): + from l4d2web.auth import validate_new_password + assert validate_new_password("") == "password must not be empty" + + +def test_validate_new_password_rejects_short(): + from l4d2web.auth import MIN_PASSWORD_LENGTH, validate_new_password + assert MIN_PASSWORD_LENGTH == 8 + assert validate_new_password("a" * 7) == "password must be at least 8 characters" + + +def test_validate_new_password_accepts_min_length(): + from l4d2web.auth import validate_new_password + assert validate_new_password("a" * 8) is None + + def test_create_user_cli_rejects_duplicate_username(tmp_path, monkeypatch) -> None: db_url = f"sqlite:///{tmp_path/'duplicate_user.db'}" monkeypatch.setenv("DATABASE_URL", db_url)