datasaur/site/surveyapp/users/routes.py
2026-01-25 15:56:01 +00:00

113 lines
5.2 KiB
Python

from surveyapp import mongo, bcrypt, mail
from flask import Flask, render_template, url_for, request, flash, redirect, Blueprint
# syntax for accessing files inside packages
from surveyapp.users.forms import (RegistrationForm, LoginForm,
UpdateAccountForm, RequestPasswordForm, PasswordResetForm)
from flask_login import current_user, login_user, logout_user, login_required
from surveyapp.models import User
from surveyapp.users.utils import send_email
users = Blueprint("users", __name__)
@users.route("/register", methods=["GET", "POST"])
def register():
form = RegistrationForm()
# Checks validation when form is submitted with submit button
if form.validate_on_submit():
# Decode with UTF-8 to make the hash a string rather than byte-code
password_hash = bcrypt.generate_password_hash(form.password.data).decode("utf-8")
# One user comment was to request the email validation to not be case sensitive. It is therefore saved in the database as lower case.
mongo.db.users.insert_one({\
"firstName" : form.first_name.data,\
"lastName" : form.last_name.data,\
"email" : form.email.data.lower(),\
"password" : password_hash})
flash("Account created successfully! You can now login.", "success")
return redirect(url_for("users.login"))
return render_template("users/register.html", title = "Register", form = form)
@users.route("/login", methods=["GET", "POST"])
def login():
if current_user.is_authenticated:
return redirect(url_for("main.index"))
form = LoginForm()
if form.validate_on_submit():
user = mongo.db.users.find_one({"email": form.email.data.lower()})
if user and bcrypt.check_password_hash(user["password"], form.password.data):
user_obj = User(email=user["email"], first_name=user["firstName"], last_name=user["lastName"], _id=user["_id"])
# logs user into a session
login_user(user_obj, remember=form.remember.data)
# retrieve the page the user was attempting to access previously from the URL
next_page = request.args.get("next")
# and redirect them to that page (if it exists) using a ternary conditional
flash("Login successful.", "success")
return redirect(next_page) if next_page else redirect(url_for("main.index"))
else:
flash("Invalid username or password", "danger")
return render_template("users/login.html", title = "Login", form = form)
@users.route('/logout')
def logout():
logout_user()
flash("Logout successful.", "success")
return redirect(url_for('main.index'))
@users.route('/account', methods=["GET", "POST"])
@login_required
def account():
form = UpdateAccountForm()
if form.validate_on_submit():
# Update the 'current_user' object
current_user.first_name = form.first_name.data
current_user.last_name = form.last_name.data
current_user.email = form.email.data
# Update the user in the database
mongo.db.users.update_one({"_id": current_user._id},
{"$set": {"firstName": form.first_name.data,\
"lastName": form.last_name.data,\
"email": form.email.data.lower()}})
flash("Account details updated.", "success")
return redirect(url_for('users.account'))
form.first_name.data = current_user.first_name
form.last_name.data = current_user.last_name
form.email.data = current_user.email
return render_template("users/account.html", title = "Account", form = form)
@users.route('/reset_password', methods=["GET", "POST"])
def request_reset():
if current_user.is_authenticated:
return redirect(url_for("main.index"))
form = RequestPasswordForm()
if form.validate_on_submit():
user = mongo.db.users.find_one({"email": form.email.data.lower()})
user_obj = User(email=user["email"], first_name=user["firstName"], last_name=user["lastName"], _id=user["_id"])
send_email(user_obj)
flash("An email has been sent with a password reset link", "success")
return redirect(url_for("users.login"))
return render_template("users/request_reset.html", title="Password Reset", form=form)
@users.route('/reset_password/<token>', methods=["GET", "POST"])
def reset_password(token):
if current_user.is_authenticated:
return redirect(url_for("main.index"))
user = User.verify_reset_token(token)
if not user:
flash("That token is invalid or has expired", "warning")
return redirect(url_for("request_reset"))
form = PasswordResetForm()
if form.validate_on_submit():
# Decode with UTF-8 to make the hash a string rather than byte-code
password_hash = bcrypt.generate_password_hash(form.password.data).decode("utf-8")
# One user comment was to request the email validation to not be case sensitive. It is therefore saved in the database as lower case.
mongo.db.users.update_one({"_id": user["_id"]},
{"$set": {"password": password_hash}})
flash("Password updated! You can now login.", "success")
return redirect(url_for("users.login"))
return render_template("users/reset_password.html", title="Password Reset", form=form)