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:
@@ -49,27 +49,6 @@ from .serializers import (
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GuestAwareContentThrottle(ScopedRateThrottle):
|
||||
"""
|
||||
مشترک با GuestAwareAIThrottle/GuestAwareDiscountThrottle
|
||||
و مشابههاش: چون GuestSessionView با هر deviceId جدید یک pk تازه میسازه،
|
||||
throttleِ استانداردِ بر اساسِ user.pk با چرخشِ حسابِ مهمان دور زده میشه —
|
||||
درحالیکه answer/complete اثرِ جانبیِ ماندگار (هارت، xp/coins/progress) دارن.
|
||||
برای همین فقط کاربرهای مهمان با IP کلید میخورن؛ کاربرهای غیرمهمان مثلِ قبل بر اساسِ pk.
|
||||
"""
|
||||
|
||||
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}
|
||||
|
||||
|
||||
# --- کشِ دادهی شبهِثابتِ برنامهی درسی -------------------------------------
|
||||
# گریدها و درختِ unit/node/lesson تقریباً هیچوقت عوض نمیشوند ولی روی هر بار
|
||||
# باز شدنِ اپ خوانده میشوند. یک نسخهکلیدِ مشترک نگه میداریم که با هر تغییرِ
|
||||
@@ -172,7 +151,7 @@ class GradesListView(APIView):
|
||||
"""GET /api/grades — لیست پایهها"""
|
||||
|
||||
throttle_scope = 'read'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(responses=GradesListResponseSerializer, tags=['Curriculum (content)'])
|
||||
def get(self, request):
|
||||
@@ -260,7 +239,7 @@ class HomeView(APIView):
|
||||
# userId همیشه از request.user.id (توکن معتبر) گرفته میشود، نه ورودی کلاینت (IDOR).
|
||||
permission_classes = [IsAuthenticated]
|
||||
throttle_scope = 'read'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
parameters=[
|
||||
@@ -438,9 +417,9 @@ class QuestionAnswerView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
# Idempotency-Key فقط جلوی retry با همون کلید رو میگیره، نه حجمِ درخواستهای
|
||||
# *متفاوت* که هرکدوم UserAnswer جدید میسازن و هارت/NodeProgress رو تغییر میدن؛
|
||||
# برای همون GuestAwareContentThrottle لازمه (نگاه کنید به تعریفش بالا).
|
||||
# برای همین throttle لازمه.
|
||||
throttle_scope = 'question_answer'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
request=AnswerRequestSerializer,
|
||||
@@ -556,11 +535,11 @@ class LessonCompleteView(APIView):
|
||||
# میتونست بهجای هر کاربرِ دیگری xp/coins ثبت کنه.
|
||||
permission_classes = [IsAuthenticated]
|
||||
# Idempotency-Key فقط جلوی retry با همون کلید رو میگیره؛ برای همینه که
|
||||
# GuestAwareContentThrottle لازمه (نگاه کنید به تعریفش بالا). نرخ در
|
||||
# throttle لازمه. نرخ در
|
||||
# settings (`lesson_complete`، الان ۱۲۰/hour) کمتر از question_answer است
|
||||
# چون این endpoint رکوردِ ماندگار میسازه.
|
||||
throttle_scope = 'lesson_complete'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
request=LessonCompleteRequestSerializer,
|
||||
@@ -823,7 +802,7 @@ class NodeQuizView(APIView):
|
||||
"""
|
||||
|
||||
throttle_scope = 'read'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
DEFAULT_SIZE = 4
|
||||
MAX_SIZE = 20
|
||||
@@ -909,7 +888,7 @@ class NodeQuizCompleteView(APIView):
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
throttle_scope = 'node_complete'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(
|
||||
request=NodeQuizCompleteRequestSerializer,
|
||||
@@ -1047,7 +1026,7 @@ class NodeLessonsView(APIView):
|
||||
"""
|
||||
|
||||
throttle_scope = 'read'
|
||||
throttle_classes = [GuestAwareContentThrottle]
|
||||
throttle_classes = [ScopedRateThrottle]
|
||||
|
||||
@extend_schema(responses=NodeLessonsResponseSerializer, tags=['Curriculum (content)'])
|
||||
def get(self, request, node_id: int):
|
||||
|
||||
Reference in New Issue
Block a user