Compare commits
17 Commits
d325a52222
...
main
Author | SHA1 | Date | |
---|---|---|---|
d3d3c98f99 | |||
9e010ed389 | |||
636a382cf5 | |||
76a351710f | |||
c1f0da4a9c | |||
eefc952ff0 | |||
8c35b3bd8c | |||
60011b1c72 | |||
859a962c12 | |||
0e9df4f859 | |||
1554404657 | |||
925af7d314 | |||
fb260a0f6d | |||
dcd9a39b46 | |||
8194e3e9fe | |||
0006044ae4 | |||
74a58879ce |
@ -4,7 +4,7 @@ from flask_jwt_extended import JWTManager
|
||||
from jwt import ExpiredSignatureError
|
||||
from models import db, RevokedToken
|
||||
import os
|
||||
from utils import init_db
|
||||
from utils import init_db, wait_for_db
|
||||
from views import user_bp
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
@ -53,6 +53,7 @@ def create_app(config_name="default"):
|
||||
|
||||
# Fill database by initial values (only if we are not testing)
|
||||
with app.app_context():
|
||||
wait_for_db()
|
||||
db.create_all()
|
||||
if config_name != "testing":
|
||||
init_db()
|
||||
@ -61,5 +62,7 @@ def create_app(config_name="default"):
|
||||
|
||||
# Server start only if we run app directly
|
||||
if __name__ == "__main__":
|
||||
from waitress import serve
|
||||
app = create_app()
|
||||
app.run(host="0.0.0.0")
|
||||
port = os.getenv("APP_PORT", "80")
|
||||
serve(app, host="0.0.0.0", port=port)
|
||||
|
@ -11,4 +11,5 @@ mysql-connector-python==9.2.0
|
||||
python-dotenv==1.0.0
|
||||
SQLAlchemy==2.0.23
|
||||
typing_extensions==4.8.0
|
||||
waitress==3.0.2
|
||||
Werkzeug==3.0.1
|
||||
|
27
api/utils.py
27
api/utils.py
@ -2,6 +2,9 @@ from flask import abort
|
||||
from flask_jwt_extended import get_jwt_identity
|
||||
from models import User, db
|
||||
import os
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.exc import DatabaseError
|
||||
import time
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
|
||||
@ -19,6 +22,30 @@ def validate_access(owner_id, message='Access denied.'):
|
||||
abort(403, message)
|
||||
|
||||
|
||||
def get_user_or_404(user_id):
|
||||
"Get user from database or abort 404"
|
||||
user = db.session.get(User, user_id)
|
||||
if user is None:
|
||||
abort(404, "User not found")
|
||||
return user
|
||||
|
||||
|
||||
MAX_RETRIES = 100
|
||||
|
||||
def wait_for_db():
|
||||
for retries in range(MAX_RETRIES):
|
||||
try:
|
||||
with db.engine.connect() as connection:
|
||||
connection.execute(text("SELECT 1"))
|
||||
print("Successfully connected with database.")
|
||||
return
|
||||
except DatabaseError:
|
||||
print(f"Waiting for database... (retry {retries + 1})")
|
||||
time.sleep(3)
|
||||
print("Failed to connect to database.")
|
||||
raise Exception("Database not ready after multiple retries.")
|
||||
|
||||
|
||||
def init_db():
|
||||
"""Create default admin account if database is empty"""
|
||||
with db.session.begin():
|
||||
|
12
api/views.py
12
api/views.py
@ -2,7 +2,7 @@ from flask import Blueprint, jsonify, request, abort
|
||||
from flask_jwt_extended import create_access_token, set_access_cookies, jwt_required, \
|
||||
verify_jwt_in_request, get_jwt_identity, unset_jwt_cookies, get_jwt
|
||||
from models import db, RevokedToken, User
|
||||
from utils import admin_required, validate_access
|
||||
from utils import admin_required, validate_access, get_user_or_404
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
|
||||
user_bp = Blueprint('user_bp', __name__)
|
||||
@ -23,9 +23,7 @@ def get_all_users():
|
||||
@jwt_required()
|
||||
def get_user(user_id):
|
||||
validate_access(user_id) # check if user tries to read other user account details
|
||||
user = db.session.get(User, user_id)
|
||||
if user is None:
|
||||
abort(404, "User not found.")
|
||||
user = get_user_or_404(user_id)
|
||||
return jsonify(user.to_dict())
|
||||
|
||||
|
||||
@ -59,7 +57,7 @@ def edit_user(user_id):
|
||||
if request_fields != editable_fields:
|
||||
abort(400, "Invalid request data structure.")
|
||||
|
||||
user_to_update = User.query.get_or_404(user_id)
|
||||
user_to_update = get_user_or_404(user_id)
|
||||
for field_name in editable_fields:
|
||||
requested_value = request_data.get(field_name)
|
||||
if requested_value is None:
|
||||
@ -75,9 +73,7 @@ def edit_user(user_id):
|
||||
@jwt_required()
|
||||
def remove_user(user_id):
|
||||
validate_access(user_id) # Only admin can remove other users accounts
|
||||
user_to_delete = db.session.get(User, user_id)
|
||||
if user_to_delete is None:
|
||||
abort(404, "User not found.")
|
||||
user_to_delete = get_user_or_404(user_id)
|
||||
db.session.delete(user_to_delete)
|
||||
db.session.commit()
|
||||
return jsonify({"msg": "User removed successfully."})
|
||||
|
Reference in New Issue
Block a user