def add_phone(): form = NewPhoneForm() if form.validate_on_submit(): userphone = UserPhoneClaim.get_for(user=current_auth.user, phone=form.phone.data) if userphone is None: userphone = UserPhoneClaim(user=current_auth.user, phone=form.phone.data) db.session.add(userphone) try: send_phone_verify_code(userphone) db.session.commit( ) # Commit after sending because send_phone_verify_code saves the message sent flash(_("We sent a verification code to your phone number"), 'success') user_data_changed.send(current_auth.user, changes=['phone-claim']) return render_redirect(url_for('.verify_phone', number=userphone.phone), code=303) except ValueError as e: db.session.rollback() form.phone.errors.append(str(e)) return render_form( form=form, title=_("Add a phone number"), formid='phone_add', submit=_("Verify phone"), ajax=True, )
def remove_phone(number): userphone = UserPhone.get(phone=number) if userphone is None or userphone.user != current_auth.user: userphone = UserPhoneClaim.get_for(user=current_auth.user, phone=number) if not userphone: abort(404) if userphone.verification_expired: flash( _("This number has been blocked due to too many failed verification attempts" ), 'danger', ) # Block attempts to delete this number if verification failed. # It needs to be deleted in a background sweep. return render_redirect(url_for('.account'), code=303) if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(current_auth.user, changes=['phone-delete']) return render_delete_sqla( userphone, db, title=_("Confirm removal"), message=_("Remove phone number {phone} from your account?").format( phone=userphone.phone), success=_("You have removed your number {phone}").format( phone=userphone.phone), next=url_for('.account'), delete_text=_("Remove"), )
def validate_phone(self, field): # TODO: Use the phonenumbers library to validate this # Step 1: Remove punctuation in number number = strip_phone(field.data) # Step 2: Check length if len(number) > 16: raise forms.ValidationError( _("This is too long to be a valid phone number")) # Step 3: Validate number format if not valid_phone(number): raise forms.ValidationError( _("Invalid phone number (must be in international format with a leading + symbol)" )) # Step 4: Check if Indian number (startswith('+91')) if number.startswith('+91') and len(number) != 13: raise forms.ValidationError( _("This does not appear to be a valid Indian mobile number")) # Step 5: Check if number has already been claimed existing = UserPhone.get(phone=number) if existing is not None: if existing.user == current_auth.user: raise forms.ValidationError( _("You have already registered this phone number")) else: raise forms.ValidationError( _("This phone number has already been claimed")) existing = UserPhoneClaim.get_for(user=current_auth.user, phone=number) if existing is not None: raise forms.ValidationError( _("This phone number is pending verification")) field.data = number # Save stripped number