diff --git a/l4d2web/routes/server_routes.py b/l4d2web/routes/server_routes.py index d778032..7a6d02c 100644 --- a/l4d2web/routes/server_routes.py +++ b/l4d2web/routes/server_routes.py @@ -1,3 +1,5 @@ +import secrets + from flask import Blueprint, Response, current_app, jsonify, redirect, request from sqlalchemy import select from sqlalchemy.exc import IntegrityError @@ -90,6 +92,7 @@ def create_server() -> Response: desired_state="stopped", actual_state="unknown", last_error="", + rcon_password=secrets.token_urlsafe(32), ) db.add(server) diff --git a/l4d2web/tests/test_servers.py b/l4d2web/tests/test_servers.py index b08286a..2cd35a6 100644 --- a/l4d2web/tests/test_servers.py +++ b/l4d2web/tests/test_servers.py @@ -427,6 +427,25 @@ def test_lifecycle_form_creates_queued_job(user_client_with_blueprints) -> None: assert response.headers["Location"] == f"/servers/{server_id}" +def test_create_server_generates_rcon_password(user_client_with_blueprints) -> None: + from sqlalchemy import select + + from l4d2web.models import Server + + client, data = user_client_with_blueprints + res = client.post( + "/servers", + data={"name": "fresh", "blueprint_id": str(data["blueprint_id"])}, + headers={"X-CSRF-Token": "test-token"}, + ) + assert res.status_code in (200, 201, 302) + + with session_scope() as db: + row = db.scalar(select(Server).where(Server.name == "fresh")) + assert row is not None + assert len(row.rcon_password) >= 32 + + def test_reset_operation_enqueues_job_and_stops_desired_state(user_client_with_blueprints) -> None: from sqlalchemy import select