From e37cbf9feeee5497feb6364284555840ab0b3a01 Mon Sep 17 00:00:00 2001 From: ske087 Date: Thu, 17 Jul 2025 16:01:10 +0300 Subject: [PATCH] updated settings --- app/models/user.py | 10 + app/routes/admin.py | 56 ++++- app/templates/admin/index.html | 436 ++++++++++++++++++++------------- cookies.txt | 2 - main.py | 20 +- 5 files changed, 343 insertions(+), 181 deletions(-) diff --git a/app/models/user.py b/app/models/user.py index 45ba6dd..9488065 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -30,6 +30,16 @@ class User(db.Model, UserMixin): """Check if user has admin role""" return self.role == 'admin' + @property + def is_super_admin(self): + """Check if user has super admin role""" + return self.role == 'sadmin' + + @property + def has_admin_access(self): + """Check if user has any admin access (admin or super admin)""" + return self.role in ['admin', 'sadmin'] + @property def is_active(self): """Required by Flask-Login""" diff --git a/app/routes/admin.py b/app/routes/admin.py index f27dd09..d003d6c 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -13,15 +13,25 @@ import os bp = Blueprint('admin', __name__) def admin_required(f): - """Decorator to require admin role""" + """Decorator to require admin or super admin role""" @wraps(f) def decorated_function(*args, **kwargs): - if not current_user.is_authenticated or not current_user.is_admin: + if not current_user.is_authenticated or not current_user.has_admin_access: flash('Admin access required.', 'danger') return redirect(url_for('dashboard.index')) return f(*args, **kwargs) return decorated_function +def super_admin_required(f): + """Decorator to require super admin role only""" + @wraps(f) + def decorated_function(*args, **kwargs): + if not current_user.is_authenticated or not current_user.is_super_admin: + flash('Super admin access required.', 'danger') + return redirect(url_for('dashboard.index')) + return f(*args, **kwargs) + return decorated_function + @bp.route('/') @login_required @admin_required @@ -64,10 +74,15 @@ def create_user(): flash('Password must be at least 6 characters long.', 'danger') return redirect(url_for('admin.index')) - if role not in ['user', 'admin']: + if role not in ['user', 'admin', 'sadmin']: flash('Invalid role specified.', 'danger') return redirect(url_for('admin.index')) + # Prevent creating sadmin users - sadmin only exists from deployment + if role == 'sadmin': + flash('Super admin users cannot be created through the interface.', 'danger') + return redirect(url_for('admin.index')) + # Check if user already exists if User.query.filter_by(username=username).first(): flash(f'User "{username}" already exists.', 'danger') @@ -91,7 +106,7 @@ def create_user(): @bp.route('/delete_user', methods=['POST']) @login_required -@admin_required +@super_admin_required def delete_user(): """Delete a user using POST form data""" user_id = request.form.get('user_id') @@ -107,6 +122,11 @@ def delete_user(): user = User.query.get_or_404(user_id) username = user.username + # Prevent deletion of sadmin users - they are permanent + if user.role == 'sadmin': + flash('Super admin users cannot be deleted.', 'danger') + return redirect(url_for('admin.index')) + try: db.session.delete(user) db.session.commit() @@ -122,9 +142,9 @@ def delete_user(): @bp.route('/change_role/', methods=['POST']) @login_required -@admin_required +@super_admin_required def change_role(user_id): - """Change user role""" + """Change user role - restricted to super admin""" # Prevent changing own role if user_id == current_user.id: flash('You cannot change your own role.', 'danger') @@ -133,10 +153,20 @@ def change_role(user_id): user = User.query.get_or_404(user_id) new_role = request.form.get('role') - if new_role not in ['user', 'admin']: + if new_role not in ['user', 'admin', 'sadmin']: flash('Invalid role specified.', 'danger') return redirect(url_for('admin.index')) + # Prevent any changes to sadmin users - they are permanent + if user.role == 'sadmin': + flash('Super admin users cannot have their role changed.', 'danger') + return redirect(url_for('admin.index')) + + # Prevent assigning sadmin role - sadmin only exists from deployment + if new_role == 'sadmin': + flash('Super admin role cannot be assigned through the interface.', 'danger') + return redirect(url_for('admin.index')) + try: old_role = user.role user.role = new_role @@ -423,10 +453,20 @@ def edit_user(): flash('Username cannot be empty.', 'danger') return redirect(url_for('admin.index')) - if role not in ['user', 'admin']: + if role not in ['user', 'admin', 'sadmin']: flash('Invalid role specified.', 'danger') return redirect(url_for('admin.index')) + # Prevent changing sadmin users - they are permanent + if user.role == 'sadmin': + flash('Super admin users cannot be modified.', 'danger') + return redirect(url_for('admin.index')) + + # Prevent assigning sadmin role - sadmin only exists from deployment + if role == 'sadmin': + flash('Super admin role cannot be assigned through the interface.', 'danger') + return redirect(url_for('admin.index')) + # Check if username is taken by another user if username != user.username: existing_user = User.query.filter_by(username=username).first() diff --git a/app/templates/admin/index.html b/app/templates/admin/index.html index 314189e..d5b042e 100644 --- a/app/templates/admin/index.html +++ b/app/templates/admin/index.html @@ -2,12 +2,47 @@ {% block title %}Admin Panel - SKE Digital Signage{% endblock %} +{% block extra_css %} + +{% endblock %} + {% block content %}
-

Admin Panel

+

Admin Panel + {% if current_user.is_super_admin %} + Super Admin + {% elif current_user.is_admin %} + Admin + {% endif %} +

System administration and user management

@@ -125,7 +160,8 @@ {% for user in users %} - + + {{ user.username }} {% if user.username == current_user.username %} @@ -133,8 +169,10 @@ {% endif %} - {% if user.role == 'admin' %} - Admin + {% if user.role == 'sadmin' %} + Super Admin + {% elif user.role == 'admin' %} + Admin {% else %} User {% endif %} @@ -149,28 +187,86 @@ {{ user.created_at.strftime('%Y-%m-%d') if user.created_at else 'N/A' }} {{ user.last_login.strftime('%Y-%m-%d %H:%M') if user.last_login else 'Never' }} -
- {% if user.username != current_user.username %} - + +
+ +
+ +
+ {% if current_user.is_super_admin %} +
Delete User
+

This action cannot be undone.

+
+ + +
+ {% else %} +
Delete User
+

Super admin access required.

+ - - {% else %} - - {% endif %} + {% endif %} +
+ {% endif %} {% endfor %} @@ -493,73 +589,6 @@ - - - - - -