Security review fixes: admin permissions, guest sessions, payment edge cases, assistant leaks
- Admin: refund/cancel/mark-resolved/Bazaar-link actions need change permission; question and curriculum import need add/delete; content browser needs view_question; guest device ids are shown to superusers only. - Accounts: registering a guest's phone revokes the guest's earlier sessions; self-deletion keeps Redemption, UserOffer and the phone's OTP rows; the public demo guest cannot be deleted (DEMO_GUEST_DEVICE_IDS); display-name contact filter covers any separator and social handles. - Payment: callback without Authority is 400; a second Bazaar purchase on a paid order is 409; orders snapshot credits/hearts/days at creation (payment.0011). - Assistant: a broken diagram no longer makes a streamed answer free; a late off-topic marker refuses the answer (not stored, not cached); a disconnect saves the partial answer; only KNOWN_COLLECTIONS are searched. - Infra: secret-key file is created atomically (workers no longer split keys); no default INTERNAL_SERVICE_KEY; Kavenegar key and Bazaar token kept out of error logs; Swagger/ReDoc pinned; schema throttled; docker compose bound to 127.0.0.1; non-ASCII digit ids are 400; ticket text capped at 5000. - docs/security-before-production.md: remaining open items 24-31 and the guard tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,15 +68,20 @@ def plan(user_ids):
|
||||
return counts
|
||||
|
||||
|
||||
def delete_users(user_ids, keep=()):
|
||||
"""keep: برچسبِ مدلهایی که نمیمانند پاک شوند (مثلاً 'payment.Order' برای حذفِ حسابِ خودِ کاربر)."""
|
||||
def delete_users(user_ids, keep=(), delete_otp_codes=True):
|
||||
"""
|
||||
keep: برچسبِ مدلهایی که نباید پاک شوند (مثلاً 'payment.Order' برای حذفِ حسابِ خودِ کاربر).
|
||||
delete_otp_codes: این دستور (کارِ ادمین) کدهای شماره را پاک میکند تا آن شماره از صفر شروع کند؛
|
||||
حذفِ حساب به دستِ خودِ کاربر این کار را نمیکند تا سقفِ پیامکِ شماره دور زده نشود.
|
||||
"""
|
||||
phones = list(User.objects.filter(pk__in=user_ids).exclude(phone=None).values_list('phone', flat=True))
|
||||
with transaction.atomic():
|
||||
for model, column in user_scoped_models():
|
||||
if model._meta.label in keep:
|
||||
continue
|
||||
model.objects.filter(**{f'{column}__in': user_ids}).delete()
|
||||
OTPCode.objects.filter(phone__in=phones).delete()
|
||||
if delete_otp_codes:
|
||||
OTPCode.objects.filter(phone__in=phones).delete()
|
||||
User.objects.filter(pk__in=user_ids).delete()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user