From 236ca4f98ceb00cb736b4cb31245c91670dcf8c9 Mon Sep 17 00:00:00 2001 From: DavHau Date: Fri, 10 Nov 2023 16:07:01 +0700 Subject: [PATCH] api/machines: ensure name is valid hostname --- pkgs/clan-cli/clan_cli/webui/api_inputs.py | 14 ++++++++++++++ pkgs/clan-cli/clan_cli/webui/api_outputs.py | 4 ---- pkgs/clan-cli/clan_cli/webui/routers/machines.py | 7 +++---- pkgs/clan-cli/tests/test_machines_api.py | 12 ++++++++++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/webui/api_inputs.py b/pkgs/clan-cli/clan_cli/webui/api_inputs.py index be3cd0990..8aebe4089 100644 --- a/pkgs/clan-cli/clan_cli/webui/api_inputs.py +++ b/pkgs/clan-cli/clan_cli/webui/api_inputs.py @@ -1,4 +1,5 @@ import logging +import re from pathlib import Path from typing import Any @@ -30,3 +31,16 @@ class MachineConfig(BaseModel): # allow extra fields to cover the full spectrum of a nixos config class Config: extra = Extra.allow + + +class MachineCreate(BaseModel): + name: str + + @classmethod + @validator("name") + def validate_hostname(cls, v: str) -> str: + # Define a regular expression for a valid hostname + hostname_regex = r"^(?!-)[A-Za-z0-9-]{1,63}(? SchemaResponse: - schema = machine_schema(flake_name, config=config) + schema = machine_schema(flake_name, config=dict(config)) return SchemaResponse(schema=schema) diff --git a/pkgs/clan-cli/tests/test_machines_api.py b/pkgs/clan-cli/tests/test_machines_api.py index 33576bdd3..3782ea3be 100644 --- a/pkgs/clan-cli/tests/test_machines_api.py +++ b/pkgs/clan-cli/tests/test_machines_api.py @@ -52,6 +52,18 @@ def test_schema_invalid_clan_imports( assert "non-existing-clan-module" in response.json()["detail"]["modules_not_found"] +def test_create_machine_invalid_hostname( + api: TestClient, test_flake: FlakeForTest +) -> None: + response = api.post( + f"/api/{test_flake.name}/machines", json={"name": "-invalid-hostname"} + ) + assert response.status_code == 422 + assert ( + "Machine name must be a valid hostname" in response.json()["detail"][0]["msg"] + ) + + @pytest.mark.with_core def test_configure_machine(api: TestClient, test_flake_with_core: FlakeForTest) -> None: # ensure error 404 if machine does not exist when accessing the config