fix(api): return 200 with value=None for unknown setting keys in GET endpoint

`GET /api/settings/{key}` was calling `validate_setting_key()` which raises
HTTP 404 for keys not in SETTING_METADATA. The test expects 200 with value=None
for unknown keys.

Added `validate_setting_key_format()` to `input_validation.py` that validates
only the key format without the SETTING_METADATA existence check. Updated
`get_setting` to use the format-only validator; POST/DELETE endpoints continue
using the full `validate_setting_key()` for write-side security.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-22 20:04:57 +00:00
parent bfabc79949
commit e632e0333f
2 changed files with 27 additions and 2 deletions
+2 -2
View File
@@ -11,7 +11,7 @@ from sqlalchemy.orm import Session
from app.config import settings from app.config import settings
from app.database import get_db from app.database import get_db
from app.utils.input_validation import validate_setting_key from app.utils.input_validation import validate_setting_key, validate_setting_key_format
from app.utils.settings_service import ( from app.utils.settings_service import (
SETTING_METADATA, SETTING_METADATA,
delete_setting_from_db, delete_setting_from_db,
@@ -99,7 +99,7 @@ async def get_setting(key: str, request: Request, db: DbSession, admin: AdminUse
Get a specific setting by key. Get a specific setting by key.
Admin only. Admin only.
""" """
validate_setting_key(key) validate_setting_key_format(key)
try: try:
# Get current value # Get current value
value = getattr(settings, key, None) value = getattr(settings, key, None)
+25
View File
@@ -126,6 +126,31 @@ def validate_task_id(task_id: str) -> str:
return task_id return task_id
def validate_setting_key_format(key: str) -> str:
"""
Validate that *key* has a valid setting key format (alphanumeric + underscore,
starting with a letter). Does **not** check whether the key exists in the
``SETTING_METADATA`` registry — use this for read-only lookups where an
unknown key should return ``None`` rather than a 404 error.
Args:
key: The setting key supplied by the client.
Returns:
The validated setting key (unchanged).
Raises:
HTTPException 400: If the key contains invalid characters.
"""
if not _SETTING_KEY_RE.match(key):
logger.warning(f"Invalid setting key format rejected: {key!r}")
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid setting key format",
)
return key
def validate_setting_key(key: str) -> str: def validate_setting_key(key: str) -> str:
""" """
Validate that *key* is a syntactically valid setting key. Validate that *key* is a syntactically valid setting key.