From fb2a96e94dd4f13f8c2042e2432c572257852aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Sun, 29 Jun 2025 23:13:26 +0300 Subject: [PATCH] log in --- app/__init__.py | 24 +++++++++- app/constants.py | 22 ++++++++- app/models.py | 16 +++++++ app/routes/topics.py | 9 ++++ app/routes/users.py | 77 +++++++++++++++++++++++++++++++ app/templates/base.html | 28 +++++++++++ app/templates/common/infobox.html | 10 ++++ app/templates/common/topnav.html | 22 +++++++++ app/templates/topics/topics.html | 7 +++ app/templates/users/log_in.html | 14 ++++++ app/templates/users/sign_up.html | 0 data/static/misc/error.svg | 5 ++ data/static/misc/image.svg | 5 ++ data/static/misc/info.svg | 5 ++ data/static/misc/lock.svg | 5 ++ data/static/misc/sticky.svg | 5 ++ data/static/misc/warn.svg | 5 ++ 17 files changed, 256 insertions(+), 3 deletions(-) create mode 100644 app/routes/topics.py create mode 100644 app/routes/users.py create mode 100644 app/templates/base.html create mode 100644 app/templates/common/infobox.html create mode 100644 app/templates/common/topnav.html create mode 100644 app/templates/topics/topics.html create mode 100644 app/templates/users/log_in.html create mode 100644 app/templates/users/sign_up.html create mode 100644 data/static/misc/error.svg create mode 100644 data/static/misc/image.svg create mode 100644 data/static/misc/info.svg create mode 100644 data/static/misc/lock.svg create mode 100644 data/static/misc/sticky.svg create mode 100644 data/static/misc/warn.svg diff --git a/app/__init__.py b/app/__init__.py index 1bd97ce..8ff3903 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,8 +1,12 @@ -from flask import Flask +from flask import Flask, session from dotenv import load_dotenv from .models import Avatars, Users from .auth import digest -from .constants import PermissionLevel +from .routes.users import is_logged_in, get_active_user +from .constants import ( + PermissionLevel, + InfoboxKind, InfoboxIcons, InfoboxHTMLClass + ) import os import time import secrets @@ -64,6 +68,22 @@ def create_app(): create_deleted_user() from app.routes.app import bp as app_bp + from app.routes.topics import bp as topics_bp + from app.routes.users import bp as users_bp app.register_blueprint(app_bp) + app.register_blueprint(topics_bp) + app.register_blueprint(users_bp) + + + @app.context_processor + def inject_constants(): + return { + "InfoboxIcons": InfoboxIcons, + "InfoboxHTMLClass": InfoboxHTMLClass, + } + + @app.context_processor + def inject_auth(): + return {"is_logged_in": is_logged_in, "get_active_user": get_active_user} return app diff --git a/app/constants.py b/app/constants.py index 136fdce..891f873 100644 --- a/app/constants.py +++ b/app/constants.py @@ -1,4 +1,4 @@ -from enum import Enum +from enum import Enum, IntEnum class PermissionLevel(Enum): GUEST = 0 @@ -6,3 +6,23 @@ class PermissionLevel(Enum): MODERATOR = 2 SYSTEM = 3 ADMIN = 4 + +class InfoboxKind(IntEnum): + INFO = 0 + LOCK = 1 + WARN = 2 + ERROR = 3 + +InfoboxIcons = { + InfoboxKind.INFO: "/static/misc/info.svg", + InfoboxKind.LOCK: "/static/misc/lock.svg", + InfoboxKind.WARN: "/static/misc/warn.svg", + InfoboxKind.ERROR: "/static/misc/error.svg", +} + +InfoboxHTMLClass = { + InfoboxKind.INFO: "", + InfoboxKind.LOCK: "warn", + InfoboxKind.WARN: "warn", + InfoboxKind.ERROR: "critical", +} diff --git a/app/models.py b/app/models.py index f539199..1711d1c 100644 --- a/app/models.py +++ b/app/models.py @@ -1,8 +1,24 @@ from .db import Model +from .constants import PermissionLevel class Users(Model): table = "users" + def is_guest(self): + return self.permission == PermissionLevel.GUEST.value + + def is_mod(self): + return self.permission >= PermissionLevel.MODERATOR.value + + def is_admin(self): + return self.permission == PermissionLevel.ADMIN.value + + def is_system(self): + return self.permission == PermissionLevel.SYSTEM.value + + def is_default_avatar(self): + return self.avatar_id == 1 + class Topics(Model): table = "topics" diff --git a/app/routes/topics.py b/app/routes/topics.py new file mode 100644 index 0000000..38a1ed8 --- /dev/null +++ b/app/routes/topics.py @@ -0,0 +1,9 @@ +from flask import Blueprint, render_template +from ..models import Users + +bp = Blueprint("topics", __name__, url_prefix = "/topics/") + +@bp.get("/") +def all_topics(): + admin = Users.find({"id": 1}) + return render_template("topics/topics.html", admin = admin) diff --git a/app/routes/users.py b/app/routes/users.py new file mode 100644 index 0000000..218fab5 --- /dev/null +++ b/app/routes/users.py @@ -0,0 +1,77 @@ +from flask import ( + Blueprint, render_template, request, redirect, url_for, flash, session + ) +from ..models import Users, Sessions +from ..constants import InfoboxKind +from ..auth import digest, verify +import secrets +import time + +bp = Blueprint("users", __name__, url_prefix = "/users/") + + +def is_logged_in(): + return "pyrom_session_key" in session + + +def get_active_user(): + if not is_logged_in(): + return None + sess = Sessions.find({"key": session["pyrom_session_key"]}) + if not sess: + return None + return Users.find({"id": sess.user_id}) + + +@bp.get("/log_in") +def log_in(): + return render_template("users/log_in.html") + + +@bp.post("/log_in") +def log_in_post(): + target_user = Users.find({ + "username": request.form['username'] + }) + if not target_user: + flash("Incorrect username or password.", InfoboxKind.ERROR) + return redirect(url_for("users.log_in")) + + if not verify(target_user.password_hash, request.form['password']): + 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['pyrom_session_key'] = session_obj.key + flash("Logged in!", InfoboxKind.INFO) + return redirect(url_for("users.log_in")) + + +@bp.get("/sign_up") +def sign_up(): + return "not yet" + + +@bp.get("/") +def page(username): + return "stub" + + +@bp.get("//setings") +def settings(username): + return "stub" + + +@bp.get("//inbox") +def inbox(username): + return "stub" + + +@bp.get("/list") +def user_list(): + return "stub" diff --git a/app/templates/base.html b/app/templates/base.html new file mode 100644 index 0000000..87787aa --- /dev/null +++ b/app/templates/base.html @@ -0,0 +1,28 @@ +{% from 'common/infobox.html' import infobox with context %} + + + + + {% if title %} + Porom - {% block title %}{% endblock %} + {% else %} + Porom + {% endif %} + + + + {% include 'common/topnav.html' %} + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + {{ infobox(message, category) }} + {% endfor %} + {% endif %} + {% endwith %} + {% block content %}{% endblock %} +
+ Porom commit +
+ + + diff --git a/app/templates/common/infobox.html b/app/templates/common/infobox.html new file mode 100644 index 0000000..1b55236 --- /dev/null +++ b/app/templates/common/infobox.html @@ -0,0 +1,10 @@ +{% macro infobox(message, kind=InfoboxKind.INFO) %} +
+ +
+ +
+ {{ message }} +
+
+{% endmacro %} diff --git a/app/templates/common/topnav.html b/app/templates/common/topnav.html new file mode 100644 index 0000000..35c66b5 --- /dev/null +++ b/app/templates/common/topnav.html @@ -0,0 +1,22 @@ + diff --git a/app/templates/topics/topics.html b/app/templates/topics/topics.html new file mode 100644 index 0000000..6d14113 --- /dev/null +++ b/app/templates/topics/topics.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} +{% block content %} + +{% endblock %} diff --git a/app/templates/users/log_in.html b/app/templates/users/log_in.html new file mode 100644 index 0000000..f4e895a --- /dev/null +++ b/app/templates/users/log_in.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% block title %}Log in{% endblock %} +{% block content %} + +{% endblock %} diff --git a/app/templates/users/sign_up.html b/app/templates/users/sign_up.html new file mode 100644 index 0000000..e69de29 diff --git a/data/static/misc/error.svg b/data/static/misc/error.svg new file mode 100644 index 0000000..443cbf8 --- /dev/null +++ b/data/static/misc/error.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/static/misc/image.svg b/data/static/misc/image.svg new file mode 100644 index 0000000..0af5386 --- /dev/null +++ b/data/static/misc/image.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/static/misc/info.svg b/data/static/misc/info.svg new file mode 100644 index 0000000..c145fb1 --- /dev/null +++ b/data/static/misc/info.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/static/misc/lock.svg b/data/static/misc/lock.svg new file mode 100644 index 0000000..da003c1 --- /dev/null +++ b/data/static/misc/lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/static/misc/sticky.svg b/data/static/misc/sticky.svg new file mode 100644 index 0000000..1dba928 --- /dev/null +++ b/data/static/misc/sticky.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/data/static/misc/warn.svg b/data/static/misc/warn.svg new file mode 100644 index 0000000..6131242 --- /dev/null +++ b/data/static/misc/warn.svg @@ -0,0 +1,5 @@ + + + + +