This commit is contained in:
2025-07-17 16:17:52 +03:00
parent e37cbf9fee
commit 67dfb671c4
4 changed files with 119 additions and 20 deletions

View File

@@ -78,9 +78,9 @@ def create_user():
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')
# Prevent regular admins from creating sadmin users - only sadmin can create sadmin
if role == 'sadmin' and not current_user.is_super_admin:
flash('Only super admin users can create other super admin users.', 'danger')
return redirect(url_for('admin.index'))
# Check if user already exists
@@ -106,7 +106,7 @@ def create_user():
@bp.route('/delete_user', methods=['POST'])
@login_required
@super_admin_required
@admin_required
def delete_user():
"""Delete a user using POST form data"""
user_id = request.form.get('user_id')
@@ -122,9 +122,9 @@ 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')
# Prevent deletion of sadmin users by regular admins - only sadmin can delete sadmin
if user.role == 'sadmin' and not current_user.is_super_admin:
flash('Only super admin users can delete other super admin users.', 'danger')
return redirect(url_for('admin.index'))
try:
@@ -457,14 +457,14 @@ def edit_user():
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')
# Prevent regular admins from modifying sadmin users - only sadmin can modify sadmin
if user.role == 'sadmin' and not current_user.is_super_admin:
flash('Only super admin users can modify other super admin users.', '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')
# Prevent regular admins from assigning sadmin role - only sadmin can assign sadmin
if role == 'sadmin' and not current_user.is_super_admin:
flash('Only super admin users can assign super admin role.', 'danger')
return redirect(url_for('admin.index'))
# Check if username is taken by another user

View File

@@ -161,7 +161,7 @@
<tbody>
{% for user in users %}
<!-- Main user row (clickable) -->
<tr class="user-row {% if user.username != current_user.username and user.role != 'sadmin' %}clickable-row{% endif %}" data-user-id="{{ user.id }}" {% if user.username != current_user.username and user.role != 'sadmin' %}style="cursor: pointer;"{% endif %}>
<tr class="user-row {% if user.username != current_user.username and (user.role != 'sadmin' or current_user.is_super_admin) %}clickable-row{% endif %}" data-user-id="{{ user.id }}" {% if user.username != current_user.username and (user.role != 'sadmin' or current_user.is_super_admin) %}style="cursor: pointer;"{% endif %}>
<td>
<strong>{{ user.username }}</strong>
{% if user.username == current_user.username %}
@@ -187,10 +187,10 @@
<td>{{ user.created_at.strftime('%Y-%m-%d') if user.created_at else 'N/A' }}</td>
<td>{{ user.last_login.strftime('%Y-%m-%d %H:%M') if user.last_login else 'Never' }}</td>
<td>
{% if user.username != current_user.username and user.role != 'sadmin' %}
{% if user.username != current_user.username and (user.role != 'sadmin' or current_user.is_super_admin) %}
<i class="bi bi-chevron-down expand-icon"></i>
<small class="text-muted">Click to edit</small>
{% elif user.role == 'sadmin' %}
{% elif user.role == 'sadmin' and not current_user.is_super_admin %}
<span class="badge bg-danger">Protected</span>
{% else %}
<span class="badge bg-secondary">Current User</span>
@@ -199,7 +199,7 @@
</tr>
<!-- Expandable edit row (hidden by default) -->
{% if user.username != current_user.username and user.role != 'sadmin' %}
{% if user.username != current_user.username and (user.role != 'sadmin' or current_user.is_super_admin) %}
<tr class="edit-row" id="edit-row-{{ user.id }}" style="display: none;">
<td colspan="6" class="bg-light">
<div class="row p-3">
@@ -223,6 +223,9 @@
<select name="role" class="form-select form-select-sm">
<option value="user" {% if user.role == 'user' %}selected{% endif %}>User</option>
<option value="admin" {% if user.role == 'admin' %}selected{% endif %}>Admin</option>
{% if current_user.is_super_admin %}
<option value="sadmin" {% if user.role == 'sadmin' %}selected{% endif %}>Super Admin</option>
{% endif %}
</select>
</div>
@@ -246,7 +249,7 @@
</div>
<div class="col-md-4">
{% if current_user.is_super_admin %}
{% if current_user.has_admin_access and (user.role != 'sadmin' or current_user.is_super_admin) %}
<h6 class="text-danger"><i class="bi bi-trash"></i> Delete User</h6>
<p class="small text-muted">This action cannot be undone.</p>
<form method="POST" action="{{ url_for('admin.delete_user') }}" onsubmit="return confirm('Are you sure you want to delete user {{ user.username }}? This action cannot be undone!');">
@@ -257,7 +260,7 @@
</form>
{% else %}
<h6 class="text-muted"><i class="bi bi-shield-lock"></i> Delete User</h6>
<p class="small text-muted">Super admin access required.</p>
<p class="small text-muted">{% if user.role == 'sadmin' %}Super admin users cannot be deleted{% else %}Admin access required{% endif %}.</p>
<button type="button" class="btn btn-outline-secondary btn-sm" disabled>
<i class="bi bi-shield-lock"></i> Restricted
</button>
@@ -577,6 +580,9 @@
<select class="form-select" id="role" name="role">
<option value="user">User</option>
<option value="admin">Admin</option>
{% if current_user.is_super_admin %}
<option value="sadmin">Super Admin</option>
{% endif %}
</select>
</div>
</div>

View File

@@ -80,7 +80,7 @@
<i class="bi bi-house"></i> Dashboard
</a>
</li>
{% if current_user.is_admin %}
{% if current_user.has_admin_access %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('content.upload') }}">
<i class="bi bi-cloud-upload"></i> Upload Content