From bd563100675538af116e2765a11b06a79b98e6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Sun, 29 Jun 2025 23:54:29 +0300 Subject: [PATCH] sign up --- app/routes/app.py | 6 +-- app/routes/users.py | 67 ++++++++++++++++++++++++++++---- app/templates/users/log_in.html | 2 +- app/templates/users/sign_up.html | 17 ++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/app/routes/app.py b/app/routes/app.py index 67b0e87..bef5e5a 100644 --- a/app/routes/app.py +++ b/app/routes/app.py @@ -1,7 +1,7 @@ -from flask import Blueprint +from flask import Blueprint, redirect, url_for bp = Blueprint("app", __name__, url_prefix = "/") @bp.route("/") -def hello_world(): - return f"" +def index(): + return redirect(url_for("topics.all_topics")) diff --git a/app/routes/users.py b/app/routes/users.py index 218fab5..e83961a 100644 --- a/app/routes/users.py +++ b/app/routes/users.py @@ -2,10 +2,11 @@ from flask import ( Blueprint, render_template, request, redirect, url_for, flash, session ) from ..models import Users, Sessions -from ..constants import InfoboxKind +from ..constants import InfoboxKind, PermissionLevel from ..auth import digest, verify import secrets import time +import re bp = Blueprint("users", __name__, url_prefix = "/users/") @@ -23,6 +24,24 @@ def get_active_user(): return Users.find({"id": sess.user_id}) +def create_session(user_id): + return Sessions.create({ + "key": secrets.token_hex(16), + "user_id": user_id, + "expires_at": int(time.time()) + 30 * 24 * 60 * 60, + }) + + +def validate_password(password): + pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_])(?!.*\s).{10,255}$' + return bool(re.fullmatch(pattern, password)) + + +def validate_username(username): + pattern = r'^[a-zA-Z0-9_-]{3,20}$' + return bool(re.fullmatch(pattern, username)) + + @bp.get("/log_in") def log_in(): return render_template("users/log_in.html") @@ -41,11 +60,7 @@ def log_in_post(): flash("Incorrect username or password.", InfoboxKind.ERROR) return redirect(url_for("users.log_in")) - session_obj = Sessions.create({ - "key": secrets.token_hex(16), - "user_id": target_user.id, - "expires_at": int(time.time()) + 30 * 24 * 60 * 60, - }) + session_obj = create_session(target_user.id) session['pyrom_session_key'] = session_obj.key flash("Logged in!", InfoboxKind.INFO) @@ -54,7 +69,45 @@ def log_in_post(): @bp.get("/sign_up") def sign_up(): - return "not yet" + return render_template("users/sign_up.html") + + +@bp.post("/sign_up") +def sign_up_post(): + username = request.form['username'] + password = request.form['password'] + password_confirm = request.form['password-confirm'] + + if not validate_username(username): + flash("Invalid username.", InfoboxKind.ERROR) + return redirect(url_for("users.sign_up")) + + user_exists = Users.count({"username": username}) > 0 + if user_exists: + flash(f"Username '{username}' is already taken.", InfoboxKind.ERROR) + return redirect(url_for("users.sign_up")) + + if not validate_password(password): + flash("Invalid password.", InfoboxKind.ERROR) + return redirect(url_for("users.sign_up")) + + if password != password_confirm: + flash("Passwords do not match.", InfoboxKind.ERROR) + return redirect(url_for("users.sign_up")) + + hashed = digest(password) + + new_user = Users.create({ + "username": username, + "password_hash": hashed, + "permission": PermissionLevel.GUEST.value, + }) + + session_obj = create_session(new_user.id) + + session['pyrom_session_key'] = session_obj.key + flash("Signed up successfully!", InfoboxKind.INFO) + return redirect(url_for("users.sign_up")) @bp.get("/") diff --git a/app/templates/users/log_in.html b/app/templates/users/log_in.html index f4e895a..2e91e03 100644 --- a/app/templates/users/log_in.html +++ b/app/templates/users/log_in.html @@ -2,7 +2,7 @@ {% block title %}Log in{% endblock %} {% block content %}