From 4a9f5382ad52bbf6ba78aea3535405cce3333089 Mon Sep 17 00:00:00 2001 From: filak Date: Tue, 17 Dec 2024 14:12:52 +0100 Subject: [PATCH 1/3] Version 1.6.8 --- flask-app/application/main.py | 10 ++++++--- flask-app/application/modules/auth.py | 12 +++++++++++ flask-app/application/modules/database.py | 7 +++++++ flask-app/application/modules/extensions.py | 9 ++++++++ flask-app/application/modules/routes.py | 21 ++++++++++--------- flask-app/application/templates/login.html | 11 +++------- flask-app/instance/conf/mtw.ini | 1 - flask-app/mtw-server.py | 2 +- flask-app/mtw_requirements.txt | 23 +++++++++++---------- flask-app/set-mtw-admin.py | 2 +- 10 files changed, 63 insertions(+), 35 deletions(-) diff --git a/flask-app/application/main.py b/flask-app/application/main.py index 722309c..25ac355 100644 --- a/flask-app/application/main.py +++ b/flask-app/application/main.py @@ -8,7 +8,7 @@ from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix -from application.modules.extensions import Talisman, cache, csrf, paranoid, sess +from application.modules.extensions import Talisman, cache, csrf, paranoid, sess # limiter from application.modules import utils as mtu @@ -56,7 +56,7 @@ def create_app(debug=False, logger=None, port=5900, app.config.update(dict( APPLICATION_ROOT = url_prefix, APP_NAME = 'MTW', - APP_VER = '1.6.7', + APP_VER = '1.6.8', API_VER = '1.0.0', DBVERSION = 1.0, CACHE_DIR = mtu.get_instance_dir(app, 'cache'), @@ -132,9 +132,13 @@ def create_app(debug=False, logger=None, port=5900, cache.init_app(app) sess.init_app(app) - # SeaSurf (csrf) & Talisman + # Limiter + # limiter.init_app(app) + + # SeaSurf (csrf) csrf.init_app(app) + # Talisman if not relax and not app.debug: # Paranoid paranoid.init_app(app) diff --git a/flask-app/application/modules/auth.py b/flask-app/application/modules/auth.py index 556f627..7f30483 100644 --- a/flask-app/application/modules/auth.py +++ b/flask-app/application/modules/auth.py @@ -1,3 +1,4 @@ +import bcrypt from functools import wraps from itsdangerous import URLSafeTimedSerializer from secrets import compare_digest @@ -14,6 +15,17 @@ from flask import current_app as app +def hash_pwd(password): + return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') + + +def check_pwd(password, hashed_password): + try: + return bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8')) + except ValueError: + return False + + def login_required(f): @wraps(f) def secure_function(*args, **kwargs): diff --git a/flask-app/application/modules/database.py b/flask-app/application/modules/database.py index e8bbcdf..4fcafce 100644 --- a/flask-app/application/modules/database.py +++ b/flask-app/application/modules/database.py @@ -8,6 +8,8 @@ from flask import flash, g from flask import current_app as app +from application.modules.auth import hash_pwd + # Database @@ -38,6 +40,9 @@ def get_db(): def addUser(username, firstname, lastname, passwd, ugroup, phone='', email=''): db = get_db() try: + if passwd: + passwd = hash_pwd(passwd) + db.execute('insert into users (username, passwd, firstname, lastname, ugroup, phone, email) values (?, ?, ?, ?, ?, ?, ?)', [username, passwd, firstname, lastname, ugroup, phone, email]) db.commit() @@ -73,6 +78,8 @@ def updateUser(username, firstname, lastname, passwd, ugroup, userid, phone='', db = get_db() try: if passwd: + passwd = hash_pwd(passwd) + db.execute('update users set username = ?, firstname = ?, lastname = ?, passwd = ?, ugroup = ?, phone = ?, email = ? where id = ?', [username, firstname, lastname, passwd, ugroup, phone, email, userid]) else: diff --git a/flask-app/application/modules/extensions.py b/flask-app/application/modules/extensions.py index 08bb7c1..87806ef 100644 --- a/flask-app/application/modules/extensions.py +++ b/flask-app/application/modules/extensions.py @@ -3,6 +3,8 @@ Flask Extensions """ from flask_caching import Cache +# from flask_limiter import Limiter +# from flask_limiter.util import get_remote_address from flask_paranoid import Paranoid from flask_seasurf import SeaSurf from flask_session import Session @@ -18,3 +20,10 @@ paranoid = Paranoid() sess = Session() + +''' +limiter = Limiter(key_func=get_remote_address, + headers_enabled=False, + in_memory_fallback_enabled=True, + default_limits=["60/minute"]) +''' diff --git a/flask-app/application/modules/routes.py b/flask-app/application/modules/routes.py index a73e45b..4ae9a9d 100644 --- a/flask-app/application/modules/routes.py +++ b/flask-app/application/modules/routes.py @@ -13,11 +13,11 @@ from flask import current_app as app -from application.main import cache +from application.main import cache # limiter from application.modules import database as mdb from application.modules import sparql as sparql from application.modules import utils as mtu -from application.modules.auth import login_required +from application.modules.auth import login_required, check_pwd from flask import (abort, flash, g, make_response, redirect, render_template, request, send_from_directory, session, @@ -1527,15 +1527,13 @@ def add_user(): email = request.form.get('email') phone = request.form.get('phone') - passwd_hashed = bcrypt.hashpw(passwd.encode('utf-8'), bcrypt.gensalt(5)) - params = {} params['insert'] = {} params['insert'].update({'firstname': firstname}) params['insert'].update({'lastname': lastname}) params['insert'].update({'role': ugroup}) - res = mdb.addUser(username, firstname, lastname, passwd_hashed.decode('utf-8'), ugroup, phone=phone, email=email) + res = mdb.addUser(username, firstname, lastname, passwd, ugroup, phone=phone, email=email) if res: flash(res, 'danger') @@ -1572,8 +1570,6 @@ def update_user(): params['changed'] = [] if passwd: - passwd = bcrypt.hashpw(passwd.encode('utf-8'), bcrypt.gensalt(5)) - passwd = passwd.decode('utf-8') params['changed'].append('password') if action == 'delete': @@ -1607,14 +1603,19 @@ def update_user(): # Login | Logout @app.route('/login/', methods=['GET', 'POST']) +# @limiter.limit("10/minute") def login(): error = None login = False + isadmin = None + + if session.get('logged_in'): + return redirect(url_for('intro')) if request.method == 'POST': username = request.form['username'] password = request.form['password'] - isadmin = request.form['isadmin'] + isadmin = request.form.get('isadmin') if isadmin == 'yes': if username == app.config['ADMINNAME'] and bcrypt.checkpw(password.encode('utf-8'), app.config['ADMINPASS'].encode('utf-8')): @@ -1626,8 +1627,8 @@ def login(): udata = mdb.getUserPwd(username) if udata: - if bcrypt.checkpw(password.encode('utf-8'), udata['passwd'].encode('utf-8')): - login = True + if udata.get('passwd'): + login = check_pwd(password, udata['passwd']) if not login: error = 'Invalid username or password' diff --git a/flask-app/application/templates/login.html b/flask-app/application/templates/login.html index 75b819c..fb5ceca 100644 --- a/flask-app/application/templates/login.html +++ b/flask-app/application/templates/login.html @@ -26,18 +26,13 @@

