import secrets from django.conf import settings from rest_framework.permissions import BasePermission class HasInternalServiceKey(BasePermission): """ برای endpointهایی مثل POST /api/payment/orders که طبق سند فقط قراره سرور-به-سرور (از اپ Subscription) صدا زده بشن، نه از یک کلاینت دلخواه. درخواست باید هدر X-Internal-Key رو برابر settings.INTERNAL_SERVICE_KEY بفرسته؛ در غیر این صورت 403 برمی‌گرده. """ message = 'این endpoint فقط برای فراخوانی داخلی/سرور-به-سرور است.' def has_permission(self, request, view): provided = request.headers.get('X-Internal-Key', '') expected = settings.INTERNAL_SERVICE_KEY # مقایسه‌ی زمان‌ثابت: == در اولین نویسه‌ی متفاوت برمی‌گردد و از زمانِ پاسخ # می‌شود کلید را نویسه‌به‌نویسه حدس زد. return bool(provided) and bool(expected) and secrets.compare_digest(provided, expected)