cli: apply min-length password policy in create-user
Same validate_new_password used by the web change-password flow, so the policy is enforced uniformly across CLI and HTTP entry points. Existing CLI tests bumped to passwords that satisfy the new floor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
224b023ca0
commit
f643246a84
2 changed files with 19 additions and 5 deletions
|
|
@ -5,7 +5,7 @@ import click
|
|||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy import select
|
||||
|
||||
from l4d2web.auth import hash_password
|
||||
from l4d2web.auth import hash_password, validate_new_password
|
||||
from l4d2web.db import session_scope
|
||||
from l4d2web.models import Overlay, User
|
||||
from l4d2web.services.overlay_creation import (
|
||||
|
|
@ -31,8 +31,9 @@ def create_user(username: str, admin: bool) -> None:
|
|||
password = os.getenv("LEFT4ME_ADMIN_PASSWORD")
|
||||
if password is None:
|
||||
password = click.prompt("Password", hide_input=True, confirmation_prompt=True)
|
||||
if password == "":
|
||||
raise click.ClickException("password must not be empty")
|
||||
policy_error = validate_new_password(password)
|
||||
if policy_error is not None:
|
||||
raise click.ClickException(policy_error)
|
||||
|
||||
try:
|
||||
with session_scope() as db:
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ def test_login_stamps_password_changed_at_in_session(client) -> None:
|
|||
def test_create_user_cli_uses_environment_password(tmp_path, monkeypatch) -> None:
|
||||
db_url = f"sqlite:///{tmp_path/'create_user.db'}"
|
||||
monkeypatch.setenv("DATABASE_URL", db_url)
|
||||
monkeypatch.setenv("LEFT4ME_ADMIN_PASSWORD", "secret")
|
||||
monkeypatch.setenv("LEFT4ME_ADMIN_PASSWORD", "secretpw1")
|
||||
app = create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})
|
||||
init_db()
|
||||
|
||||
|
|
@ -215,6 +215,19 @@ def test_create_user_cli_uses_environment_password(tmp_path, monkeypatch) -> Non
|
|||
assert user.admin is True
|
||||
|
||||
|
||||
def test_create_user_cli_rejects_short_password(tmp_path, monkeypatch) -> None:
|
||||
db_url = f"sqlite:///{tmp_path/'short_pw.db'}"
|
||||
monkeypatch.setenv("DATABASE_URL", db_url)
|
||||
monkeypatch.setenv("LEFT4ME_ADMIN_PASSWORD", "short7x")
|
||||
app = create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})
|
||||
init_db()
|
||||
|
||||
result = app.test_cli_runner().invoke(args=["create-user", "admin", "--admin"])
|
||||
|
||||
assert result.exit_code != 0
|
||||
assert "at least 8" in result.output
|
||||
|
||||
|
||||
def test_create_user_cli_rejects_empty_environment_password(tmp_path, monkeypatch) -> None:
|
||||
db_url = f"sqlite:///{tmp_path/'empty_password.db'}"
|
||||
monkeypatch.setenv("DATABASE_URL", db_url)
|
||||
|
|
@ -247,7 +260,7 @@ def test_validate_new_password_accepts_min_length():
|
|||
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)
|
||||
monkeypatch.setenv("LEFT4ME_ADMIN_PASSWORD", "secret")
|
||||
monkeypatch.setenv("LEFT4ME_ADMIN_PASSWORD", "secretpw1")
|
||||
app = create_app({"TESTING": True, "DATABASE_URL": db_url, "SECRET_KEY": "test"})
|
||||
init_db()
|
||||
with session_scope() as session:
|
||||
|
|
|
|||
Loading…
Reference in a new issue