Add payment provider validation entrypoint

This commit is contained in:
2026-04-09 00:52:25 +02:00
parent 310ac83bc4
commit cf33be8361
3 changed files with 92 additions and 42 deletions

View File

@@ -0,0 +1,63 @@
from __future__ import annotations
import json
import os
from pathlib import Path
from django.conf import settings
from django.core.management.base import CommandError
def _is_demo_data(value: str) -> bool:
normalized = "".join(ch for ch in str(value).lower() if ch.isalnum())
return "demodata" in normalized
def validate_payment_provider_config() -> None:
installed_apps = list(settings.INSTALLED_APPS)
payment_apps = [app for app in installed_apps if "payment" in app.lower()]
checkout_apps = [app for app in installed_apps if "checkout" in app.lower()]
if not payment_apps:
raise CommandError("No payment app found in INSTALLED_APPS.")
if not checkout_apps:
raise CommandError("No checkout app found in INSTALLED_APPS.")
if not any("oscar_checkout" in app.lower() for app in checkout_apps):
raise CommandError("Oscar checkout app is not active.")
if any(_is_demo_data(app) for app in installed_apps):
raise CommandError(
"Demo data plugin detected in INSTALLED_APPS. Remove all demodata plugins before launch."
)
if any("dummy" in app.lower() for app in payment_apps):
raise CommandError(
"Dummy payment app detected in INSTALLED_APPS. Use a real provider plugin before production launch."
)
if any("mollie" in app.lower() for app in payment_apps):
mollie_settings = (
getattr(settings, "PAYMENT_MOLLIE", None)
or getattr(settings, "payment_mollie", None)
or {}
)
config_key = str(mollie_settings.get("api_key", "")).strip()
env_key = str(os.environ.get("MOLLIE_API_KEY", "")).strip()
effective_key = env_key or config_key
if not effective_key or effective_key.upper() == "CHANGE_ME":
raise CommandError(
"Mollie payment provider is enabled but no valid API key is configured. "
"Set MOLLIE_API_KEY or settings.payment_mollie.api_key to a real key."
)
if not effective_key.startswith("live_"):
raise CommandError(
"Mollie key must be a live key for production launch (expected prefix 'live_')."
)
config_path = Path(__file__).resolve().parent / "ocyan.json"
if config_path.exists():
with config_path.open("r", encoding="utf-8") as handle:
config_payload = json.load(handle)
config_plugins = [str(plugin) for plugin in config_payload.get("ocyan_plugins", [])]
if any(_is_demo_data(plugin) for plugin in config_plugins):
raise CommandError(
"Demo data plugin detected in ocyan.json. Remove it before launch."
)

View File

@@ -1,7 +1,6 @@
from __future__ import annotations
import json
import os
from pathlib import Path
from django.conf import settings
@@ -17,6 +16,7 @@ from mandelstudio.idea_marketplace import (
IDEA_PRODUCTS,
SHORT_DESCRIPTION_ATTRIBUTE_CODE,
)
from mandelstudio.launch_validation import validate_payment_provider_config
class Command(BaseCommand):
@@ -32,53 +32,14 @@ class Command(BaseCommand):
StockRecord = get_model("partner", "StockRecord")
Page = get_model("wagtailcore", "Page")
installed_apps = list(settings.INSTALLED_APPS)
payment_apps = [app for app in installed_apps if "payment" in app.lower()]
checkout_apps = [app for app in installed_apps if "checkout" in app.lower()]
if not payment_apps:
raise CommandError("No payment app found in INSTALLED_APPS.")
if not checkout_apps:
raise CommandError("No checkout app found in INSTALLED_APPS.")
if not any("oscar_checkout" in app.lower() for app in checkout_apps):
raise CommandError("Oscar checkout app is not active.")
def _is_demo_data(value: str) -> bool:
normalized = "".join(ch for ch in str(value).lower() if ch.isalnum())
return "demodata" in normalized
if any(_is_demo_data(app) for app in installed_apps):
raise CommandError(
"Demo data plugin detected in INSTALLED_APPS. Remove all demodata plugins before launch."
)
if any("dummy" in app.lower() for app in payment_apps):
raise CommandError(
"Dummy payment app detected in INSTALLED_APPS. Use a real provider plugin before production launch."
)
if any("mollie" in app.lower() for app in payment_apps):
mollie_settings = (
getattr(settings, "PAYMENT_MOLLIE", None)
or getattr(settings, "payment_mollie", None)
or {}
)
config_key = str(mollie_settings.get("api_key", "")).strip()
env_key = str(os.environ.get("MOLLIE_API_KEY", "")).strip()
effective_key = env_key or config_key
if not effective_key or effective_key.upper() == "CHANGE_ME":
raise CommandError(
"Mollie payment provider is enabled but no valid API key is configured. "
"Set MOLLIE_API_KEY or settings.payment_mollie.api_key to a real key."
)
if not effective_key.startswith("live_"):
raise CommandError(
"Mollie key must be a live key for production launch (expected prefix 'live_')."
)
validate_payment_provider_config()
config_path = Path(__file__).resolve().parents[2] / "ocyan.json"
if config_path.exists():
with config_path.open("r", encoding="utf-8") as handle:
config_payload = json.load(handle)
config_plugins = [str(plugin) for plugin in config_payload.get("ocyan_plugins", [])]
if any(_is_demo_data(plugin) for plugin in config_plugins):
if any("demodata" in "".join(ch for ch in str(plugin).lower() if ch.isalnum()) for plugin in config_plugins):
raise CommandError(
"Demo data plugin detected in ocyan.json. Remove it before launch."
)

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python3
from __future__ import annotations
import os
import sys
from pathlib import Path
def main() -> int:
project_root = Path(__file__).resolve().parents[1]
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mandelstudio.settings.base")
os.chdir(project_root)
import django
django.setup()
from mandelstudio.launch_validation import validate_payment_provider_config
validate_payment_provider_config()
print("Payment provider configuration validation passed.")
return 0
if __name__ == "__main__":
raise SystemExit(main())