def logout_client(): """ Client-initiated logout """ client = Client.query.filter_by(key=request.args['client_id']).first() if client is None: # No such client. Possible CSRF. Don't logout and don't send them back flash(logout_errormsg, 'error') return redirect(url_for('index')) if client.trusted: # This is a trusted client. Does the referring domain match? clienthost = urlparse.urlsplit(client.redirect_uri).hostname if request.referrer: if clienthost != urlparse.urlsplit(request.referrer).hostname: # Doesn't. Don't logout and don't send back flash(logout_errormsg, 'error') return redirect(url_for('index')) # else: no referrer? Either stripped out by browser or a proxy, or this is a direct link. # We can't do anything about that, so assume it's a legit case. # # If there is a next destination, is it in the same domain? if 'next' in request.args: if clienthost != urlparse.urlsplit(request.args['next']).hostname: # Doesn't. Assume CSRF and redirect to index without logout flash(logout_errormsg, 'error') return redirect(url_for('index')) # All good. Log them out and send them back logout_internal() return redirect(get_next_url(external=True)) else: # We know this client, but it's not trusted. Send back without logout. return redirect(get_next_url(external=True))
def reset_email(userid, secret): logout_internal() user = User.query.filter_by(userid=userid).first() if not user: abort(404) resetreq = PasswordResetRequest.query.filter_by(user=user, reset_code=secret).first() if not resetreq: return render_message(title="Invalid reset link", message=Markup("The reset link you clicked on is invalid.")) if resetreq.created_at < datetime.utcnow() - timedelta(days=1): # Reset code has expired (> 24 hours). Delete it db.session.delete(resetreq) db.session.commit() return render_message(title="Expired reset link", message=Markup("The reset link you clicked on has expired.")) # Reset code is valid. Now ask user to choose a new password form = PasswordResetForm() if form.validate_on_submit(): user.password = form.password.data db.session.delete(resetreq) db.session.commit() return render_message(title="Password reset complete", message=Markup( 'Your password has been reset. You may now <a href="%s">login</a> with your new password.' % escape(url_for('login')))) return render_form(form=form, title="Reset password", formid='reset', submit="Reset password", message=Markup('Hello, <strong>%s</strong>. You may now choose a new password.' % user.fullname), ajax=True)
def logout_user(): """ User-initiated logout """ if not request.referrer or (urlparse.urlsplit(request.referrer).hostname != urlparse.urlsplit(request.url).hostname): # TODO: present a logout form flash(logout_errormsg, 'error') return redirect(url_for('index')) else: logout_internal() flash('You are now logged out', category='success') return redirect(get_next_url())
def reset_email(user, kwargs): logout_internal() resetreq = PasswordResetRequest.query.filter_by( user=user, reset_code=kwargs['secret']).first() if not resetreq: return render_message( title="Invalid reset link", message=Markup("The reset link you clicked on is invalid.")) if resetreq.created_at < datetime.utcnow() - timedelta(days=1): # Reset code has expired (> 24 hours). Delete it db.session.delete(resetreq) db.session.commit() return render_message( title="Expired reset link", message=Markup("The reset link you clicked on has expired.")) # Reset code is valid. Now ask user to choose a new password form = PasswordResetForm() if form.validate_on_submit(): user.password = form.password.data db.session.delete(resetreq) db.session.commit() return render_message( title="Password reset complete", message=Markup( 'Your password has been reset. You may now <a href="%s">login</a> with your new password.' % escape(url_for('login')))) return render_form( form=form, title="Reset password", formid='reset', submit="Reset password", message=Markup( 'Hello, <strong>%s</strong>. You may now choose a new password.' % user.fullname), ajax=True)