fix: use model_validator for API keys validation
Changed from field_validator to model_validator to properly access auth_enabled field during validation. This fixes the SettingsError when parsing mcp_api_keys from environment variables. Also improved handling of empty strings and None values.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from pydantic import Field, HttpUrl, field_validator
|
from pydantic import Field, HttpUrl, field_validator, model_validator
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +109,12 @@ class Settings(BaseSettings):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def parse_api_keys(cls, v: object) -> List[str]:
|
def parse_api_keys(cls, v: object) -> List[str]:
|
||||||
"""Parse API keys from comma-separated string or list."""
|
"""Parse API keys from comma-separated string or list."""
|
||||||
|
if v is None:
|
||||||
|
return []
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
|
# Empty string returns empty list
|
||||||
|
if not v.strip():
|
||||||
|
return []
|
||||||
# Split by comma and strip whitespace
|
# Split by comma and strip whitespace
|
||||||
keys = [key.strip() for key in v.split(",") if key.strip()]
|
keys = [key.strip() for key in v.split(",") if key.strip()]
|
||||||
return keys
|
return keys
|
||||||
@@ -117,28 +122,24 @@ class Settings(BaseSettings):
|
|||||||
return v
|
return v
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@field_validator("mcp_api_keys")
|
@model_validator(mode="after")
|
||||||
@classmethod
|
def validate_api_keys_if_auth_enabled(self) -> "Settings":
|
||||||
def validate_api_keys(cls, v: List[str], info) -> List[str]:
|
|
||||||
"""Validate API keys if authentication is enabled."""
|
"""Validate API keys if authentication is enabled."""
|
||||||
# Get auth_enabled from values (it's already been processed)
|
if self.auth_enabled and not self.mcp_api_keys:
|
||||||
auth_enabled = info.data.get("auth_enabled", True)
|
|
||||||
|
|
||||||
if auth_enabled and not v:
|
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"At least one API key must be configured when auth_enabled=True. "
|
"At least one API key must be configured when auth_enabled=True. "
|
||||||
"Set MCP_API_KEYS environment variable or disable auth with AUTH_ENABLED=false"
|
"Set MCP_API_KEYS environment variable or disable auth with AUTH_ENABLED=false"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate key format (at least 32 characters for security)
|
# Validate key format (at least 32 characters for security)
|
||||||
for key in v:
|
for key in self.mcp_api_keys:
|
||||||
if len(key) < 32:
|
if len(key) < 32:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"API keys must be at least 32 characters long. "
|
f"API keys must be at least 32 characters long. "
|
||||||
f"Use scripts/generate_api_key.py to generate secure keys."
|
f"Use scripts/generate_api_key.py to generate secure keys."
|
||||||
)
|
)
|
||||||
|
|
||||||
return v
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gitea_base_url(self) -> str:
|
def gitea_base_url(self) -> str:
|
||||||
|
|||||||
Reference in New Issue
Block a user