Signed payment links, hashed refresh tokens, login-only leaderboard, load test tools
- /api/payment/orders/{id}/pay requires the short-lived signature that paymentUrl carries;
without it (or with another order's) it is the same 404 as an unknown order
- Session.refresh_token stores the SHA-256 of the token; migration accounts.0007 hashes the
existing rows so tokens clients already hold keep working
- /api/leaderboard requires a token (guests have one); names of children were scrapable
- RAG mock only for `manage.py test`, not any command with an argument named "test"
- tools/loadtest: user factory, load generator, fake GapGPT+Qdrant, with method notes
- security-before-production.md lists only open items; closed ones become a guards table
with the tests that hold them. Comments describe current behaviour, not history
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
پیادهسازی شده، نه یک HTTP call به خودمون.
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.core import signing
|
||||
from django.db import IntegrityError
|
||||
from django.db import transaction as db_transaction
|
||||
from django.utils import timezone
|
||||
@@ -53,7 +54,29 @@ def call_payment_gateway(order: Order) -> str:
|
||||
باری که کاربر واقعاً این URL را باز کند زده میشود (نگاه کنید به
|
||||
payment/zarinpal.py و PaymentRedirectView در views.py).
|
||||
"""
|
||||
return f'{settings.PUBLIC_BASE_URL}/api/payment/orders/{order.id}/pay'
|
||||
return f'{settings.PUBLIC_BASE_URL}/api/payment/orders/{order.id}/pay?t={pay_link_token(order.id)}'
|
||||
|
||||
|
||||
# لینکِ پرداخت بیتوکنِ ورود باز میشود (مرورگر هدرِ Bearer نمیفرستد) و شناسهی سفارش ترتیبی
|
||||
# است؛ امضای کوتاهعمر جلوی این را میگیرد که غریبه با پیمایشِ شناسهها روی سفارشِ دیگران
|
||||
# authority بسازد (و کدِ تخفیفِ صاحبش را ببندد) یا وضعیتِ سفارششان را از ریدایرکت بخواند.
|
||||
# امضا با همان DJANGO_SECRET_KEY است؛ تا وقتی آن کلید روی سرور همان کلیدِ داخلِ ریپوست،
|
||||
# این امضا هم برای کسی که ریپو را دیده جعلشدنی است. یک روز: لینک بلافاصله بعد از ساختِ
|
||||
# سفارش باز میشود؛ یک روز صفحهای را هم که باز مانده پوشش میدهد.
|
||||
PAY_LINK_SALT = 'tadrisino-pay-link'
|
||||
PAY_LINK_MAX_AGE_SECONDS = 24 * 3600
|
||||
|
||||
|
||||
def pay_link_token(order_id: int) -> str:
|
||||
return signing.TimestampSigner(salt=PAY_LINK_SALT).sign(str(order_id))
|
||||
|
||||
|
||||
def pay_link_is_valid(order_id: int, token: str) -> bool:
|
||||
try:
|
||||
value = signing.TimestampSigner(salt=PAY_LINK_SALT).unsign(token, max_age=PAY_LINK_MAX_AGE_SECONDS)
|
||||
except signing.BadSignature: # SignatureExpired هم زیرکلاسِ همین است
|
||||
return False
|
||||
return value == str(order_id)
|
||||
|
||||
|
||||
def create_order(*, user_id: int, amount: int, currency: str = 'IRT',
|
||||
|
||||
Reference in New Issue
Block a user