From 0e6f6058a0eee8c2478a9a294e963d06ef849798 Mon Sep 17 00:00:00 2001 From: Ahmet Gazakbayev Date: Thu, 15 May 2025 16:21:47 +0300 Subject: [PATCH] service, readme & bug fixes in TX start logic --- README.md | 104 +++++++++++++++++++++++++++++++ example.service | 20 ++++++ server-tx/app/__init__.py | 2 + server-tx/app/_tools/database.py | 13 ++++ server-tx/app/config.py | 2 +- 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 example.service diff --git a/README.md b/README.md index e69de29..1285834 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,104 @@ +# ICPC-WEBPRINT + +This platform helps contest participants to print their code using no drivers, only web application in any browser. Supports authorization, printing PDF for administrators and teachers. + +Platform was already used on some events, like "The FPMI Cup : February, 2025" and "MIPT Open Programming Championship : April, 2025". + +## Instalation +### Environment and Service +Both RX and TX servers have the same way to install dependencies. First, be sure to have venv globally installed on your system: + +```bash +apt install python3-venv +# or +python3 -m pip install venv +``` + +After that create virtual environment: + +``` +cd print-tx # and then print-rx +python3 -m venv .venv +``` + +Enter environment and install dependencies from `requirements.txt`: + +``` +source .venv/bin/activate +python3 -m pip install -r requirements.txt +``` +Great! Now you have working system. You can start your project either running +``` +python3 -m gunicorn wsgi_back:app -c gunicorn.py +``` +in venv, or creating services on your Linux. Template could be found in `example.serivce` file. After that you can start your web app with running: +``` +systemctl start example.service +``` + +### Setting Secrets + +Change secret code, that is used to access RX server from TX in `server-tx.json` and `server-rx.json`. +Change salt and session secret key in `server-tx/app/config.py`: +``` +_SALT = '$2b$12$DE09JKsqy6Ii/zAxEAA5n.' #edit +_SECRET_SESSION_KEY = "GAZAKBAYEV-AHMET-PROJECT" #edit +``` +You can also to set super admin user (it can add and remove others): +``` +_SUPER_ADMINS = ( #edit + "god" +) +``` + +Accounts with login:password like "god:god" will be checked and created if not exist, when application start. + +### Setting ports + +You can set port of TX part in file `gunicorn.py`, and RX part in config file `server-rx.json`. Using TX interface, in admin panel, you can configure RX server and get `server-rx.json` to load it. + +### Setting default printer + +Learn more about `lp` service in Linux ([Wiki](https://ru.wikipedia.org/wiki/Lp)). + +## Features + +- Four groups: Super Admin, Admin (create and remove users, set configuration), Tutor (print PDF and code), Team Member (default, print only code) +- Print code & PDF +- Create & Delete users +- Statistic of printed pages & last printing time of member +- Setting RX server using UI +- Setting TX configuration: PDF Watermark and limits. + +## Setting user group + +Groups are just team names! Use `$root` for Admins, `$tutor$` for Teachers and other names for members. + +## Interface + +### Team Member +![Team Member](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/member_view.png&fileId=62728&x=2880&y=1800&a=true&etag=112840f341b1c0419ddb384ee1c54d9c) + +![Limit Example](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/limit_realization.png&fileId=62726&x=2880&y=1800&a=true&etag=b2a38e2f507cce30f4ece5a1d2d203e5) + +### Tutor +![Tutor](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/tutor_view.png&fileId=62729&x=2880&y=1800&a=true&etag=d8c90831ce28b0fa1056efc9bdb4e940) + +### Админ Панель +![View1](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/admin_panel_view1.png&fileId=62724&x=2880&y=1800&a=true&etag=21a34169474060c299a3e4c74c5b6076) + +![View2](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/admin_panel_view2.png&fileId=62722&x=2880&y=1800&a=true&etag=48ba6f4ff8f0b1ce9679a2ec06bb1391) + +![View3](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/admin_panel_view3.png&fileId=62720&x=2880&y=1800&a=true&etag=3e47f48910e457564c8ae692fca12506) + +![View4](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/admin_panel_view4.png&fileId=62721&x=2880&y=1800&a=true&etag=58a0d96be70a9af936510a24682dea6c) + +### Создание и Редактирование пользователя + +![Create](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/create_user.png&fileId=62723&x=2880&y=1800&a=true&etag=d29264a65fc01ac2aafa06fdd0139040) + +![Create Result](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/create_user_created.png&fileId=62725&x=2880&y=1800&a=true&etag=af5b7e8672570468acbd81ba6a675e3f) + +![Update](https://cloud.gazakbayev.net/index.php/apps/files_sharing/publicpreview/gqzmo9S8KFGcQLi?file=/edit_user.png&fileId=62727&x=2880&y=1800&a=true&etag=551dcadc3402e7555a7d701269cd0b94) + +Просмотреть данную галерею можно на [NextCloud](https://cloud.gazakbayev.net/index.php/s/gqzmo9S8KFGcQLi?dir=/) автора. \ No newline at end of file diff --git a/example.service b/example.service new file mode 100644 index 0000000..e3fa185 --- /dev/null +++ b/example.service @@ -0,0 +1,20 @@ +# +# NOTICE! Replace PATH_TO_SCRIPT with required directory! +# Paste content of this file into /etc/systemd/system/YOUR_NAME.service +# + +# Suggested names for service: print-rx.service & print-tx.server +# REMEMBER to create virtual environment before using script (read README.md) + +[Unit] +Description=Print Server TX/RX server script. +After=network.target + +[Service] +User=www-data +Group=www-data +WorkingDirectory=PATH_TO_SCRIPT +ExecStart=PATH_TO_SCRIPT/.venv/bin/gunicorn wsgi_back:app -c gunicorn.py + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/server-tx/app/__init__.py b/server-tx/app/__init__.py index 8c233fe..31c9efd 100644 --- a/server-tx/app/__init__.py +++ b/server-tx/app/__init__.py @@ -29,6 +29,8 @@ def get_app(): from app._tools.database import DataManager from app._tools.database import SessionManager DataManager.init_table() + DataManager.check_admins() SessionManager.init_table() + return app \ No newline at end of file diff --git a/server-tx/app/_tools/database.py b/server-tx/app/_tools/database.py index e3f000e..eef9c0e 100644 --- a/server-tx/app/_tools/database.py +++ b/server-tx/app/_tools/database.py @@ -4,12 +4,15 @@ import json from app._tools.models.user import User from app._tools.models.session import Session +from app._tools import passhash as Hash from app.config import _USER_DATABASE as U_DB_PATH from app.config import _TOKEN_DATABASE as T_DB_PATH from app.config import _SERVER_CONFIG as S_CFG_PATH from app.config import _SCHEMA_USERS as SCHEMA_USERS from app.config import _SCHEMA_TOKENS as SCHEMA_TOKENS +from app.config import _SUPER_ADMINS as SUPER_ADMINS +from app.config import _SALT as SALT class ConnectManager: def __init__(self, db_file : str): @@ -96,6 +99,16 @@ class DataManager: c_man = ConnectManager(U_DB_PATH) c_man.execute(SCHEMA_USERS, close_connection = False) c_man.execute("VACUUM;") + def check_admins(): + for k in SUPER_ADMINS: + if DataManager.get_user_by_name(k) == None: + DataManager.add_user( + k, + "$root$", + "Super Admin", + Hash.hashPassword(k, SALT) + ) + print(f"Create super admin {k} with password {k}") def get_user_by_name(username : str) -> User: c_man = ConnectManager(U_DB_PATH) data = c_man.execute( diff --git a/server-tx/app/config.py b/server-tx/app/config.py index 7c64a2a..c48e9dc 100644 --- a/server-tx/app/config.py +++ b/server-tx/app/config.py @@ -8,7 +8,7 @@ _USER_DATABASE = "databases/users.db" #default _TOKEN_DATABASE = "databases/tokens.db" #default _SERVER_CONFIG = "server-tx.json" #default _SALT = '$2b$12$DE09JKsqy6Ii/zAxEAA5n.' #edit -_SECRET_SESSION_KEY = "fpmi_cup_event_2025_by_MMCFPMI_developed_by_gallahad_ru_Welcomeee!!!" #edit +_SECRET_SESSION_KEY = "GAZAKBAYEV-AHMET-PROJECT" #edit _SUPER_ADMINS = ( #edit "god" )