Remove the guest system entirely: no is_guest/device_id, no guest throttles, phone login is the only way in
accounts.0008 drops the columns and refuses to run while guest rows exist. Docs describe the current state; tests that only proved guest behaviour are gone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,40 +20,6 @@ from .serializers import (
|
||||
from .services import redeem_offer_code
|
||||
|
||||
|
||||
class GuestAwareDiscountThrottle(ScopedRateThrottle):
|
||||
"""
|
||||
همان مشکلِ GuestAwareAIThrottle (ai_tutor/views.py) اینجا هم هست.
|
||||
ScopedRateThrottle استاندارد برای درخواستِ احرازهویتشده از
|
||||
request.user.pk بهعنوانِ کلیدِ throttle استفاده میکنه؛ چون
|
||||
GuestSessionView با هر deviceId جدید یک کاربرِ مهمانِ تازه (pk جدید)
|
||||
میسازه، یک مهاجم میتونست با ساختنِ پیدرپیِ حسابهای مهمان (تا سقفِ
|
||||
guest_session=20/hour)، برای هر حساب یک bucket تازه از throttle_scope
|
||||
'discount_redeem' بگیره. ریسکِ این endpoint از بقیه هم بیشتره، چون
|
||||
DiscountCode یک رکوردِ سراسری با max_uses مشترکِ بینِ همهی کاربرهاست؛
|
||||
یک حدسِ درست صرفاً اطلاعات لو نمیده، بلکه یک Redemption واقعی
|
||||
میسازه و مبلغِ سفارش رو کم میکنه — یعنی throttle دورزدهشده به
|
||||
مهاجم guessهای واقعاً بیشتری روی یک کدِ سراسری میده.
|
||||
|
||||
دقیقاً طبقِ همون الگو: فقط برای کاربرهای مهمان (is_guest=True) کلیدِ
|
||||
cache از pk کاربر به IP کلاینت (get_ident) تغییر میکنه، پس همهی
|
||||
حسابهای مهمانِ ساختهشده از یک IP یک bucket مشترک دارن و چرخشِ حساب
|
||||
دیگه bucket تازه نمیده. رفتارِ throttle برای کاربرهای غیرمهمان
|
||||
(ثبتنامشده) دقیقاً مثلِ قبل (کلید بر اساسِ pk) باقی میمونه؛ منطقِ
|
||||
lookup/redemption/order دستنخوردهست.
|
||||
"""
|
||||
|
||||
def get_cache_key(self, request, view):
|
||||
user = request.user
|
||||
if user and user.is_authenticated and getattr(user, 'is_guest', False):
|
||||
ident = f'guest-ip:{self.get_ident(request)}'
|
||||
elif user and user.is_authenticated:
|
||||
ident = user.pk
|
||||
else:
|
||||
ident = self.get_ident(request)
|
||||
|
||||
return self.cache_format % {'scope': self.scope, 'ident': ident}
|
||||
|
||||
|
||||
def _is_usable(discount: DiscountCode) -> bool:
|
||||
# ⚠️ هر Redemption شمرده میشود، حتی روی سفارشی که هرگز پرداخت نشد؛ پس
|
||||
# سبدِ رهاشده سهمِ max_uses را برای همیشه میسوزاند و خودِ همان کاربر هم
|
||||
@@ -73,11 +39,9 @@ class ValidateDiscountView(APIView):
|
||||
|
||||
# این endpoint type/value کد رو برمیگردونه، پس بدونِ throttle یک
|
||||
# کاربر میتونست بینهایت کد رو probe کنه؛ نرخ کمی بالاتر از
|
||||
# offer_redeem چون این یک چکِ read-only پیش از خریده. GuestAwareDiscountThrottle
|
||||
# مشترک (هم اینجا هم RedeemDiscountView/RedeemOfferCodeView) برای
|
||||
# مهمانها کلید رو بر اساسِ IP میسازه تا چرخشِ حساب bucket تازه نده.
|
||||
# offer_redeem چون این یک چکِ read-only پیش از خریده.
|
||||
throttle_scope = 'discount_validate'
|
||||
throttle_classes = [GuestAwareDiscountThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
parameters=[OpenApiParameter('code', OpenApiTypes.STR, required=True)],
|
||||
@@ -112,10 +76,9 @@ class RedeemDiscountView(APIView):
|
||||
# همون oracleِ probe مثلِ ValidateDiscountView، ولی ریسکش بیشتره: حدسِ
|
||||
# درست یه کدِ واقعی رو مصرف میکنه (سهمِ max_uses مشترک) و مبلغِ سفارش
|
||||
# رو واقعاً کم میکنه، ضمن اینکه هر تلاش دو select_for_update و یه
|
||||
# تراکنشه. GuestAwareDiscountThrottle برای مهمانها کلید رو بر اساسِ IP
|
||||
# میسازه تا چرخشِ حساب bucket تازه نده.
|
||||
# تراکنشه.
|
||||
throttle_scope = 'discount_redeem'
|
||||
throttle_classes = [GuestAwareDiscountThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(request=RedeemRequestSerializer, responses=RedeemResponseSerializer,
|
||||
tags=['Discount (discount)'])
|
||||
@@ -209,11 +172,9 @@ class RedeemOfferCodeView(APIView):
|
||||
|
||||
# بدونِ throttle، کدهای آفر قابلِ probe بودن؛ اینجا حساستره چون
|
||||
# Offer.code سراسری/یکتاست و redeem_offer_code() فقط جلوی تکرارِ همون
|
||||
# کاربر رو میگیره — یک حسابِ مهمانِ چرخشی میتونست همون آفرِ سراسری رو
|
||||
# دوباره بگیره. GuestAwareDiscountThrottle برای مهمانها کلید رو بر
|
||||
# اساسِ IP میسازه تا چرخشِ حساب bucket تازه نده.
|
||||
# کاربر رو میگیره.
|
||||
throttle_scope = 'offer_redeem'
|
||||
throttle_classes = [GuestAwareDiscountThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
request=RedeemOfferCodeRequestSerializer, responses=UserOfferResponseSerializer,
|
||||
|
||||
Reference in New Issue
Block a user