Login required

- -
+ + +
- - - - - -
diff --git a/flask-app/instance/conf/mtw.ini b/flask-app/instance/conf/mtw.ini index 3a409c9..e8aa7c9 100644 --- a/flask-app/instance/conf/mtw.ini +++ b/flask-app/instance/conf/mtw.ini @@ -80,7 +80,6 @@ CSRF_COOKIE_SECURE = False ## See: https://flask-caching.readthedocs.io/en/latest/ #CACHING = {"CACHE_TYPE": "null"} - CACHING = {"CACHE_DEFAULT_TIMEOUT": 1800, "CACHE_THRESHOLD": 500} ### Flask-Session params diff --git a/flask-app/mtw-server.py b/flask-app/mtw-server.py index 8de2e45..869a5f4 100644 --- a/flask-app/mtw-server.py +++ b/flask-app/mtw-server.py @@ -14,7 +14,7 @@ DEFAULT_PREFIX = 'mtw' appname = 'mtw-server' -appdesc = 'MTW Server 1.6.7' +appdesc = 'MTW Server 1.6.8' appusage = 'Help: ' + appname + ' -h \n' appauthor = 'Filip Kriz' diff --git a/flask-app/mtw_requirements.txt b/flask-app/mtw_requirements.txt index fbbfa3c..b235f06 100644 --- a/flask-app/mtw_requirements.txt +++ b/flask-app/mtw_requirements.txt @@ -1,15 +1,16 @@ -### Version 1.6.7 +### Version 1.6.8 ### Python 3.12 ### arrow==1.3.0 -bcrypt==4.2.0 ## NOT python-bcrypt !!! +bcrypt==4.2.1 ## NOT python-bcrypt !!! cachelib==0.9.0 ## Stick to 0.9.0 OR run after pip install -r ... : # pip install cachelib --upgrade --force -certifi==2024.8.30 +certifi==2024.12.14 cffi==1.17.1 colorama==0.4.6 diff_match_patch==20241021 -Flask==3.0.3 +Flask==3.1.0 Flask-Caching==2.3.0 +# Flask-Limiter==3.9.2 Flask-Paranoid==0.3.0 Flask-SeaSurf==2.0.0 Flask-Session==0.8.0 @@ -22,15 +23,15 @@ MarkupSafe==3.0.2 pip_audit==2.7.3 ## Run: pip freeze > requirements.txt ; pip-audit ; pip-audit -r mtw_requirements.txt pyuca==1.2 requests==2.32.3 -requests_futures==1.0.1 -setuptools==75.3.0 +requests_futures==1.0.2 +setuptools==75.6.0 urllib3==1.26.20 -waitress==3.0.1 -Werkzeug==3.0.6 -wheel==0.44.0 +waitress==3.0.2 +Werkzeug==3.1.3 +wheel==0.45.1 ### (optional) If building for Windows: -pyinstaller==6.11.0; sys_platform == "win32" -pyinstaller-hooks-contrib==2024.8; sys_platform == "win32" +pyinstaller==6.11.1; sys_platform == "win32" +pyinstaller-hooks-contrib==2024.10; sys_platform == "win32" ## Install pywin32 pywin32==308; sys_platform == "win32" ## and run in CMD as Admin with activated VENV (!): diff --git a/flask-app/set-mtw-admin.py b/flask-app/set-mtw-admin.py index b866e1a..4880e41 100644 --- a/flask-app/set-mtw-admin.py +++ b/flask-app/set-mtw-admin.py @@ -54,7 +54,7 @@ def procFile(args): config.set(section, 'ADMINNAME', args.login) pwd = args.pwd - pwd_hashed = bcrypt.hashpw(pwd.encode('utf-8'), bcrypt.gensalt(5)) + pwd_hashed = bcrypt.hashpw(pwd.encode('utf-8'), bcrypt.gensalt()) config.set(section, 'ADMINPASS', pwd_hashed.decode('utf-8')) section = 'worker' From 74bb8ed16fe672ec3bace3296ccc9299ebd8f307 Mon Sep 17 00:00:00 2001 From: filak Date: Tue, 17 Dec 2024 14:56:46 +0100 Subject: [PATCH 2/3] Better build batch --- flask-app/!!build__dist_pyinstaller.bat | 104 ++++++++++++++++++++++++ flask-app/!!build__mtw-server.bat | 57 ------------- flask-app/!!build__mtw-tools.bat | 58 ------------- flask-app/!!build__mtw-worker.bat | 42 ---------- flask-app/!!build__set-mtw-admin.bat | 34 -------- 5 files changed, 104 insertions(+), 191 deletions(-) create mode 100644 flask-app/!!build__dist_pyinstaller.bat delete mode 100644 flask-app/!!build__mtw-server.bat delete mode 100644 flask-app/!!build__mtw-tools.bat delete mode 100644 flask-app/!!build__mtw-worker.bat delete mode 100644 flask-app/!!build__set-mtw-admin.bat diff --git a/flask-app/!!build__dist_pyinstaller.bat b/flask-app/!!build__dist_pyinstaller.bat new file mode 100644 index 0000000..8ce0e17 --- /dev/null +++ b/flask-app/!!build__dist_pyinstaller.bat @@ -0,0 +1,104 @@ +@echo off +setlocal +echo. +set python=venv\Scripts\pyinstaller.exe + +echo. +choice /C AN /M "Activate Python VENV ? A/N" +if errorlevel 2 goto:start + +echo. +echo Activating VENV +call venv\Scripts\activate + +:start +echo. +choice /C AN /M "Clean build ? A/N" +if errorlevel 1 set buildClean=--clean +if errorlevel 2 set buildClean= + +choice /C AN /M "Test run ? A/N" +if errorlevel 1 set testRun=1 +if errorlevel 2 set testRun=0 + +echo Build using pyinstaller : %python% + +set srcDir=application +set targetDir=dist +set subdir= +set logFile=!build_dist_pyinstaller.rep + +echo. +echo Cleaning static files %targetDir% ... +RMDIR %targetDir%\static /S /Q +RMDIR %targetDir%\templates /S /Q +MKDIR %targetDir%\static +MKDIR %targetDir%\templates + +echo. +echo Copying files from: static, templates ... +xcopy %srcDir%\static %targetDir%\static /E /Q /Y +xcopy %srcDir%\templates %targetDir%\templates /E /Q /Y + +echo. > %logFile% + +set fileHandle=mtw-server +set extras=--add-data %srcDir%/pyuca/*.txt;pyuca +set subdir= +call:buildFiles + +set fileHandle=mtw-worker +set extras=--add-data %srcDir%/pyuca/*.txt;pyuca +set subdir= +call:buildFiles + +set fileHandle=set-mtw-admin +set extras= +set subdir= +call:buildFiles + +set fileHandle=mesh-nt2trx +set extras= +set subdir=tools\ +call:buildFiles + +set fileHandle=mesh-trx2nt +set extras= +set subdir=tools\ +call:buildFiles + +set fileHandle=mesh-xml2trx +set extras= +set subdir=tools\ +call:buildFiles + +echo. +echo Finished !!! +echo. + +title Finished building! +goto:eof + +:buildFiles +set srcFile=%subdir%%fileHandle%.py +echo. +echo Building %srcFile% +title Building %srcFile% + +CALL %python% --log-level ERROR --onefile %extras% --distpath %targetDir%\%subdir% %srcFile% %buildClean% >> %logFile% 2>&1 + +if %testRun%==1 call:runTestHelp +goto:eof + +:runTestHelp +echo. +set binFile=%subdir%%fileHandle%.exe +echo Running %targetDir%\%binFile% ... +CALL %targetDir%\%binFile% -h +echo. +echo Done. +echo. +goto:eof + +endlocal + diff --git a/flask-app/!!build__mtw-server.bat b/flask-app/!!build__mtw-server.bat deleted file mode 100644 index 6f742f9..0000000 --- a/flask-app/!!build__mtw-server.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off -setlocal -echo. -REM set python=c:\Programs\Python\Python38\Scripts\pyinstaller.exe -set python=venv\Scripts\pyinstaller.exe -echo Build using pyinstaller : %python% - -echo. -choice /C AN /M "Activate Python VENV ? A/N" -if errorlevel 2 goto:start - -echo. -echo Activating VENV -call venv\Scripts\activate - -:start -set targetDir=dist -set fileHandle=mtw-server -set srcFile=%fileHandle%.py -set srcDir=application -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Stop the service: %targetDir%\%fileHandle%.exe - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean ^ - --add-data %srcDir%/pyuca/*.txt;pyuca ^ - --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - -echo - Done! -echo. -echo Cleaning static files %targetDir% ... - -RMDIR %targetDir%\static /S /Q -RMDIR %targetDir%\templates /S /Q - -echo - Done! -echo. -echo Copying files... - -MKDIR %targetDir%\static -xcopy %srcDir%\static %targetDir%\static /E /Q /Y -MKDIR %targetDir%\templates -xcopy %srcDir%\templates %targetDir%\templates /E /Q /Y -echo - Done! -echo. - -echo. -echo Finished -echo. - -endlocal diff --git a/flask-app/!!build__mtw-tools.bat b/flask-app/!!build__mtw-tools.bat deleted file mode 100644 index 35db71d..0000000 --- a/flask-app/!!build__mtw-tools.bat +++ /dev/null @@ -1,58 +0,0 @@ -@echo off -setlocal -echo. -REM set python=c:\Programs\Python\Python38\Scripts\pyinstaller.exe -set python=venv\Scripts\pyinstaller.exe -echo Build using pyinstaller : %python% -set targetDir=dist\tools - -echo. -choice /C AN /M "Activate Python VENV ? A/N" -if errorlevel 2 goto:start - -echo. -echo Activating VENV -call venv\Scripts\activate - -:start -set fileHandle=mesh-nt2trx -set srcFile=tools\%fileHandle%.py -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - - -set fileHandle=mesh-trx2nt -set srcFile=tools\%fileHandle%.py -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - - -set fileHandle=mesh-xml2trx -set srcFile=tools\%fileHandle%.py -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - - -echo. -echo Finished -echo. - -endlocal diff --git a/flask-app/!!build__mtw-worker.bat b/flask-app/!!build__mtw-worker.bat deleted file mode 100644 index 13c8f0c..0000000 --- a/flask-app/!!build__mtw-worker.bat +++ /dev/null @@ -1,42 +0,0 @@ -@echo off -setlocal -echo. -REM set python=c:\Programs\Python\Python38\Scripts\pyinstaller.exe -set python=venv\Scripts\pyinstaller.exe -echo Build using pyinstaller : %python% - -echo. -choice /C AN /M "Activate Python VENV ? A/N" -if errorlevel 2 goto:start - -echo. -echo Activating VENV -call venv\Scripts\activate - -:start -set targetDir=dist -set fileHandle=mtw-worker -set srcFile=%fileHandle%.py -set srcDir=application -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Stop the service: %targetDir%\%fileHandle%.exe - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean ^ - --add-data %srcDir%/pyuca/*.txt;pyuca ^ - --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - -echo - Done! -echo. - -echo. -echo Finished -echo. - -endlocal diff --git a/flask-app/!!build__set-mtw-admin.bat b/flask-app/!!build__set-mtw-admin.bat deleted file mode 100644 index e9e2d03..0000000 --- a/flask-app/!!build__set-mtw-admin.bat +++ /dev/null @@ -1,34 +0,0 @@ -@echo off -setlocal -echo. -REM set python=c:\Programs\Python\Python38\Scripts\pyinstaller.exe -set python=venv\Scripts\pyinstaller.exe -echo Build using pyinstaller : %python% - -echo. -choice /C AN /M "Activate Python VENV ? A/N" -if errorlevel 2 goto:start - -echo. -echo Activating VENV -call venv\Scripts\activate - -:start -set targetDir=dist -set fileHandle=set-mtw-admin -set srcFile=%fileHandle%.py -set logFile=!build_%fileHandle%.rep - -echo. > %logFile% - -echo. -echo Building %srcFile% ... - -CALL %python% --log-level ERROR --onefile --clean ^ - --distpath %targetDir% %srcFile% >> %logFile% 2>&1 - -echo. -echo Finished -echo. - -endlocal From 7ce87a716f259d0e5df54e666ea9d4309d0c9066 Mon Sep 17 00:00:00 2001 From: filak Date: Tue, 17 Dec 2024 15:07:21 +0100 Subject: [PATCH 3/3] Update !!build__dist_pyinstaller.bat --- flask-app/!!build__dist_pyinstaller.bat | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/flask-app/!!build__dist_pyinstaller.bat b/flask-app/!!build__dist_pyinstaller.bat index 8ce0e17..3933f0b 100644 --- a/flask-app/!!build__dist_pyinstaller.bat +++ b/flask-app/!!build__dist_pyinstaller.bat @@ -32,13 +32,11 @@ echo. echo Cleaning static files %targetDir% ... RMDIR %targetDir%\static /S /Q RMDIR %targetDir%\templates /S /Q -MKDIR %targetDir%\static -MKDIR %targetDir%\templates echo. echo Copying files from: static, templates ... -xcopy %srcDir%\static %targetDir%\static /E /Q /Y -xcopy %srcDir%\templates %targetDir%\templates /E /Q /Y +xcopy %srcDir%\static %targetDir%\static /I /E /Q /Y +xcopy %srcDir%\templates %targetDir%\templates /I /E /Q /Y echo. > %logFile%