def change_password(): """ Changes a password. Associated template: change-password.html Associated form: PasswordChangeForm """ form = PasswordChangeForm() if request.method == 'GET': return render_template('change-password.html', form=form) else: if form.validate_on_submit(): # Set the new password current_user.password = bcrypt.hashpw(form.password.data, bcrypt.gensalt()) # Save the user and log them in. db.session.commit() # Flash a message and redirect the user to the settings page flash('Your password has been successfully changed!') return redirect(url_for('remedy.settings')) else: flash_errors(form) return render_template('change-password.html', form=form), 400
def sign_up(): """ Handles user signup. Associated template: create-account.html """ form = SignUpForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return redirect(url_for('remedy.index')) if request.method == 'GET': return render_template('create-account.html', form=form) else: if form.validate_on_submit(): u = User(form.username.data, form.email.data, form.password.data) db.session.add(u) db.session.commit() login_user(u, True) return redirect(url_for('remedy.index')) else: flash_errors(form) return render_template('create-account.html', form=form), 400
def sign_up(): """ Handles user signup. Associated template: create-account.html Associated form: SignUpForm """ # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() # Get active populations and set up the form population_choices = active_populations() form = SignUpForm(request.form, population_choices) if request.method == 'GET': return render_template('create-account.html', form=form) else: if form.validate_on_submit(): # Create the user. u = User(form.username.data, form.email.data, form.password.data) # If we have a display name, use that - otherwise, # default to the username. if form.display_name.data and not form.display_name.data.isspace(): u.display_name = form.display_name.data else: u.display_name = form.username.data # Set up populations pop_ids = set(form.populations.data) for new_pop_id in pop_ids: # Find it in our population choices and add it in new_pop = next( (p for p in population_choices if p.id == new_pop_id), None) if new_pop: u.populations.append(new_pop) # Generate an activation code u.email_code = str(uuid4()) u.email_activated = False # Save the user and send a confirmation email. db.session.add(u) db.session.commit() send_confirm_account(u) # Display the success page return render_template('create-account-success.html') else: flash_errors(form) return render_template('create-account.html', form=form), 400
def sign_up(): """ Handles user signup. Associated template: create-account.html Associated form: SignUpForm """ # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() # Get active populations and set up the form population_choices = active_populations() form = SignUpForm(request.form, population_choices) if request.method == 'GET': return render_template('create-account.html', form=form) else: if form.validate_on_submit(): # Create the user. u = User(form.username.data, form.email.data, form.password.data) # If we have a display name, use that - otherwise, # default to the username. if form.display_name.data and not form.display_name.data.isspace(): u.display_name = form.display_name.data else: u.display_name = form.username.data # Set up populations pop_ids = set(form.populations.data) for new_pop_id in pop_ids: # Find it in our population choices and add it in new_pop = next((p for p in population_choices if p.id == new_pop_id), None) if new_pop: u.populations.append(new_pop) # Generate an activation code u.email_code = str(uuid4()) u.email_activated = False # Save the user and send a confirmation email. db.session.add(u) db.session.commit() send_confirm_account(u) # Display the success page return render_template('create-account-success.html') else: flash_errors(form) return render_template('create-account.html', form=form), 400
def request_password_reset(): """ Requests a password reset. Associated template: request-password-reset.html Associated form: RequestPasswordResetForm """ form = RequestPasswordResetForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() if request.method == 'GET': return render_template('request-password-reset.html', form=form) else: if form.validate_on_submit(): # Look up the user. user = User.query.filter_by(email=form.email.data).first() # Make sure the user exists. if user is not None: # Make sure the user's email has been activated. if user.email_activated == False: flash( 'You must first activate your account. Check your email for the confirmation link.' ) return login_redirect(), 401 # Generate a code and update the reset date. user.email_code = str(uuid4()) user.reset_pass_date = datetime.utcnow() # Save the user and send a confirmation email. db.session.commit() send_password_reset(user) # Flash a message and redirect the user to the login page # Note: This is outside of the user check so that people can't abuse # this system - it'll always indicate successful even if there isn't already an account. flash( 'Your password reset was successfully requested. Check your email for the link.' ) return login_redirect() else: flash_errors(form) return render_template('request-password-reset.html', form=form), 400
def sign_in(): """ Handles user sign-in. Associated template: login.html Associated form: LoginForm """ form = LoginForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() if request.method == 'GET': return render_template('login.html', form=form) else: if form.validate_on_submit(): # Look up the user user = User.query.filter_by(username=form.username.data).first() # Make sure the user exists and the password is correct. # We use different branches for the purposes of logging # the appropriate reason for the failed login. if user is None: return login_failure("Invalid username or password.", "No User", form) if not user.verify_password(form.password.data): return login_failure("Invalid username or password.", "Bad Password", form) # Lock out inactive users. if not user.active: return login_failure("Your account is currently inactive.", "Deactivated", form) # Lock out users who haven't confirmed their account. if not user.email_activated: return login_failure("Your account must first be confirmed. Please check your email (" + \ user.email + ") for the confirmation link.", "Not Confirmed", form) # We're good. login_success(user) return index_redirect() else: flash_errors(form) return render_template('login.html', form=form), 400
def sign_up(): """ Handles user signup. Associated template: create-account.html Associated form: SignUpForm """ form = SignUpForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() if request.method == 'GET': return render_template('create-account.html', form=form) else: if form.validate_on_submit(): # Create the user. u = User(form.username.data, form.email.data, form.password.data) # If we have a display name, use that - otherwise, # default to the username. if form.display_name.data and not form.display_name.data.isspace(): u.display_name = form.display_name.data else: u.display_name = form.username.data # Generate an activation code u.email_code = str(uuid4()) u.email_activated = False # Save the user and send a confirmation email. db.session.add(u) db.session.commit() send_confirm_account(u) # Display the success page return render_template('create-account-success.html') else: flash_errors(form) return render_template('create-account.html', form=form), 400
def request_password_reset(): """ Requests a password reset. Associated template: request-password-reset.html Associated form: RequestPasswordResetForm """ form = RequestPasswordResetForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() if request.method == 'GET': return render_template('request-password-reset.html', form=form) else: if form.validate_on_submit(): # Look up the user. user = User.query.filter_by(email=form.email.data).first() # Make sure the user exists. if user is not None: # Make sure the user's email has been activated. if user.email_activated == False: flash('You must first activate your account. Check your email for the confirmation link.') return login_redirect(), 401 # Generate a code and update the reset date. user.email_code = str(uuid4()) user.reset_pass_date = datetime.utcnow() # Save the user and send a confirmation email. db.session.commit() send_password_reset(user) # Flash a message and redirect the user to the login page # Note: This is outside of the user check so that people can't abuse # this system - it'll always indicate successful even if there isn't already an account. flash('Your password reset was successfully requested. Check your email for the link.') return login_redirect() else: flash_errors(form) return render_template('request-password-reset.html', form=form), 400
def sign_in(): """ Handles user sign-in. Associated template: login.html """ form = LoginForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return redirect(url_for('remedy.index')) if request.method == 'GET': return render_template('login.html', form=form) else: if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() # Make sure the user exists and the password is correct. if user is None or not user.verify_password(form.password.data): flash("Invalid username or password.") return render_template('login.html', form=form), 401 # Lock out inactive users. if not user.active: flash("Your account is currently inactive.") return render_template('login.html', form=form), 401 # We're good. login_user(user, True) return redirect(url_for('remedy.index')) flash_errors(form) return render_template('login.html', form=form), 401
def reset_password(code): """ Resets a password. Associated template: password-reset.html Associated form: PasswordResetForm Args: code: The activation code, sent through email. """ form = PasswordResetForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() # Normalize our code code = code.strip().lower() if not code: flash('A password reset code was not provided.') return login_redirect() # Find the user based on the code and if they're already activated reset_user = db.session.query(User). \ filter(User.email_code == code). \ filter(User.email_activated == True). \ first() # Make sure we have a user. if reset_user is None: flash('The provided reset code is invalid.') return login_redirect() # Only allow codes to be used for 48 hours min_reset_date = datetime.utcnow() - timedelta(days=2) if reset_user.reset_pass_date is None or \ reset_user.reset_pass_date < min_reset_date: flash( 'The reset code is invalid or has expired. You must request a new code.' ) return redirect(url_for('auth.request_password_reset')) if request.method == 'GET': return render_template('password-reset.html', form=form, code=code) else: if form.validate_on_submit(): # Set the new password reset_user.password = bcrypt.hashpw(form.password.data, bcrypt.gensalt()) # Clear the email code and reset date reset_user.email_code = None reset_user.reset_pass_date = None # Save the user and log them in. db.session.commit() login_success(reset_user) # Flash a message and redirect the user to the index flash('Your password has been successfully reset!') return index_redirect() else: flash_errors(form) return render_template('password-reset.html', form=form, code=code), 400
def reset_password(code): """ Resets a password. Associated template: password-reset.html Associated form: PasswordResetForm Args: code: The activation code, sent through email. """ form = PasswordResetForm() # Kick the current user back to the index # if they're already logged in if current_user.is_authenticated(): return index_redirect() # Normalize our code code = code.strip().lower() if not code: flash('A password reset code was not provided.') return login_redirect() # Find the user based on the code and if they're already activated reset_user = db.session.query(User). \ filter(User.email_code == code). \ filter(User.email_activated == True). \ first() # Make sure we have a user. if reset_user is None: flash('The provided reset code is invalid.') return login_redirect() # Only allow codes to be used for 48 hours min_reset_date = datetime.utcnow() - timedelta(days=2) if reset_user.reset_pass_date is None or \ reset_user.reset_pass_date < min_reset_date: flash('The reset code is invalid or has expired. You must request a new code.') return redirect(url_for('auth.request_password_reset')) if request.method == 'GET': return render_template('password-reset.html', form=form, code=code) else: if form.validate_on_submit(): # Set the new password reset_user.password = bcrypt.hashpw(form.password.data, bcrypt.gensalt()) # Clear the email code and reset date reset_user.email_code = None reset_user.reset_pass_date = None # Save the user and log them in. db.session.commit() login_success(reset_user) # Flash a message and redirect the user to the index flash('Your password has been successfully reset!') return index_redirect() else: flash_errors(form) return render_template('password-reset.html', form=form, code=code), 400