cleanup: trim bloated multi-line comments across the project
This commit is contained in:
@@ -23,25 +23,10 @@ from .services import apply_order_payment_result, create_order
|
||||
|
||||
|
||||
class GuestAwareBazaarThrottle(ScopedRateThrottle):
|
||||
"""
|
||||
⚠️ اضافه شده: همون مشکلِ GuestAwareAIThrottle (ai_tutor/views.py)،
|
||||
GuestAwareFamilyThrottle (family/views.py) و GuestAwareDiscountThrottle/
|
||||
GuestAwarePurchaseThrottle (discount/views.py، subscription/views.py)
|
||||
اینجا هم هست. ScopedRateThrottle استاندارد برای درخواستِ احرازهویتشده
|
||||
از request.user.pk بهعنوانِ کلیدِ throttle استفاده میکنه؛ چون
|
||||
GuestSessionView با هر deviceId جدید یک کاربرِ مهمانِ تازه (pk جدید)
|
||||
میسازه، یک مهاجم میتونست با ساختنِ پیدرپیِ حسابهای مهمان، برای هر
|
||||
حساب یک bucket تازه از throttle_scope 'bazaar_verify' بگیره — درحالیکه
|
||||
هر درخواستِ پذیرفتهشده یک فراخوانیِ سرور-به-سرور به API بازار رو
|
||||
تریگر میکنه.
|
||||
|
||||
دقیقاً طبقِ همون الگو: فقط برای کاربرهای مهمان (is_guest=True) کلیدِ
|
||||
cache از pk کاربر به IP کلاینت (get_ident) تغییر میکنه، پس همهی
|
||||
حسابهای مهمانِ ساختهشده از یک IP یک bucket مشترک دارن و چرخشِ حساب
|
||||
دیگه bucket تازه نمیده. رفتارِ throttle برای کاربرهای غیرمهمان
|
||||
(ثبتنامشده) دقیقاً مثلِ قبل (کلید بر اساسِ pk) باقی میمونه؛ منطقِ
|
||||
verify/order ownership/transaction/apply-payment دستنخوردهست.
|
||||
"""
|
||||
"""همون الگوی GuestAwareAIThrottle/GuestAwareFamilyThrottle/etc: چرخشِ
|
||||
حساب مهمان (هر deviceId یه pk تازه) نباید bucket تازهی bazaar_verify
|
||||
بده، چون هر درخواستِ پذیرفتهشده یه فراخوانیِ سرور-به-سرور به بازاره.
|
||||
برای مهمانها کلیدِ cache بر اساسِ IP هست، نه pk."""
|
||||
|
||||
def get_cache_key(self, request, view):
|
||||
user = request.user
|
||||
@@ -121,14 +106,10 @@ class PaymentWebhookView(APIView):
|
||||
"""
|
||||
|
||||
permission_classes = [HasWebhookSecret]
|
||||
# ⚠️ اضافه شده: این endpoint قبلاً هیچ throttleای نداشت، درحالیکه فقط
|
||||
# با مقایسهی یک هدرِ ثابت (X-Webhook-Secret) محافظت میشه؛ بدونِ
|
||||
# throttle، تعدادِ نامحدودی تلاش برای حدسِ این سکرت (یا fuzz کردنِ
|
||||
# orderId بعد از افشای احتمالیِ سکرت) ممکن بود، درحالیکه یک حدسِ
|
||||
# درست باعثِ paid شدنِ واقعیِ سفارش و فعالسازیِ اشتراک میشه. چون
|
||||
# این caller یک کاربرِ اپ نیست (خودِ درگاهِ پرداخته)، از یک
|
||||
# ScopedRateThrottleِ سادهٔ IP-محور استفاده شده، نه الگویِ
|
||||
# GuestAware*Throttle (که نیازمندِ request.user است).
|
||||
# این endpoint فقط با مقایسهی هدرِ ثابتِ X-Webhook-Secret محافظت میشه،
|
||||
# پس throttle لازمه تا حدسِ سکرت (یا fuzzِ orderId) محدود بمونه. چون
|
||||
# caller خودِ درگاهه نه یک کاربرِ اپ، از ScopedRateThrottleِ IP-محور
|
||||
# استفاده شده، نه الگویِ GuestAware*Throttle که نیازمندِ request.user است.
|
||||
throttle_scope = 'payment_webhook'
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@@ -182,19 +163,11 @@ class BazaarVerifyPurchaseView(APIView):
|
||||
"""
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
# ⚠️ افزوده شده: این endpoint یک فراخوانیِ سرور-به-سرور به API بازار
|
||||
# (verify_purchase) رو تریگر میکنه؛ بدون throttle مخصوص، یک کاربر
|
||||
# میتونست با ارسال مکرر purchaseToken نامعتبر، بار زیادی روی سرویس
|
||||
# بازار و بکاند بندازه. throttle_scope مجزا (bazaar_verify) جدا از
|
||||
# نرخهای دیگه (مثل otp_*) تنظیم شده.
|
||||
# ⚠️ اصلاح شده: چون کاربرهای مهمان (GuestSessionView) با هر deviceId
|
||||
# جدید یک pk تازه میگیرن، ScopedRateThrottleِ ساده (کلید بر اساسِ
|
||||
# user.pk) توسطِ چرخشِ حساب مهمان قابلدورزدن بود. حالا از
|
||||
# GuestAwareBazaarThrottle استفاده میشه که برای کاربرهای مهمان کلید
|
||||
# رو بر اساسِ IP میسازه و برای کاربرهای غیرمهمان رفتارِ per-user
|
||||
# قبلی رو دستنخورده نگه میداره. نرخ هم از ۲۰/hour به ۱۰/hour
|
||||
# سختگیرانهتر شد چون هر درخواستِ پذیرفتهشده یک تماسِ سرور-به-سرورِ
|
||||
# واقعی با بازار میزنه.
|
||||
# این endpoint یک فراخوانیِ سرور-به-سرورِ واقعی به API بازار (verify_purchase)
|
||||
# تریگر میکنه، برای همین throttle_scope مجزا و نرخِ سختگیرانهتر (۱۰/hour)
|
||||
# داره. کاربرهای مهمان با هر deviceId یک pk تازه میگیرن، پس
|
||||
# GuestAwareBazaarThrottle برای اونها بر اساسِ IP کلید میسازه تا چرخشِ
|
||||
# حساب bucket تازه نگیره؛ برای کاربرهای غیرمهمان رفتارِ per-user حفظ میشه.
|
||||
throttle_scope = 'bazaar_verify'
|
||||
throttle_classes = [GuestAwareBazaarThrottle]
|
||||
|
||||
@@ -208,13 +181,10 @@ class BazaarVerifyPurchaseView(APIView):
|
||||
serializer.is_valid(raise_exception=True)
|
||||
v = serializer.validated_data
|
||||
|
||||
# ⚛️🔒 اصلاح: فراخوانی HTTP به API بازار (تا ~۲۰ ثانیه، دو درخواست
|
||||
# پشتسرهم برای refresh token + verify) قبلاً *داخل* transaction.atomic
|
||||
# و زیر select_for_update روی Order انجام میشد؛ یعنی ردیف Order (و
|
||||
# هر تراکنش دیگهای که بخواد همون Order یا Subscription مرتبط رو لمس
|
||||
# کنه) تا برگشتِ پاسخ بازار قفل میموند. حالا verify_purchase قبل از
|
||||
# باز شدن atomic/lock صدا زده میشه؛ لاک فقط برای اعمال نتیجه (چند
|
||||
# میلیثانیه) گرفته میشه.
|
||||
# verify_purchase (تا ~۲۰ ثانیه، دو درخواستِ پشتسرهم) عمداً *قبل* از
|
||||
# بازشدنِ atomic/lock صدا زده میشه، نه داخلش — وگرنه ردیفِ Order (و هر
|
||||
# تراکنشِ دیگهای روی همون Order/Subscription) تا برگشتِ پاسخِ بازار
|
||||
# قفل میموند. لاک فقط برای اعمالِ نتیجه (چند میلیثانیه) گرفته میشه.
|
||||
order_lookup = get_object_or_404(
|
||||
Order, pk=v['orderId'], user_id=request.user.id, provider='bazaar',
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user