throttling, abuse-protection & logging/monitoring pass
This commit is contained in:
@@ -10,6 +10,22 @@ from rest_framework.exceptions import APIException
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _phone_suffix(phone: str) -> str:
|
||||
"""
|
||||
⚠️ اصلاح: قبلاً لاگهای مربوط به OTP، شمارهتلفنِ کامل رو لاگ میکردن
|
||||
(PIIِ غیرضروری در لاگهای اپلیکیشن). حالا فقط ۴ رقمِ آخر (برای
|
||||
correlation/دیباگ، بدونِ افشای کاملِ شماره) لاگ میشه — همون الگویی که
|
||||
قبلاً در accounts/views.py::LoginView هم برای همین منظور استفاده شده.
|
||||
|
||||
⚠️ اصلاحِ این دور: لاگهای خطای ارائهدهنده (provider) دیگه
|
||||
response.text خام رو لاگ نمیکنن — چون بدنهی پاسخِ کاوهنگار میتونه
|
||||
دادهی حساس/غیرضروری (مثلاً جزئیاتِ گیرنده یا پیامِ متنی) داشته باشه.
|
||||
بهجاش فقط context مفید و بیخطر (phone_suffix، status، provider_status)
|
||||
لاگ میشه.
|
||||
"""
|
||||
return phone[-4:] if phone else phone
|
||||
|
||||
|
||||
class OTPDeliveryError(APIException):
|
||||
"""
|
||||
⚠️ اصلاح: قبلاً send_otp_sms یک استاب بود که فقط لاگ میکرد و همیشه
|
||||
@@ -44,11 +60,17 @@ def send_otp_sms(*, phone: str, code: str) -> None:
|
||||
میگیره، نه یک success دروغین).
|
||||
"""
|
||||
if settings.DEBUG:
|
||||
logger.info('OTP sms dispatch (dev, no real SMS sent): phone=%s code_len=%d', phone, len(code))
|
||||
logger.info(
|
||||
'OTP sms dispatch (dev, no real SMS sent): phone_suffix=%s code_len=%d',
|
||||
_phone_suffix(phone), len(code),
|
||||
)
|
||||
return
|
||||
|
||||
if not settings.KAVENEGAR_API_KEY:
|
||||
logger.error('OTP SMS misconfigured: KAVENEGAR_API_KEY is not set (phone=%s)', phone)
|
||||
logger.error(
|
||||
'OTP SMS misconfigured: KAVENEGAR_API_KEY is not set (phone_suffix=%s)',
|
||||
_phone_suffix(phone),
|
||||
)
|
||||
raise OTPDeliveryError('پیکربندیِ سرویسِ پیامک ناقص است.')
|
||||
|
||||
message = settings.OTP_SMS_TEMPLATE.format(code=code)
|
||||
@@ -63,13 +85,13 @@ def send_otp_sms(*, phone: str, code: str) -> None:
|
||||
timeout=5,
|
||||
)
|
||||
except requests.RequestException:
|
||||
logger.exception('OTP SMS request to provider failed: phone=%s', phone)
|
||||
logger.exception('OTP SMS request to provider failed: phone_suffix=%s', _phone_suffix(phone))
|
||||
raise OTPDeliveryError('ارسال پیامک OTP با خطا مواجه شد.')
|
||||
|
||||
if response.status_code != 200:
|
||||
logger.error(
|
||||
'OTP SMS provider returned non-200: phone=%s status=%s body=%s',
|
||||
phone, response.status_code, response.text[:500],
|
||||
'OTP SMS provider returned non-200: phone_suffix=%s status=%s',
|
||||
_phone_suffix(phone), response.status_code,
|
||||
)
|
||||
raise OTPDeliveryError('ارسال پیامک OTP با خطا مواجه شد.')
|
||||
|
||||
@@ -85,15 +107,15 @@ def send_otp_sms(*, phone: str, code: str) -> None:
|
||||
provider_status = body['return']['status']
|
||||
except (ValueError, KeyError, TypeError):
|
||||
logger.error(
|
||||
'OTP SMS provider returned malformed response body: phone=%s body=%s',
|
||||
phone, response.text[:500],
|
||||
'OTP SMS provider returned malformed response body: phone_suffix=%s status=%s',
|
||||
_phone_suffix(phone), response.status_code,
|
||||
)
|
||||
raise OTPDeliveryError('ارسال پیامک OTP با خطا مواجه شد.')
|
||||
|
||||
if provider_status != 200:
|
||||
logger.error(
|
||||
'OTP SMS provider rejected message at application level: phone=%s '
|
||||
'provider_status=%s body=%s',
|
||||
phone, provider_status, response.text[:500],
|
||||
'OTP SMS provider rejected message at application level: phone_suffix=%s '
|
||||
'provider_status=%s',
|
||||
_phone_suffix(phone), provider_status,
|
||||
)
|
||||
raise OTPDeliveryError('ارسال پیامک OTP با خطا مواجه شد.')
|
||||
|
||||
Reference in New Issue
Block a user