diff --git a/auth.py b/auth.py index 6ce583a..305b455 100644 --- a/auth.py +++ b/auth.py @@ -1,35 +1,64 @@ -from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response, current_app +from flask import Blueprint, render_template, request, redirect, url_for, flash, make_response 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 +import pickle +from cryptography.fernet import Fernet +import datetime auth_bp = Blueprint("auth", __name__) -AUTOLOGIN_MAX_AGE_SECONDS = 7 * 24 * 60 * 60 -AUTOLOGIN_SALT = "lapp-autologin" +# ===================================================== +# SECRET KEY (only for this program) +# ===================================================== +# Generate once using: Fernet.generate_key() +_SECRET_KEY = b'YFK7QCyTzhyLO4vqrnRxvDAI5uu8mXEYrInEjbRoQgs=' +fernet = Fernet(_SECRET_KEY) -def autologin_serializer(): - return URLSafeTimedSerializer(current_app.config["SECRET_KEY"], salt=AUTOLOGIN_SALT) +# ===================================================== +# ENCRYPT +# ===================================================== +def encrypt_object(obj) -> bytes: + """ + Encrypt any Python object and return encrypted bytes. + """ + serialized = pickle.dumps(obj) + encrypted = fernet.encrypt(serialized) + return encrypted + +# ===================================================== +# DECRYPT +# ===================================================== +def decrypt_object(encrypted_data: bytes): + """ + Decrypt bytes back into the original Python object. + """ + decrypted = fernet.decrypt(encrypted_data) + obj = pickle.loads(decrypted) + return obj def create_cookie(userid): cookie_data = { - "user": userid + "user": userid, + "datetime": datetime.datetime.now() } - return autologin_serializer().dumps(cookie_data) + return encrypt_object(cookie_data).decode('utf-8') def is_cookie_ok_to_autologin(cookie_content): - if not cookie_content: - return 0 - + user = 0 + autologin = False 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): + cookie_data = decrypt_object(cookie_content) + user = cookie_data["user"] + dt = cookie_data["datetime"] + lastweek = datetime.datetime.now() - datetime.timedelta(days=7) + autologin = dt > lastweek + except: Log.info("Cookie error") + if autologin: + return user return 0 #. @auth_bp.route("/", methods=["GET", "POST"]) @@ -94,13 +123,12 @@ def logout(): @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"] - print(f" >>{pwd_old} {pwd_new1} {pwd_new2}") - print(f"cp: {current_user.name}") if current_user.check_password(pwd_old): if pwd_new1 == pwd_new2: current_user.set_password(pwd_new2)