This commit is contained in:
2025-12-20 03:46:45 +01:00
parent 8c2429732e
commit a3afb0726f
-223
View File
@@ -1,223 +0,0 @@
from flask import render_template, request, make_response, redirect
import database, re, bcrypt, secrets, time
from app import app
def get_session(request):
sessionid = request.cookies.get('session')
if not sessionid:
return False
sessionid = str(sessionid)
sessioninfo = database.fetch("""SELECT uid, created_at, expires, description
FROM session
WHERE value=?;""",
[sessionid])
if len(sessioninfo) == 0:
return False
if len(sessioninfo) > 1:
# there is a problem
return False
return sessioninfo[0] + (sessionid,)
def check_pw(uid, password):
userquery = database.fetch("SELECT uid, password FROM user WHERE username=?", [username])
# STOP TIMING ATTACKS
time.sleep(secrets.randbelow(100)/50)
if len(userquery) == 0:
return render_template("auth/login.html",
response=f"Der Nutzername >{username} oder das Passwort ist falsch.",
username=username)
uidquery = userquery[0][0]
passquery = userquery[0][1]
passform = str(request.form['pass'])
passform = passform.encode("utf8")
passcorrect = bcrypt.checkpw(passform, passquery)
if not passcorrect:
return render_template("auth/login.html",
response=f"Der Nutzername {username} oder das >Passwort ist falsch.",
username=username)
@app.route("/auth/headerbar")
def headerbar():
sessioninfo = get_session(request)
if not sessioninfo:
return render_template("auth/headerbar.html", loggedin=False)
return render_template("auth/headerbar.html", loggedin=True)
@app.route("/auth/sessioninfo", methods=['GET'])
def sessioninfo():
time.sleep(secrets.randbelow(100)/50) # Rate limiting
sessioninfo = get_session(request)
if not sessioninfo:
return "Invalid session"
(uid, created_at, expires, description) = sessioninfo
# uid = sessioninfo[0][0]
# created_at = sessioninfo[0][1]
# expires = sessioninfo[0][2]
# description = sessioninfo[0][3]
return render_template("/auth/sessioninfo.html",
sessionid=sessionid,
uid=uid,
created_at=created_at,
expires=expires,
description=description)
@app.route("/auth/logout", methods=['GET'])
def logout():
sessioninfo = get_session(request)
response = redirect("/")
response.set_cookie('session', value='', expires=0)
if not sessioninfo:
return response
database.execute("DELETE FROM session WHERE value = ?", [sessioninfo[4]])
return response
@app.route("/auth/login", methods=['GET', 'POST'])
def login():
sessioninfo = get_session(request)
if sessioninfo:
uid = sessioninfo[0]
username = database.fetch("SELECT username FROM user WHERE uid = ?", [uid])
username = username[0][0]
return render_template("auth/loginsuccess.html", username=username)
if request.method == 'GET':
return render_template("auth/login.html",
response="",
username="")
username = _sanitizeUsername(request.form['user'])
if len(username) < 3:
return render_template("auth/login.html",
response=f"Der Nutzername {username} ist zu kurz.",
username=username)
userquery = database.fetch("SELECT uid, password FROM user WHERE username=?", [username])
# STOP TIMING ATTACKS
time.sleep(secrets.randbelow(100)/50)
if len(userquery) == 0:
return render_template("auth/login.html",
response=f"Der Nutzername >{username} oder das Passwort ist falsch.",
username=username)
uidquery = userquery[0][0]
passquery = userquery[0][1]
passform = str(request.form['pass'])
passform = passform.encode("utf8")
passcorrect = bcrypt.checkpw(passform, passquery)
if not passcorrect:
return render_template("auth/login.html",
response=f"Der Nutzername {username} oder das >Passwort ist falsch.",
username=username)
now = int(time.time())
timeout = int(request.form['timeout'])
timeout = now + timeout
session = secrets.randbelow(999999999)
session = str(session) + str(now)
database.execute("DELETE FROM session WHERE expires < ?", [str(now)])
database.execute("""INSERT INTO session
(uid, created_at, expires, description, value)
VALUES (?, ?, ?, ?, ?);""",
(uidquery, int(time.time()), timeout, "", session)
)
response = make_response("<script>location.href = '/';</script>")
response.set_cookie('session', value=session, expires=timeout)
return response
@app.route("/auth/newuser", methods=['GET', 'POST'])
def newuser():
if request.method == 'GET':
return render_template("auth/register.html",
responses=[],
username="")
success = True
responses = []
username = _sanitizeUsername(request.form['user'])
if len(username) < 3:
success = False
responses.append(f"Der Nutzername {username} ist zu kurz.")
usernamequery = database.fetch("SELECT id FROM user WHERE username=?", [username])
if len(usernamequery) != 0:
success = False
responses.append(f"Der Nutzername {username} wird bereits verwendet.")
pass1 = str(request.form['pass1'])
pass2 = str(request.form['pass2'])
if pass1 != pass2:
success = False
responses.append(f"Passwort und Passwortbestätigung sind ungleich.")
if len(pass1) < 10:
success = False
responses.append(f"Das Passwort ist kürzer als 10 Zeichen.")
if not success:
return render_template("auth/register.html",
responses=responses,
username=username)
uid = secrets.randbelow(99999999)
created_at = int(time.time())
# emailcode = secrets.randbelow(999999)
passsalt = bcrypt.gensalt()
passhash = bcrypt.hashpw(pass1.encode("utf8"), passsalt)
database.execute("""INSERT INTO user
(uid, created_at, username, password) VALUES
(?, ?, ?, ?)""",
(uid, created_at, username, passhash))
return render_template("auth/registersuccess.html", username=username)
def _sanitizeUsername(username):
username = str(username)
username = username.strip()
username = username[:32]
# Remove all non-word characters (everything except numbers and letters)
username = re.sub(r"[^._\w\s-]", '', username)
# Replace all runs of whitespace with a single dash
username = re.sub(r"\s+", '_', username)
return username
def _verifyEmail(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if re.match(pattern, email):
return True
else:
return False