64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
from urllib.parse import urljoin, urlsplit
|
|
|
|
from flask import flash, redirect, render_template, request, url_for
|
|
from flask_login import current_user, login_required, login_user, logout_user
|
|
|
|
from . import bp
|
|
from .forms import LoginForm, LogoutForm, RegistrationForm
|
|
from .services import DuplicateUserError, authenticate_user, create_user
|
|
|
|
|
|
def _is_safe_redirect(target: str) -> bool:
|
|
host_url = urlsplit(request.host_url)
|
|
redirect_url = urlsplit(urljoin(request.host_url, target))
|
|
return redirect_url.scheme in {"http", "https"} and (
|
|
host_url.netloc == redirect_url.netloc
|
|
)
|
|
|
|
|
|
@bp.route("/login", methods=["GET", "POST"])
|
|
def login():
|
|
if current_user.is_authenticated:
|
|
return redirect(url_for("core.index"))
|
|
|
|
form = LoginForm()
|
|
if form.validate_on_submit():
|
|
user = authenticate_user(form.email.data, form.password.data)
|
|
if user is None:
|
|
flash("Email or password is incorrect.", "error")
|
|
else:
|
|
login_user(user, remember=form.remember.data)
|
|
next_page = request.args.get("next", "")
|
|
if next_page and _is_safe_redirect(next_page):
|
|
return redirect(next_page)
|
|
return redirect(url_for("core.index"))
|
|
|
|
return render_template("auth/login.html", form=form)
|
|
|
|
|
|
@bp.route("/register", methods=["GET", "POST"])
|
|
def register():
|
|
if current_user.is_authenticated:
|
|
return redirect(url_for("core.index"))
|
|
|
|
form = RegistrationForm()
|
|
if form.validate_on_submit():
|
|
try:
|
|
create_user(form.username.data, form.email.data, form.password.data)
|
|
except DuplicateUserError as exc:
|
|
flash(str(exc), "error")
|
|
else:
|
|
flash("Your account is ready. You can sign in now.", "success")
|
|
return redirect(url_for("auth.login"))
|
|
|
|
return render_template("auth/register.html", form=form)
|
|
|
|
|
|
@bp.post("/logout")
|
|
@login_required
|
|
def logout():
|
|
form = LogoutForm()
|
|
if form.validate_on_submit():
|
|
logout_user()
|
|
flash("You have been signed out.", "info")
|
|
return redirect(url_for("core.index"))
|