Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,15 @@ def validate_secrets(self) -> "Settings":
if self.environment.lower() != "production":
return self

if self.jwt_secret == "change-this-in-production" or len(self.jwt_secret) < 32:
raise ValueError("Production JWT_SECRET must not use the default and must be at least 32 characters")
jwt_secret = self.jwt_secret.strip()
known_jwt_placeholders = {
"change-this-in-production",
"replace-with-a-long-random-secret",
}
if jwt_secret.lower() in known_jwt_placeholders or len(jwt_secret) < 32:
raise ValueError(
"Production JWT_SECRET must not use a placeholder and must be at least 32 characters"
)

try:
Fernet(self.encryption_key.encode())
Expand Down
20 changes: 19 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from pathlib import Path

import pytest
from cryptography.fernet import Fernet
from pydantic import ValidationError
Expand All @@ -14,6 +16,22 @@ def test_production_rejects_default_jwt_secret() -> None:
)


def test_production_rejects_jwt_placeholder_from_env_example() -> None:
example_file = Path(__file__).resolve().parents[1] / ".env.example"
jwt_secret = next(
line.partition("=")[2]
for line in example_file.read_text(encoding="utf-8").splitlines()
if line.startswith("JWT_SECRET=")
)

with pytest.raises(ValidationError, match="Production JWT_SECRET"):
Settings(
environment="production",
jwt_secret=jwt_secret,
encryption_key=Fernet.generate_key().decode(),
)


def test_production_requires_a_valid_fernet_key() -> None:
with pytest.raises(ValidationError, match="Production ENCRYPTION_KEY"):
Settings(
Expand Down Expand Up @@ -90,6 +108,7 @@ def test_environment_rejects_unknown_values() -> None:
with pytest.raises(ValidationError, match="environment"):
Settings(environment="prod")


def test_production_requires_database_tls() -> None:
with pytest.raises(ValidationError, match="must enable PostgreSQL TLS"):
Settings(
Expand All @@ -99,4 +118,3 @@ def test_production_requires_database_tls() -> None:
encryption_key=Fernet.generate_key().decode(),
rate_limit_storage_uri="redis://localhost:6379/0",
)

Loading