def verify_phone(phoneclaim): if phoneclaim.verification_expired: flash(_("You provided an incorrect verification code too many times"), 'danger') # Block attempts to verify this number, but also keep the claim so that a new # claim cannot be made. A periodic sweep to delete old claims is needed. return render_redirect(url_for('.account'), code=303) form = VerifyPhoneForm() form.phoneclaim = phoneclaim if form.validate_on_submit(): if UserPhone.get(phoneclaim.phone) is None: if not current_auth.user.phones: primary = True else: primary = False userphone = UserPhone(user=current_auth.user, phone=phoneclaim.phone, gets_text=True) userphone.primary = primary db.session.add(userphone) db.session.delete(phoneclaim) db.session.commit() flash(_("Your phone number has been verified"), 'success') user_data_changed.send(current_auth.user, changes=['phone']) return render_redirect(url_for('.account'), code=303) else: db.session.delete(phoneclaim) db.session.commit() flash(_("This phone number has already been claimed by another user"), 'danger') elif request.method == 'POST': phoneclaim.verification_attempts += 1 db.session.commit() return render_form(form=form, title=_("Verify phone number"), formid='phone_verify', submit=_("Verify"), 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 verify_phone(phoneclaim): form = VerifyPhoneForm() form.phoneclaim = phoneclaim if form.validate_on_submit(): if UserPhone.get(phoneclaim.phone) is None: if not g.user.phones: primary = True else: primary = False userphone = UserPhone(user=g.user, phone=phoneclaim.phone, gets_text=True) userphone.primary = primary db.session.add(userphone) db.session.delete(phoneclaim) db.session.commit() flash(_("Your phone number has been verified"), 'success') user_data_changed.send(g.user, changes=['phone']) return render_redirect(url_for('.profile'), code=303) else: db.session.delete(phoneclaim) db.session.commit() flash( _("This phone number has already been claimed by another user" ), 'danger') return render_form(form=form, title=_("Verify phone number"), formid='phone_verify', submit=_("Verify"), ajax=True)
def add_phone(): form = NewPhoneForm() if form.validate_on_submit(): userphone = UserPhoneClaim.get(user=g.user, phone=form.phone.data) if userphone is None: userphone = UserPhoneClaim(user=g.user, phone=form.phone.data, type=form.type.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(g.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(unicode(e)) return render_form(form=form, title=_("Add a phone number"), formid='phone_add', submit=_("Add phone"), ajax=True)
def account_merge(): if 'merge_buid' not in session: return redirect(get_next_url(), code=302) other_user = User.get(buid=session['merge_buid']) if other_user is None: session.pop('merge_buid', None) return redirect(get_next_url(), code=302) form = ProfileMergeForm() if form.validate_on_submit(): if 'merge' in request.form: new_user = merge_users(current_auth.user, other_user) login_internal(new_user) flash(_("Your accounts have been merged"), 'success') session.pop('merge_buid', None) db.session.commit() user_data_changed.send(new_user, changes=['merge']) return redirect(get_next_url(), code=303) else: session.pop('merge_buid', None) return redirect(get_next_url(), code=303) return render_template( 'merge.html.jinja2', form=form, user=current_auth.user, other_user=other_user, login_registry=login_registry, )
def confirm_email(md5sum, secret): emailclaim = UserEmailClaim.query.filter_by( md5sum=md5sum, verification_code=secret).first() if emailclaim is not None: if 'verify' in emailclaim.permissions(g.user): existing = UserEmail.query.filter( UserEmail.email.in_( [emailclaim.email, emailclaim.email.lower()])).first() if existing is not None: claimed_email = emailclaim.email claimed_user = emailclaim.user db.session.delete(emailclaim) db.session.commit() if claimed_user != g.user: return render_message( title="Email address already claimed", message=Markup( "The email address <code>%s</code> has already been verified by another user." % escape(claimed_email))) else: return render_message( title="Email address already verified", message=Markup( "Hello %s! Your email address <code>%s</code> has already been verified." % (escape(claimed_user.fullname), escape(claimed_email)))) useremail = emailclaim.user.add_email( emailclaim.email.lower(), primary=emailclaim.user.email is None) db.session.delete(emailclaim) for claim in UserEmailClaim.query.filter( UserEmailClaim.email.in_( [useremail.email, useremail.email.lower()])).all(): db.session.delete(claim) db.session.commit() user_data_changed.send(g.user, changes=['email']) return render_message( title="Email address verified", message=Markup( "Hello %s! Your email address <code>%s</code> has now been verified." % (escape(emailclaim.user.fullname), escape( useremail.email)))) else: return render_message( title="That was not for you", message= u"You’ve opened an email verification link that was meant for another user. " u"If you are managing multiple accounts, please login with the correct account " u"and open the link again.", code=403) else: return render_message( title="Expired confirmation link", message= "The confirmation link you clicked on is either invalid or has expired.", code=404)
def remove_phone(number): userphone = UserPhone.query.filter_by(phone=number, user=g.user).first() if userphone is None: userphone = UserPhoneClaim.query.filter_by(phone=number, user=g.user).first_or_404() if request.method == 'POST': user_data_changed.send(g.user, changes=['phone-delete']) return render_delete_sqla(userphone, db, title="Confirm removal", message="Remove phone number %s?" % userphone, success="You have removed your number %s." % userphone, next=url_for('.profile'))
def account_edit(newprofile=False): form = ProfileForm(obj=current_auth.user) form.edit_user = current_auth.user form.fullname.description = current_app.config.get('FULLNAME_REASON') form.email.description = current_app.config.get('EMAIL_REASON') form.username.description = current_app.config.get('USERNAME_REASON') form.timezone.description = current_app.config.get('TIMEZONE_REASON') if current_auth.user.email or newprofile is False: del form.email if form.validate_on_submit(): # Can't auto-populate here because user.email is read-only current_auth.user.fullname = form.fullname.data current_auth.user.username = form.username.data current_auth.user.timezone = form.timezone.data if newprofile and not current_auth.user.email: useremail = UserEmailClaim.get(user=current_auth.user, email=form.email.data) if useremail is None: useremail = UserEmailClaim(user=current_auth.user, email=form.email.data) db.session.add(useremail) send_email_verify_link(useremail) db.session.commit() user_data_changed.send(current_auth.user, changes=['profile', 'email-claim']) flash(_( "Your profile has been updated. We sent you an email to confirm your address" ), category='success') else: db.session.commit() user_data_changed.send(current_auth.user, changes=['profile']) flash(_("Your profile has been updated"), category='success') if newprofile: return render_redirect(get_next_url(), code=303) else: return render_redirect(url_for('account'), code=303) if newprofile: return render_form( form, title=_("Update profile"), formid='account_new', submit=_("Continue"), message=Markup( _(u"Hello, <strong>{fullname}</strong>. Please spare a minute to fill out your profile" ).format(fullname=escape(current_auth.user.fullname))), ajax=True) else: return render_form(form, title=_("Edit profile"), formid='account_edit', submit=_("Save changes"), ajax=True)
def confirm_email(md5sum, secret): emailclaim = UserEmailClaim.query.filter_by(md5sum=md5sum, verification_code=secret).first() if emailclaim is not None: if "verify" in emailclaim.permissions(g.user): existing = UserEmail.query.filter(UserEmail.email.in_([emailclaim.email, emailclaim.email.lower()])).first() if existing is not None: claimed_email = emailclaim.email claimed_user = emailclaim.user db.session.delete(emailclaim) db.session.commit() if claimed_user != g.user: return render_message( title="Email address already claimed", message=Markup( "The email address <code>%s</code> has already been verified by another user." % escape(claimed_email) ), ) else: return render_message( title="Email address already verified", message=Markup( "Hello %s! Your email address <code>%s</code> has already been verified." % (escape(claimed_user.fullname), escape(claimed_email)) ), ) useremail = emailclaim.user.add_email(emailclaim.email.lower(), primary=emailclaim.user.email is None) db.session.delete(emailclaim) for claim in UserEmailClaim.query.filter( UserEmailClaim.email.in_([useremail.email, useremail.email.lower()]) ).all(): db.session.delete(claim) db.session.commit() user_data_changed.send(g.user, changes=["email"]) return render_message( title="Email address verified", message=Markup( "Hello %s! Your email address <code>%s</code> has now been verified." % (escape(emailclaim.user.fullname), escape(useremail.email)) ), ) else: return render_message( title="That was not for you", message=u"You’ve opened an email verification link that was meant for another user. " u"If you are managing multiple accounts, please login with the correct account " u"and open the link again.", code=403, ) else: return render_message( title="Expired confirmation link", message="The confirmation link you clicked on is either invalid or has expired.", code=404, )
def add_email(): form = NewEmailAddressForm() if form.validate_on_submit(): useremail = UserEmailClaim(user=g.user, email=form.email.data) db.session.add(useremail) db.session.commit() send_email_verify_link(useremail) flash("We sent you an email to confirm your address.", 'success') user_data_changed.send(g.user, changes=['email-claim']) return render_redirect(url_for('.profile'), code=303) return render_form(form=form, title="Add an email address", formid="email_add", submit="Add email", ajax=True)
def add_phone(): form = NewPhoneForm() if form.validate_on_submit(): userphone = UserPhoneClaim(user=g.user, phone=form.phone.data) db.session.add(userphone) send_phone_verify_code(userphone) db.session.commit() flash("We sent a verification code to your phone number.", 'success') user_data_changed.send(g.user, changes=['phone-claim']) return render_redirect(url_for('.verify_phone', number=userphone.phone), code=303) return render_form(form=form, title="Add a phone number", formid="phone_add", submit="Add phone", ajax=True)
def remove_email(md5sum): useremail = UserEmail.query.filter_by(md5sum=md5sum, user=g.user).first() if not useremail: useremail = UserEmailClaim.query.filter_by(md5sum=md5sum, user=g.user).first_or_404() if isinstance(useremail, UserEmail) and useremail.primary: flash("You cannot remove your primary email address", "error") return render_redirect(url_for('.profile'), code=303) if request.method == 'POST': user_data_changed.send(g.user, changes=['email-delete']) return render_delete_sqla(useremail, db, title="Confirm removal", message="Remove email address %s?" % useremail, success="You have removed your email address %s." % useremail, next=url_for('.profile'))
def remove_phone(number): userphone = UserPhone.query.filter_by(phone=number, user=g.user).first() if userphone is None: userphone = UserPhoneClaim.query.filter_by(phone=number, user=g.user).first_or_404() if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(g.user, changes=['phone-delete']) return render_delete_sqla(userphone, db, title=_(u"Confirm removal"), message=_(u"Remove phone number {phone}?").format( phone=userphone.phone), success=_(u"You have removed your number {phone}").format(phone=userphone.phone), next=url_for('.profile'))
def profile_edit(newprofile=False): form = ProfileForm(obj=g.user) form.fullname.description = current_app.config.get('FULLNAME_REASON') form.email.description = current_app.config.get('EMAIL_REASON') form.username.description = current_app.config.get('USERNAME_REASON') form.description.description = current_app.config.get('BIO_REASON') form.timezone.description = current_app.config.get('TIMEZONE_REASON') if g.user.email or newprofile is False: del form.email if form.validate_on_submit(): # Can't auto-populate here because user.email is read-only g.user.fullname = form.fullname.data g.user.username = form.username.data g.user.description = form.description.data g.user.timezone = form.timezone.data if newprofile and not g.user.email: useremail = UserEmailClaim(user=g.user, email=form.email.data) db.session.add(useremail) send_email_verify_link(useremail) db.session.commit() user_data_changed.send(g.user, changes=['profile', 'email-claim']) flash( "Your profile has been updated. We sent you an email to confirm your address", category='success') else: db.session.commit() user_data_changed.send(g.user, changes=['profile']) flash("Your profile has been updated.", category='success') if newprofile: return render_redirect(get_next_url(), code=303) else: return render_redirect(url_for('profile'), code=303) if newprofile: return render_form( form, title="Update profile", formid="profile_new", submit="Continue", message= u"Hello, %s. Please spare a minute to fill out your profile." % g.user.fullname, ajax=True) else: return render_form(form, title="Edit profile", formid="profile_edit", submit="Save changes", ajax=True)
def add_email(): form = NewEmailAddressForm() if form.validate_on_submit(): useremail = UserEmailClaim.get(user=current_auth.user, email=form.email.data) if useremail is None: useremail = UserEmailClaim(user=current_auth.user, email=form.email.data, type=form.type.data) db.session.add(useremail) db.session.commit() send_email_verify_link(useremail) flash(_("We sent you an email to confirm your address"), 'success') user_data_changed.send(current_auth.user, changes=['email-claim']) return render_redirect(url_for('.account'), code=303) return render_form(form=form, title=_("Add an email address"), formid='email_add', submit=_("Add email"), ajax=True)
def remove_email(md5sum): useremail = UserEmail.query.filter_by(md5sum=md5sum, user=current_auth.user).first() if not useremail: useremail = UserEmailClaim.query.filter_by(md5sum=md5sum, user=current_auth.user).first_or_404() if isinstance(useremail, UserEmail) and useremail.primary: flash(_("You cannot remove your primary email address"), 'danger') return render_redirect(url_for('.account'), code=303) if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(current_auth.user, changes=['email-delete']) return render_delete_sqla(useremail, db, title=_(u"Confirm removal"), message=_(u"Remove email address {email} from your account?").format(email=useremail.email), success=_(u"You have removed your email address {email}").format(email=useremail.email), next=url_for('.account'), delete_text=_(u"Remove"))
def profile_edit(newprofile=False): form = ProfileForm(obj=g.user) form.fullname.description = current_app.config.get("FULLNAME_REASON") form.email.description = current_app.config.get("EMAIL_REASON") form.username.description = current_app.config.get("USERNAME_REASON") form.description.description = current_app.config.get("BIO_REASON") form.timezone.description = current_app.config.get("TIMEZONE_REASON") if g.user.email or newprofile is False: del form.email if newprofile is True: del form.description if form.validate_on_submit(): # Can't auto-populate here because user.email is read-only g.user.fullname = form.fullname.data g.user.username = form.username.data if not newprofile: g.user.description = form.description.data g.user.timezone = form.timezone.data if newprofile and not g.user.email: useremail = UserEmailClaim(user=g.user, email=form.email.data) db.session.add(useremail) send_email_verify_link(useremail) db.session.commit() user_data_changed.send(g.user, changes=["profile", "email-claim"]) flash("Your profile has been updated. We sent you an email to confirm your address", category="success") else: db.session.commit() user_data_changed.send(g.user, changes=["profile"]) flash("Your profile has been updated.", category="success") if newprofile: return render_redirect(get_next_url(), code=303) else: return render_redirect(url_for("profile"), code=303) if newprofile: return render_form( form, title="Update profile", formid="profile_new", submit="Continue", message=u"Hello, %s. Please spare a minute to fill out your profile." % g.user.fullname, ajax=True, ) else: return render_form(form, title="Edit profile", formid="profile_edit", submit="Save changes", ajax=True)
def verify_phone(phoneclaim): form = VerifyPhoneForm() form.phoneclaim = phoneclaim if form.validate_on_submit(): if not g.user.phones: primary = True else: primary = False userphone = UserPhone(user=g.user, phone=phoneclaim.phone, gets_text=True, primary=primary) db.session.add(userphone) db.session.delete(phoneclaim) db.session.commit() flash("Your phone number has been verified.", 'success') user_data_changed.send(g.user, 'phone') return render_redirect(url_for('.profile'), code=303) return render_form(form=form, title="Verify phone number", formid="phone_verify", submit="Verify", ajax=True)
def profile_edit(newprofile=False): form = ProfileForm(obj=g.user) form.edit_user = g.user form.fullname.description = current_app.config.get('FULLNAME_REASON') form.email.description = current_app.config.get('EMAIL_REASON') form.username.description = current_app.config.get('USERNAME_REASON') form.description.description = current_app.config.get('BIO_REASON') form.timezone.description = current_app.config.get('TIMEZONE_REASON') if g.user.email or newprofile is False: del form.email if newprofile is True: del form.description if form.validate_on_submit(): # Can't auto-populate here because user.email is read-only g.user.fullname = form.fullname.data g.user.username = form.username.data if not newprofile: g.user.description = form.description.data g.user.timezone = form.timezone.data if newprofile and not g.user.email: useremail = UserEmailClaim.get(user=g.user, email=form.email.data) if useremail is None: useremail = UserEmailClaim(user=g.user, email=form.email.data) db.session.add(useremail) send_email_verify_link(useremail) db.session.commit() user_data_changed.send(g.user, changes=['profile', 'email-claim']) flash("Your profile has been updated. We sent you an email to confirm your address", category='success') else: db.session.commit() user_data_changed.send(g.user, changes=['profile']) flash("Your profile has been updated.", category='success') if newprofile: return render_redirect(get_next_url(), code=303) else: return render_redirect(url_for('profile'), code=303) if newprofile: return render_form(form, title="Update profile", formid="profile_new", submit="Continue", message=Markup(u"Hello, <strong>{fullname}</strong>. Please spare a minute to fill out your profile.".format( fullname=escape(g.user.fullname))), ajax=True) else: return render_form(form, title="Edit profile", formid="profile_edit", submit="Save changes", ajax=True)
def confirm_email(md5sum, secret): emailclaim = UserEmailClaim.query.filter_by(md5sum=md5sum, verification_code=secret).first() if emailclaim is not None: if 'verify' in emailclaim.permissions(current_auth.user): existing = UserEmail.query.filter(UserEmail.email.in_([emailclaim.email, emailclaim.email.lower()])).first() if existing is not None: claimed_email = emailclaim.email claimed_user = emailclaim.user db.session.delete(emailclaim) db.session.commit() if claimed_user != current_auth.user: return render_message(title=_("Email address already claimed"), message=Markup( _(u"The email address <code>{email}</code> has already been verified by another user").format( email=escape(claimed_email)))) else: return render_message(title=_("Email address already verified"), message=Markup(_(u"Hello <strong>{fullname}</strong>! " u"Your email address <code>{email}</code> has already been verified").format( fullname=escape(claimed_user.fullname), email=escape(claimed_email)))) useremail = emailclaim.user.add_email(emailclaim.email, primary=emailclaim.user.email is None, type=emailclaim.type, private=emailclaim.private) db.session.delete(emailclaim) for claim in UserEmailClaim.query.filter( UserEmailClaim.email.in_([useremail.email, useremail.email.lower()])).all(): db.session.delete(claim) db.session.commit() user_data_changed.send(current_auth.user, changes=['email']) return render_message(title=_("Email address verified"), message=Markup(_(u"Hello <strong>{fullname}</strong>! " u"Your email address <code>{email}</code> has now been verified").format( fullname=escape(emailclaim.user.fullname), email=escape(useremail.email)))) else: return render_message( title=_("This was not for you"), message=_(u"You’ve opened an email verification link that was meant for another user. " u"If you are managing multiple accounts, please login with the correct account " u"and open the link again"), code=403) else: return render_message( title=_("Expired confirmation link"), message=_(u"The confirmation link you clicked on is either invalid or has expired"), code=404)
def make_email_primary(): form = EmailPrimaryForm() if form.validate_on_submit(): useremail = UserEmail.query.filter_by(email=form.email.data, user=current_auth.user).first() if useremail is not None and isinstance(useremail, UserEmail): if useremail.primary: flash(_("This is already your primary email address"), 'info') else: current_auth.user.primary_email = useremail db.session.commit() user_data_changed.send(current_auth.user, changes=['email-update-primary']) flash(_(u"Your primary email address has been updated"), 'success') else: flash(_("No such email address is linked to this user account"), 'danger') else: flash(_("Please select an email address"), 'danger') return render_redirect(url_for('.account'), code=303)
def remove_phone(number): userphone = UserPhone.query.filter_by(phone=number, user=g.user).first() if userphone is None: userphone = UserPhoneClaim.query.filter_by(phone=number, user=g.user).first_or_404() if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(g.user, changes=['phone-delete']) return render_delete_sqla( userphone, db, title=_(u"Confirm removal"), message=_(u"Remove phone number {phone}?").format( phone=userphone.phone), success=_(u"You have removed your number {phone}").format( phone=userphone.phone), next=url_for('.profile'))
def make_phone_primary(): form = PhonePrimaryForm() if form.validate_on_submit(): userphone = UserPhone.query.filter_by(phone=form.phone.data, user=current_auth.user).first() if userphone is not None and isinstance(userphone, UserPhone): if userphone.primary: flash(_("This is already your primary phone number"), 'info') else: current_auth.user.primary_phone = userphone db.session.commit() user_data_changed.send(current_auth.user, changes=['phone-update-primary']) flash(_(u"Your primary phone number has been updated"), 'success') else: flash(_("No such phone number is linked to this user account"), 'danger') else: flash(_("Please select a phone number"), 'danger') return render_redirect(url_for('.account'), code=303)
def remove_email(md5sum): useremail = UserEmail.query.filter_by(md5sum=md5sum, user=g.user).first() if not useremail: useremail = UserEmailClaim.query.filter_by(md5sum=md5sum, user=g.user).first_or_404() if isinstance(useremail, UserEmail) and useremail.primary: flash("You cannot remove your primary email address", "error") return render_redirect(url_for('.profile'), code=303) if request.method == 'POST': user_data_changed.send(g.user, changes=['email-delete']) return render_delete_sqla( useremail, db, title="Confirm removal", message="Remove email address %s?" % useremail, success="You have removed your email address %s." % useremail, next=url_for('.profile'))
def add_phone(): form = NewPhoneForm() if form.validate_on_submit(): userphone = UserPhoneClaim.get(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(unicode(e)) return render_form(form=form, title=_("Add a phone number"), formid='phone_add', submit=_("Verify phone"), ajax=True)
def verify_phone(phoneclaim): if phoneclaim.verification_expired: flash(_("You provided an incorrect verification code too many times"), 'danger') # Block attempts to verify this number, but also keep the claim so that a new # claim cannot be made. A periodic sweep to delete old claims is needed. return render_redirect(url_for('.account'), code=303) form = VerifyPhoneForm() form.phoneclaim = phoneclaim if form.validate_on_submit(): if UserPhone.get(phoneclaim.phone) is None: if not current_auth.user.phones: primary = True else: primary = False userphone = UserPhone(user=current_auth.user, phone=phoneclaim.phone, gets_text=True) userphone.primary = primary db.session.add(userphone) db.session.delete(phoneclaim) db.session.commit() flash(_("Your phone number has been verified"), 'success') user_data_changed.send(current_auth.user, changes=['phone']) return render_redirect(url_for('.account'), code=303) else: db.session.delete(phoneclaim) db.session.commit() flash( _("This phone number has already been claimed by another user" ), 'danger', ) elif request.method == 'POST': phoneclaim.verification_attempts += 1 db.session.commit() return render_form( form=form, title=_("Verify phone number"), formid='phone_verify', submit=_("Verify"), ajax=True, )
def remove_phone(number): userphone = UserPhone.query.filter_by(phone=number, user=current_auth.user).first() if userphone is None: userphone = UserPhoneClaim.query.filter_by(phone=number, user=current_auth.user).first_or_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=_(u"Confirm removal"), message=_(u"Remove phone number {phone} from your account?").format( phone=userphone.phone), success=_(u"You have removed your number {phone}").format(phone=userphone.phone), next=url_for('.account'), delete_text=_(u"Remove"))
def profile_merge(): if "merge_userid" not in session: return redirect(get_next_url(), code=302) other_user = User.query.filter_by(userid=session["merge_userid"]).first() if other_user is None: session.pop("merge_userid", None) return redirect(get_next_url(), code=302) form = ProfileMergeForm() if form.validate_on_submit(): if "merge" in request.form: new_user = merge_users(g.user, other_user) login_internal(new_user) user_data_changed.send(new_user, changes=["merge"]) flash("Your accounts have been merged.", "success") session.pop("merge_userid", None) return redirect(get_next_url(), code=303) else: session.pop("merge_userid", None) return redirect(get_next_url(), code=303) return render_template("merge.html", form=form, user=g.user, other_user=other_user, login_registry=login_registry)
def remove_email(md5sum): useremail = UserEmail.query.filter_by(md5sum=md5sum, user=g.user).first() if not useremail: useremail = UserEmailClaim.query.filter_by(md5sum=md5sum, user=g.user).first_or_404() if isinstance(useremail, UserEmail) and useremail.primary: flash(_("You cannot remove your primary email address"), 'error') return render_redirect(url_for('.profile'), code=303) if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(g.user, changes=['email-delete']) return render_delete_sqla( useremail, db, title=_(u"Confirm removal"), message=_(u"Remove email address {email}?").format( email=useremail.email), success=_(u"You have removed your email address {email}").format( email=useremail.email), next=url_for('.profile'))
def make_email_primary(): form = EmailPrimaryForm() if form.validate_on_submit(): useremail = UserEmail.get_for(user=current_auth.user, email=form.email.data) if useremail is not None: if useremail.primary: flash(_("This is already your primary email address"), 'info') else: current_auth.user.primary_email = useremail db.session.commit() user_data_changed.send(current_auth.user, changes=['email-update-primary']) flash(_("Your primary email address has been updated"), 'success') else: flash(_("No such email address is linked to this user account"), 'danger') else: flash(_("Please select an email address"), 'danger') return render_redirect(url_for('.account'), code=303)
def make_phone_primary(): form = PhonePrimaryForm() if form.validate_on_submit(): userphone = UserPhone.get_for(user=current_auth.user, phone=form.phone.data) if userphone is not None: if userphone.primary: flash(_("This is already your primary phone number"), 'info') else: current_auth.user.primary_phone = userphone db.session.commit() user_data_changed.send(current_auth.user, changes=['phone-update-primary']) flash(_("Your primary phone number has been updated"), 'success') else: flash(_("No such phone number is linked to this user account"), 'danger') else: flash(_("Please select a phone number"), 'danger') return render_redirect(url_for('.account'), code=303)
def verify_phone(phoneclaim): form = VerifyPhoneForm() form.phoneclaim = phoneclaim if form.validate_on_submit(): if UserPhone.get(phoneclaim.phone) is None: if not g.user.phones: primary = True else: primary = False userphone = UserPhone(user=g.user, phone=phoneclaim.phone, gets_text=True, primary=primary) db.session.add(userphone) db.session.delete(phoneclaim) db.session.commit() flash(_("Your phone number has been verified"), 'success') user_data_changed.send(g.user, changes=['phone']) return render_redirect(url_for('.profile'), code=303) else: db.session.delete(phoneclaim) db.session.commit() flash(_("This phone number has already been claimed by another user"), 'danger') return render_form(form=form, title=_("Verify phone number"), formid='phone_verify', submit=_("Verify"), ajax=True)
def account_merge(): if 'merge_buid' not in session: return redirect(get_next_url(), code=302) other_user = User.get(buid=session['merge_buid']) if other_user is None: session.pop('merge_buid', None) return redirect(get_next_url(), code=302) form = ProfileMergeForm() if form.validate_on_submit(): if 'merge' in request.form: new_user = merge_users(current_auth.user, other_user) login_internal(new_user) flash(_("Your accounts have been merged"), 'success') session.pop('merge_buid', None) db.session.commit() user_data_changed.send(new_user, changes=['merge']) return redirect(get_next_url(), code=303) else: session.pop('merge_buid', None) return redirect(get_next_url(), code=303) return render_template('merge.html.jinja2', form=form, user=current_auth.user, other_user=other_user, login_registry=login_registry)
def profile_merge(): if 'merge_userid' not in session: return redirect(get_next_url(), code=302) other_user = User.get(userid=session['merge_userid']) if other_user is None: session.pop('merge_userid', None) return redirect(get_next_url(), code=302) form = ProfileMergeForm() if form.validate_on_submit(): if 'merge' in request.form: new_user = merge_users(g.user, other_user) login_internal(new_user) user_data_changed.send(new_user, changes=['merge']) flash("Your accounts have been merged.", 'success') session.pop('merge_userid', None) return redirect(get_next_url(), code=303) else: session.pop('merge_userid', None) return redirect(get_next_url(), code=303) return render_template("merge.html", form=form, user=g.user, other_user=other_user, login_registry=login_registry)
def remove_email(md5sum): useremail = UserEmail.get_for(user=current_auth.user, md5sum=md5sum) if not useremail: useremail = UserEmailClaim.get_for(user=current_auth.user, md5sum=md5sum) if not useremail: abort(404) if isinstance(useremail, UserEmail) and useremail.primary: flash(_("You cannot remove your primary email address"), 'danger') return render_redirect(url_for('.account'), code=303) if request.method == 'POST': # FIXME: Confirm validation success user_data_changed.send(current_auth.user, changes=['email-delete']) return render_delete_sqla( useremail, db, title=_("Confirm removal"), message=_("Remove email address {email} from your account?").format( email=useremail.email), success=_("You have removed your email address {email}").format( email=useremail.email), next=url_for('.account'), delete_text=_("Remove"), )
def confirm_email(md5sum, secret): emailclaim = UserEmailClaim.get_by(md5sum=md5sum, verification_code=secret) if emailclaim is not None: if 'verify' in emailclaim.permissions(current_auth.user): existing = UserEmail.get(email=emailclaim.email) if existing is not None: claimed_email = emailclaim.email claimed_user = emailclaim.user db.session.delete(emailclaim) db.session.commit() if claimed_user != current_auth.user: return render_message( title=_("Email address already claimed"), message=Markup( _( "The email address <code>{email}</code> has already been verified by another user" ).format(email=escape(claimed_email)) ), ) else: return render_message( title=_("Email address already verified"), message=Markup( _( "Hello <strong>{fullname}</strong>! " "Your email address <code>{email}</code> has already been verified" ).format( fullname=escape(claimed_user.fullname), email=escape(claimed_email), ) ), ) useremail = emailclaim.user.add_email( emailclaim.email, primary=emailclaim.user.email is None, type=emailclaim.type, private=emailclaim.private, ) db.session.delete(emailclaim) UserEmailClaim.all(useremail.email).delete(synchronize_session=False) db.session.commit() user_data_changed.send(current_auth.user, changes=['email']) return render_message( title=_("Email address verified"), message=Markup( _( "Hello <strong>{fullname}</strong>! " "Your email address <code>{email}</code> has now been verified" ).format( fullname=escape(emailclaim.user.fullname), email=escape(useremail.email), ) ), ) else: return render_message( title=_("This was not for you"), message=_( "You’ve opened an email verification link that was meant for another user. " "If you are managing multiple accounts, please login with the correct account " "and open the link again" ), code=403, ) else: return render_message( title=_("Expired confirmation link"), message=_( "The confirmation link you clicked on is either invalid or has expired" ), code=404, )