feat(slice-2): config — session secret, cookie_secure, mailer_kind (INV-8)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,3 +17,24 @@ _DEFAULT_DATABASE_URL = "postgresql://ecomm:ecomm@localhost:5432/ecomm"
|
|||||||
def database_url() -> str:
|
def database_url() -> str:
|
||||||
"""The psycopg DSN for the application database."""
|
"""The psycopg DSN for the application database."""
|
||||||
return os.environ.get("ECOMM_DATABASE_URL") or _DEFAULT_DATABASE_URL
|
return os.environ.get("ECOMM_DATABASE_URL") or _DEFAULT_DATABASE_URL
|
||||||
|
|
||||||
|
|
||||||
|
# Session signing secret. Dev default is intentionally well-known and insecure — a clean
|
||||||
|
# checkout works with no setup; deployed environments MUST supply ECOMM_SESSION_SECRET from
|
||||||
|
# Secret Manager (INV-8, §6.6). Rotating it invalidates all sessions at once (§6.2).
|
||||||
|
_DEFAULT_SESSION_SECRET = "dev-insecure-session-secret-change-me"
|
||||||
|
|
||||||
|
|
||||||
|
def session_secret() -> str:
|
||||||
|
"""The HMAC key for signed session cookies (and the one-time-code pepper)."""
|
||||||
|
return os.environ.get("ECOMM_SESSION_SECRET") or _DEFAULT_SESSION_SECRET
|
||||||
|
|
||||||
|
|
||||||
|
def cookie_secure() -> bool:
|
||||||
|
"""Whether to mark the session cookie Secure (HTTPS-only). True in deployed envs."""
|
||||||
|
return os.environ.get("ECOMM_COOKIE_SECURE", "").strip().lower() in {"1", "true", "yes", "on"}
|
||||||
|
|
||||||
|
|
||||||
|
def mailer_kind() -> str:
|
||||||
|
"""Which mailer adapter to build: 'log' (dev/tests) or 'smtp' (deployed; SLICE-4)."""
|
||||||
|
return os.environ.get("ECOMM_MAILER") or "log"
|
||||||
|
|||||||
@@ -11,3 +11,33 @@ def test_database_url_defaults_to_local_compose(monkeypatch):
|
|||||||
def test_database_url_honors_env(monkeypatch):
|
def test_database_url_honors_env(monkeypatch):
|
||||||
monkeypatch.setenv("ECOMM_DATABASE_URL", "postgresql://x:y@db:5432/z")
|
monkeypatch.setenv("ECOMM_DATABASE_URL", "postgresql://x:y@db:5432/z")
|
||||||
assert config.database_url() == "postgresql://x:y@db:5432/z"
|
assert config.database_url() == "postgresql://x:y@db:5432/z"
|
||||||
|
|
||||||
|
|
||||||
|
def test_session_secret_defaults_for_dev(monkeypatch):
|
||||||
|
monkeypatch.delenv("ECOMM_SESSION_SECRET", raising=False)
|
||||||
|
# A non-empty dev default so localhost works with no setup; deployed overrides it.
|
||||||
|
assert config.session_secret()
|
||||||
|
|
||||||
|
|
||||||
|
def test_session_secret_honors_env(monkeypatch):
|
||||||
|
monkeypatch.setenv("ECOMM_SESSION_SECRET", "s3cret")
|
||||||
|
assert config.session_secret() == "s3cret"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cookie_secure_defaults_false(monkeypatch):
|
||||||
|
monkeypatch.delenv("ECOMM_COOKIE_SECURE", raising=False)
|
||||||
|
assert config.cookie_secure() is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_cookie_secure_truthy_env(monkeypatch):
|
||||||
|
monkeypatch.setenv("ECOMM_COOKIE_SECURE", "1")
|
||||||
|
assert config.cookie_secure() is True
|
||||||
|
monkeypatch.setenv("ECOMM_COOKIE_SECURE", "true")
|
||||||
|
assert config.cookie_secure() is True
|
||||||
|
monkeypatch.setenv("ECOMM_COOKIE_SECURE", "0")
|
||||||
|
assert config.cookie_secure() is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_mailer_kind_defaults_to_log(monkeypatch):
|
||||||
|
monkeypatch.delenv("ECOMM_MAILER", raising=False)
|
||||||
|
assert config.mailer_kind() == "log"
|
||||||
|
|||||||
Reference in New Issue
Block a user