Automated Action 493289730d Add secure SECRET_KEY generation and improve key documentation
- Update config.py to auto-generate a secure SECRET_KEY if not provided
- Add warning log when using an auto-generated key
- Update README with clearer information about the two different keys
- Add detailed security notes explaining each key's purpose
2025-05-27 18:57:18 +00:00

58 lines
1.9 KiB
Python

from typing import List, Union
import logging
import secrets
from pathlib import Path
from pydantic import AnyHttpUrl, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
logger = logging.getLogger(__name__)
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", case_sensitive=True)
API_V1_STR: str = "/api/v1"
PROJECT_NAME: str = "News Aggregation Service"
VERSION: str = "0.1.0"
DESCRIPTION: str = "A service that aggregates news from various sources using the Mediastack API"
# CORS
BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []
@field_validator("BACKEND_CORS_ORIGINS", mode="before")
@classmethod
def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
if isinstance(v, str) and not v.startswith("["):
return [i.strip() for i in v.split(",")]
elif isinstance(v, (list, str)):
return v
raise ValueError(v)
# Mediastack API
MEDIASTACK_API_KEY: str = ""
MEDIASTACK_BASE_URL: str = "http://api.mediastack.com/v1"
# Security
SECRET_KEY: str = ""
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days
@field_validator("SECRET_KEY", mode="before")
@classmethod
def generate_secret_key_if_needed(cls, v: str) -> str:
"""Generate a secure secret key if none is provided."""
if not v:
generated_key = secrets.token_hex(32)
logger.warning(
"No SECRET_KEY provided. Using a randomly generated key. "
"This is OK for development but not recommended for production. "
"The authentication tokens will be invalidated on server restart."
)
return generated_key
return v
# Database
DATABASE_PATH: Path = Path("/projects/newsaggregationservice-ks0ts2/app/storage/db/db.sqlite")
settings = Settings()