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")) return redirect(url_for("core.login")) @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"))