from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response, current_app from flask_login import login_user, logout_user, login_required, current_user from models import db from models import User from log import Log from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer auth_bp = Blueprint("auth", __name__) AUTOLOGIN_MAX_AGE_SECONDS = 7 * 24 * 60 * 60 AUTOLOGIN_SALT = "lapp-autologin" def autologin_serializer(): return URLSafeTimedSerializer(current_app.config["SECRET_KEY"], salt=AUTOLOGIN_SALT) def create_cookie(userid): cookie_data = { "user": userid } return autologin_serializer().dumps(cookie_data) def is_cookie_ok_to_autologin(cookie_content): if not cookie_content: return 0 try: cookie_data = autologin_serializer().loads(cookie_content, max_age=AUTOLOGIN_MAX_AGE_SECONDS) return int(cookie_data["user"]) except (BadSignature, SignatureExpired, KeyError, TypeError, ValueError): Log.info("Cookie error") return 0 #. @auth_bp.route("/", methods=["GET", "POST"]) @auth_bp.route("/login", methods=["GET", "POST"]) def login(): username = request.cookies.get('username') userid = is_cookie_ok_to_autologin(username) if userid>0: user = User.query.filter_by(id=userid).first() if user and user.is_approved and user.group_id>0: login_user(user) return redirect(url_for("lists.home")) if request.method == "POST": user = User.query.filter_by(name=request.form["name"]).first() if user and user.check_password(request.form["password"]): if not user.is_approved: return render_template("pending.html") if user.group_id>0: login_user(user) return redirect(url_for("lists.home")) # flash("Invalid key credentials.") Log.info(f"Authorization failure for user '{request.form["name"]}' ") login_failed = request.method == "POST" resp = make_response(render_template( "login.html", name_placeholder="Sorry" if login_failed else "Name", password_placeholder="Try again" if login_failed else "Password", )) resp.set_cookie('username', '') return resp @auth_bp.route("/register", methods=["GET", "POST"]) def register(): if request.method == "POST": name = request.form["name"].strip() group = request.form["group"] password = request.form["password"] existing_user = User.query.filter_by(name=name).first() if existing_user: return render_template("register.html", error="That name is already registered.") user = User(name=name) group_id = user.set_group_id(group) if group_id == 0: return render_template("register.html", error="Unknown registration key.") user.set_password(password) user.group_id = group_id db.session.add(user) db.session.commit() return render_template("pending.html") return render_template("register.html") @auth_bp.route("/logout") @login_required def logout(): logout_user() resp = make_response(redirect(url_for("auth.login"))) resp.set_cookie('username', '') return resp @auth_bp.route("/change_pwd", methods=["GET", "POST"]) @login_required def change_pwd(): if request.method == "POST": pwd_old = request.form["password_old"] pwd_new1 = request.form["password_new1"] pwd_new2 = request.form["password_new2"] if not current_user.check_password(pwd_old): flash("Invalid old credentials") Log.info(f"Authorization failure for user '{current_user.name}' ") elif pwd_new1 != pwd_new2: flash("New Passwords are not identical") else: current_user.set_password(pwd_new2) db.session.commit() return redirect(url_for("lists.home")) return redirect(url_for("auth.change_pwd")) return render_template("change_pwd.html")