@login_required()
@valid_ajax_request_required
def verification_start_view(request: WSGIRequest) -> JsonResponse:
account_sid = settings.TWILIO_ACCOUNT_SID
auth_token = settings.TWILIO_AUTH_TOKEN
from_phone_number = settings.TWILIO_PHONE_NUMBER
if not account_sid or not auth_token or not from_phone_number:
return error_json_response(
'Text message sending is not configured. Please try again later.'
)
body = json.loads(request.body.decode('utf-8'))
phone_number_raw = body.get('phone_number', '')
phone_number_normalized = phone_number_normalize(phone_number_raw)
if phone_number_normalized is None:
return error_json_response('That phone number is not valid. Please check it and try again.')
auth_sms = AuthSms.objects.by_phone_number(phone_number=phone_number_normalized).first()
if auth_sms is not None and auth_sms.user_id != request.user.id:
return error_json_response('That phone number is already in use by another account.')
if auth_sms is None:
auth_sms = AuthSms.objects.create(user=request.user, phone_number=phone_number_normalized)
auth_sms.record_attempt()
if auth_sms.is_throttled():
return error_json_response(
'You have requested too many codes. Please wait a moment and try again.'
)
code = auth_sms.services.processor.issue_code(AuthSmsCodePurposeChoices.VERIFICATION)
expiry_minutes = settings.DJANGO_SPIRE_AUTH_SMS_CODE_EXPIRY_MINUTES
twilio_client = Client(account_sid, auth_token)
twilio_client.messages.create(
to=phone_number_normalized,
from_=from_phone_number,
body=f'Your verification code is {code}. It expires in {expiry_minutes} minutes.',
)
return success_json_response('Your verification code has been sent.')