Compare commits
4 Commits
dynamic-si
...
fix-dashbo
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f9e8781e3 | |||
| 880f4fb615 | |||
| 42db5e6a63 | |||
| 7394e150f1 |
172
DASHBOARD_FIX.md
Normal file
172
DASHBOARD_FIX.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Dashboard Routing Fix
|
||||
|
||||
Questo branch (`fix-dashboard-routing`) contiene le correzioni per risolvere i problemi di accesso alla dashboard nel branch `dynamic-site-enhancement`.
|
||||
|
||||
## Problemi Risolti
|
||||
|
||||
### 1. Template Mancante
|
||||
- ✅ Aggiunto il template mancante `templates/dashboard/users.html`
|
||||
- Il template è ora completo con paginazione e gestione degli errori
|
||||
|
||||
### 2. Gestione Errori Migliorata
|
||||
- ✅ Aggiunta gestione degli errori in tutte le route della dashboard
|
||||
- ✅ Messaggi di errore più dettagliati per il debugging
|
||||
- ✅ Fallback sicuri quando il database non è accessibile
|
||||
|
||||
### 3. Route di Debug
|
||||
- ✅ Aggiunta route `/dashboard/debug/auth` per controllare lo stato di autenticazione
|
||||
- ✅ Aggiunta route `/dashboard/debug/access` per testare l'accesso alla dashboard
|
||||
- ✅ Informazioni dettagliate su sessioni e privilegi utente
|
||||
|
||||
### 4. Script di Utilità
|
||||
- ✅ Creato script `utils/create_admin.py` per creare utenti amministratore
|
||||
- ✅ Supporto per creare, listare e promuovere utenti
|
||||
|
||||
## Come Risolvere i Problemi di Accesso
|
||||
|
||||
### Passo 1: Verifica la Configurazione
|
||||
|
||||
Assicurati che il file `config.py` abbia la `SECRET_KEY` configurata:
|
||||
|
||||
```python
|
||||
SECRET_KEY = 'your-secret-key-here'
|
||||
```
|
||||
|
||||
### Passo 2: Inizializza il Database
|
||||
|
||||
Assicurati che il database sia inizializzato e accessibile:
|
||||
|
||||
```bash
|
||||
# Con Docker Compose
|
||||
docker-compose up -d db
|
||||
|
||||
# Controlla i log per errori
|
||||
docker-compose logs app
|
||||
```
|
||||
|
||||
### Passo 3: Crea un Utente Amministratore
|
||||
|
||||
Usa lo script di utilità per creare un utente admin:
|
||||
|
||||
```bash
|
||||
# Crea utente admin predefinito
|
||||
python utils/create_admin.py create
|
||||
|
||||
# Oppure promuovi un utente esistente
|
||||
python utils/create_admin.py promote username
|
||||
|
||||
# Lista tutti gli utenti
|
||||
python utils/create_admin.py list
|
||||
```
|
||||
|
||||
### Passo 4: Testa l'Accesso
|
||||
|
||||
1. **Controlla lo stato di autenticazione:**
|
||||
```
|
||||
GET /dashboard/debug/auth
|
||||
```
|
||||
Questo ti dirà se sei loggato e hai i privilegi corretti.
|
||||
|
||||
2. **Testa l'accesso alla dashboard:**
|
||||
```
|
||||
GET /dashboard/debug/access
|
||||
```
|
||||
Questo ti dirà se puoi accedere alla dashboard e perché.
|
||||
|
||||
3. **Effettua il login:**
|
||||
- Vai a `/auth/login`
|
||||
- Usa le credenziali dell'utente admin
|
||||
- Dovresti essere reindirizzato automaticamente a `/dashboard/`
|
||||
|
||||
## Credenziali Admin Predefinite
|
||||
|
||||
Se usi lo script `create_admin.py create`, verranno create queste credenziali:
|
||||
|
||||
- **Username:** `admin`
|
||||
- **Email:** `admin@hersel.it`
|
||||
- **Password:** `admin123`
|
||||
|
||||
⚠️ **IMPORTANTE:** Cambia la password predefinita dopo il primo login!
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problema: "401 Login required"
|
||||
**Soluzione:** Non sei loggato. Vai a `/auth/login` e effettua il login.
|
||||
|
||||
### Problema: "403 Admin access required"
|
||||
**Soluzione:** Il tuo utente non ha privilegi di amministratore. Usa:
|
||||
```bash
|
||||
python utils/create_admin.py promote il_tuo_username
|
||||
```
|
||||
|
||||
### Problema: "500 Internal Server Error"
|
||||
**Possibili cause:**
|
||||
1. Database non accessibile
|
||||
2. Errore nei template
|
||||
3. Configurazione mancante
|
||||
|
||||
**Debug:**
|
||||
1. Controlla i log dell'applicazione
|
||||
2. Usa le route di debug: `/dashboard/debug/auth` e `/dashboard/debug/access`
|
||||
3. Verifica la configurazione del database
|
||||
|
||||
### Problema: Template non trovato
|
||||
**Soluzione:** Assicurati che tutti i template esistano in `templates/dashboard/`:
|
||||
- `index.html` ✅
|
||||
- `projects.html` ✅
|
||||
- `project_form.html` ✅
|
||||
- `users.html` ✅ (aggiunto in questo fix)
|
||||
- `base.html` ✅
|
||||
|
||||
## URL della Dashboard
|
||||
|
||||
Dopo aver risolto i problemi di autenticazione, puoi accedere a:
|
||||
|
||||
- **Dashboard principale:** `/dashboard/`
|
||||
- **Gestione progetti:** `/dashboard/projects`
|
||||
- **Nuovo progetto:** `/dashboard/projects/new`
|
||||
- **Gestione utenti:** `/dashboard/users`
|
||||
- **Debug autenticazione:** `/dashboard/debug/auth`
|
||||
- **Test accesso:** `/dashboard/debug/access`
|
||||
|
||||
## Modifiche Apportate
|
||||
|
||||
1. **`templates/dashboard/users.html`** - Nuovo template per la gestione utenti
|
||||
2. **`routes/dashboard.py`** - Migliorate gestione errori e aggiunte route di debug
|
||||
3. **`utils/create_admin.py`** - Nuovo script per gestire utenti amministratore
|
||||
4. **`DASHBOARD_FIX.md`** - Questa documentazione
|
||||
|
||||
## Come Applicare i Fix
|
||||
|
||||
1. **Merge di questo branch:**
|
||||
```bash
|
||||
git checkout dynamic-site-enhancement
|
||||
git merge fix-dashboard-routing
|
||||
```
|
||||
|
||||
2. **Oppure crea un PR:**
|
||||
- Crea una pull request da `fix-dashboard-routing` a `dynamic-site-enhancement`
|
||||
- Rivedi le modifiche e fai il merge
|
||||
|
||||
3. **Testa l'applicazione:**
|
||||
```bash
|
||||
# Restart dell'applicazione
|
||||
docker-compose restart app
|
||||
|
||||
# Crea utente admin
|
||||
docker-compose exec app python utils/create_admin.py create
|
||||
|
||||
# Testa l'accesso
|
||||
curl http://localhost:5000/dashboard/debug/access
|
||||
```
|
||||
|
||||
## Supporto
|
||||
|
||||
Se hai ancora problemi dopo aver applicato questi fix:
|
||||
|
||||
1. Controlla i log dell'applicazione
|
||||
2. Usa le route di debug per diagnosticare il problema
|
||||
3. Verifica che il database sia accessibile
|
||||
4. Assicurati di avere un utente con privilegi di amministratore
|
||||
|
||||
Tutti i fix sono backward-compatible e non dovrebbero causare problemi al codice esistente.
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# Dashboard Routes (Admin)
|
||||
|
||||
from quart import Blueprint, request, render_template, redirect, url_for, jsonify
|
||||
from quart import Blueprint, request, render_template, redirect, url_for, jsonify, session
|
||||
from models.user import User
|
||||
from models.project import Project
|
||||
from models.category import Category
|
||||
@@ -13,27 +13,115 @@ from utils.validators import validate_project_data
|
||||
|
||||
dashboard_bp = Blueprint('dashboard', __name__, url_prefix='/dashboard')
|
||||
|
||||
# Debug route to check authentication status
|
||||
@dashboard_bp.route('/debug/auth')
|
||||
async def debug_auth():
|
||||
"""Debug route to check authentication status"""
|
||||
current_user = await get_current_user()
|
||||
session_data = dict(session)
|
||||
|
||||
debug_info = {
|
||||
'session_exists': 'user_id' in session,
|
||||
'user_id_in_session': session.get('user_id'),
|
||||
'username_in_session': session.get('username'),
|
||||
'is_admin_in_session': session.get('is_admin'),
|
||||
'current_user_found': current_user is not None,
|
||||
'current_user_is_admin': current_user.is_admin if current_user else None,
|
||||
'current_user_details': {
|
||||
'id': current_user.id,
|
||||
'username': current_user.username,
|
||||
'email': current_user.email,
|
||||
'role': current_user.role,
|
||||
'is_admin': current_user.is_admin
|
||||
} if current_user else None,
|
||||
'session_data': session_data
|
||||
}
|
||||
|
||||
return jsonify(debug_info)
|
||||
|
||||
# Public route to check dashboard access without admin_required decorator
|
||||
@dashboard_bp.route('/debug/access')
|
||||
async def debug_access():
|
||||
"""Debug route to check dashboard access requirements"""
|
||||
try:
|
||||
current_user = await get_current_user()
|
||||
|
||||
if not current_user:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Nessun utente loggato',
|
||||
'redirect': url_for('auth.login')
|
||||
}), 401
|
||||
|
||||
if not current_user.is_admin:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Utente {current_user.username} non ha privilegi di amministratore',
|
||||
'user_role': current_user.role,
|
||||
'is_admin': current_user.is_admin,
|
||||
'redirect': url_for('home.index')
|
||||
}), 403
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': f'Accesso consentito per {current_user.username}',
|
||||
'user': {
|
||||
'id': current_user.id,
|
||||
'username': current_user.username,
|
||||
'role': current_user.role,
|
||||
'is_admin': current_user.is_admin
|
||||
},
|
||||
'dashboard_url': url_for('dashboard.index')
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Errore durante il controllo accesso: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@dashboard_bp.route('/')
|
||||
@admin_required
|
||||
async def index():
|
||||
"""Dashboard home"""
|
||||
current_user = await get_current_user()
|
||||
|
||||
# Get statistics
|
||||
stats = {
|
||||
'total_users': await User.count(),
|
||||
'total_projects': await Project.count(published_only=False),
|
||||
'published_projects': await Project.count(published_only=True),
|
||||
'featured_projects': len(await Project.get_featured())
|
||||
}
|
||||
|
||||
# Get recent projects
|
||||
recent_projects = await Project.get_all(published_only=False, limit=5)
|
||||
|
||||
return await render_template('dashboard/index.html',
|
||||
user=current_user,
|
||||
stats=stats,
|
||||
recent_projects=recent_projects)
|
||||
try:
|
||||
current_user = await get_current_user()
|
||||
|
||||
# Get statistics with error handling
|
||||
stats = {
|
||||
'total_users': 0,
|
||||
'total_projects': 0,
|
||||
'published_projects': 0,
|
||||
'featured_projects': 0
|
||||
}
|
||||
|
||||
try:
|
||||
stats['total_users'] = await User.count()
|
||||
except Exception as e:
|
||||
print(f"Error getting user count: {e}")
|
||||
|
||||
try:
|
||||
stats['total_projects'] = await Project.count(published_only=False)
|
||||
stats['published_projects'] = await Project.count(published_only=True)
|
||||
featured_projects = await Project.get_featured()
|
||||
stats['featured_projects'] = len(featured_projects) if featured_projects else 0
|
||||
except Exception as e:
|
||||
print(f"Error getting project stats: {e}")
|
||||
|
||||
# Get recent projects with error handling
|
||||
recent_projects = []
|
||||
try:
|
||||
recent_projects = await Project.get_all(published_only=False, limit=5)
|
||||
except Exception as e:
|
||||
print(f"Error getting recent projects: {e}")
|
||||
|
||||
return await render_template('dashboard/index.html',
|
||||
user=current_user,
|
||||
stats=stats,
|
||||
recent_projects=recent_projects)
|
||||
except Exception as e:
|
||||
flash_message(f'Errore nel caricamento della dashboard: {str(e)}', 'error')
|
||||
return redirect(url_for('home.index'))
|
||||
|
||||
@dashboard_bp.route('/projects')
|
||||
@admin_required
|
||||
@@ -42,26 +130,34 @@ async def projects():
|
||||
page = int(request.args.get('page', 1))
|
||||
per_page = 10
|
||||
|
||||
# Get projects with pagination
|
||||
projects = await Project.get_all(published_only=False, limit=per_page, offset=(page-1)*per_page)
|
||||
total_projects = await Project.count(published_only=False)
|
||||
|
||||
pagination = calculate_pagination(total_projects, page, per_page)
|
||||
|
||||
return await render_template('dashboard/projects.html',
|
||||
projects=projects,
|
||||
pagination=pagination)
|
||||
try:
|
||||
# Get projects with pagination
|
||||
projects = await Project.get_all(published_only=False, limit=per_page, offset=(page-1)*per_page)
|
||||
total_projects = await Project.count(published_only=False)
|
||||
|
||||
pagination = calculate_pagination(total_projects, page, per_page)
|
||||
|
||||
return await render_template('dashboard/projects.html',
|
||||
projects=projects,
|
||||
pagination=pagination)
|
||||
except Exception as e:
|
||||
flash_message(f'Errore nel caricamento dei progetti: {str(e)}', 'error')
|
||||
return redirect(url_for('dashboard.index'))
|
||||
|
||||
@dashboard_bp.route('/projects/new', methods=['GET', 'POST'])
|
||||
@admin_required
|
||||
async def new_project():
|
||||
"""Create new project"""
|
||||
if request.method == 'GET':
|
||||
categories = await Category.get_all()
|
||||
return await render_template('dashboard/project_form.html',
|
||||
project=None,
|
||||
categories=categories,
|
||||
action='create')
|
||||
try:
|
||||
categories = await Category.get_all()
|
||||
return await render_template('dashboard/project_form.html',
|
||||
project=None,
|
||||
categories=categories,
|
||||
action='create')
|
||||
except Exception as e:
|
||||
flash_message(f'Errore nel caricamento delle categorie: {str(e)}', 'error')
|
||||
return redirect(url_for('dashboard.projects'))
|
||||
|
||||
form_data = await request.form
|
||||
data = {
|
||||
@@ -208,11 +304,15 @@ async def users():
|
||||
page = int(request.args.get('page', 1))
|
||||
per_page = 10
|
||||
|
||||
users = await User.get_all(limit=per_page, offset=(page-1)*per_page)
|
||||
total_users = await User.count()
|
||||
|
||||
pagination = calculate_pagination(total_users, page, per_page)
|
||||
|
||||
return await render_template('dashboard/users.html',
|
||||
users=users,
|
||||
pagination=pagination)
|
||||
try:
|
||||
users = await User.get_all(limit=per_page, offset=(page-1)*per_page)
|
||||
total_users = await User.count()
|
||||
|
||||
pagination = calculate_pagination(total_users, page, per_page)
|
||||
|
||||
return await render_template('dashboard/users.html',
|
||||
users=users,
|
||||
pagination=pagination)
|
||||
except Exception as e:
|
||||
flash_message(f'Errore nel caricamento degli utenti: {str(e)}', 'error')
|
||||
return redirect(url_for('dashboard.index'))
|
||||
157
templates/dashboard/users.html
Normal file
157
templates/dashboard/users.html
Normal file
@@ -0,0 +1,157 @@
|
||||
{% extends "dashboard/base.html" %}
|
||||
|
||||
{% block title %}Gestione Utenti - Dashboard{% endblock %}
|
||||
|
||||
{% block dashboard_content %}
|
||||
<div class="dashboard-header">
|
||||
<h1 class="dashboard-title">
|
||||
<i class="fas fa-users"></i>
|
||||
Gestione Utenti
|
||||
</h1>
|
||||
<div class="dashboard-actions">
|
||||
<span class="badge badge-info">{{ pagination.total_items if pagination else 0 }} utenti totali</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-content">
|
||||
{% if users %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Username</th>
|
||||
<th>Nome Completo</th>
|
||||
<th>Email</th>
|
||||
<th>Ruolo</th>
|
||||
<th>Stato</th>
|
||||
<th>Registrato</th>
|
||||
<th>Ultimo Accesso</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.id }}</td>
|
||||
<td>
|
||||
<strong>{{ user.username }}</strong>
|
||||
{% if user.is_admin %}
|
||||
<span class="badge badge-danger ms-1">Admin</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ user.full_name or '-' }}</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<span class="badge {% if user.role == 'admin' %}badge-danger{% else %}badge-secondary{% endif %}">
|
||||
{{ user.role.title() }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {% if user.is_active %}badge-success{% else %}badge-warning{% endif %}">
|
||||
{% if user.is_active %}Attivo{% else %}Inattivo{% endif %}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if user.created_at %}
|
||||
<small>{{ user.created_at.strftime('%d/%m/%Y %H:%M') }}</small>
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if user.last_login %}
|
||||
<small>{{ user.last_login.strftime('%d/%m/%Y %H:%M') }}</small>
|
||||
{% else %}
|
||||
<span class="text-muted">Mai</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if pagination and pagination.total_pages > 1 %}
|
||||
<nav aria-label="User pagination" class="mt-4">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% if pagination.has_prev %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ url_for('dashboard.users', page=pagination.prev_num) }}">
|
||||
<i class="fas fa-chevron-left"></i> Precedente
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for page_num in pagination.iter_pages() %}
|
||||
{% if page_num %}
|
||||
{% if page_num != pagination.page %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ url_for('dashboard.users', page=page_num) }}">{{ page_num }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item active">
|
||||
<span class="page-link">{{ page_num }}</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">…</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if pagination.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ url_for('dashboard.users', page=pagination.next_num) }}">
|
||||
Successivo <i class="fas fa-chevron-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="alert alert-info text-center">
|
||||
<i class="fas fa-info-circle fa-2x mb-3"></i>
|
||||
<h4>Nessun utente trovato</h4>
|
||||
<p class="mb-0">Non ci sono utenti registrati nel sistema.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.dashboard-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid #e9ecef;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
color: #495057;
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dashboard-title i {
|
||||
color: #6c757d;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.table th {
|
||||
font-weight: 600;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.alert i {
|
||||
color: #0dcaf0;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
147
utils/create_admin.py
Normal file
147
utils/create_admin.py
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Utility script to create an admin user
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add the parent directory to Python path to import our modules
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from models.database import init_database
|
||||
from models.user import User
|
||||
|
||||
async def create_admin_user():
|
||||
"""Create an admin user for dashboard access"""
|
||||
try:
|
||||
# Initialize database
|
||||
await init_database()
|
||||
print("✅ Database connection established")
|
||||
|
||||
# Check if admin user already exists
|
||||
existing_admin = await User.find_by_username('admin')
|
||||
if existing_admin:
|
||||
print("⚠️ Admin user already exists!")
|
||||
print(f" Username: {existing_admin.username}")
|
||||
print(f" Email: {existing_admin.email}")
|
||||
print(f" Role: {existing_admin.role}")
|
||||
print(f" Is Admin: {existing_admin.is_admin}")
|
||||
return
|
||||
|
||||
# Create admin user
|
||||
admin_user = User(
|
||||
username='admin',
|
||||
email='admin@hersel.it',
|
||||
first_name='Admin',
|
||||
last_name='User',
|
||||
role='admin'
|
||||
)
|
||||
|
||||
# Set password (change this to a secure password)
|
||||
admin_password = 'admin123' # CHANGE THIS IN PRODUCTION!
|
||||
admin_user.set_password(admin_password)
|
||||
|
||||
# Save user
|
||||
await admin_user.save()
|
||||
|
||||
print("🎉 Admin user created successfully!")
|
||||
print("📝 Login credentials:")
|
||||
print(f" Username: {admin_user.username}")
|
||||
print(f" Email: {admin_user.email}")
|
||||
print(f" Password: {admin_password}")
|
||||
print(f" Role: {admin_user.role}")
|
||||
print(f" Is Admin: {admin_user.is_admin}")
|
||||
print("")
|
||||
print("🔐 IMPORTANT: Change the default password after first login!")
|
||||
print("📍 You can now access the dashboard at: /dashboard/")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error creating admin user: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
async def list_users():
|
||||
"""List all users in the system"""
|
||||
try:
|
||||
await init_database()
|
||||
users = await User.get_all()
|
||||
|
||||
if not users:
|
||||
print("No users found in the system.")
|
||||
return
|
||||
|
||||
print("\n👥 Users in the system:")
|
||||
print("-" * 80)
|
||||
print(f"{'ID':<5} {'Username':<15} {'Email':<25} {'Role':<10} {'Admin':<7} {'Active':<8}")
|
||||
print("-" * 80)
|
||||
|
||||
for user in users:
|
||||
print(f"{user.id:<5} {user.username:<15} {user.email:<25} {user.role:<10} {user.is_admin:<7} {user.is_active:<8}")
|
||||
|
||||
print("-" * 80)
|
||||
print(f"Total users: {len(users)}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error listing users: {e}")
|
||||
|
||||
async def promote_user_to_admin(username):
|
||||
"""Promote an existing user to admin"""
|
||||
try:
|
||||
await init_database()
|
||||
user = await User.find_by_username(username)
|
||||
|
||||
if not user:
|
||||
print(f"❌ User '{username}' not found.")
|
||||
return
|
||||
|
||||
# Update user role
|
||||
user.role = 'admin'
|
||||
await user.save()
|
||||
|
||||
print(f"✅ User '{username}' promoted to admin successfully!")
|
||||
print(f" Username: {user.username}")
|
||||
print(f" Email: {user.email}")
|
||||
print(f" Role: {user.role}")
|
||||
print(f" Is Admin: {user.is_admin}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error promoting user: {e}")
|
||||
|
||||
def print_usage():
|
||||
"""Print usage instructions"""
|
||||
print("Usage:")
|
||||
print(" python utils/create_admin.py create # Create default admin user")
|
||||
print(" python utils/create_admin.py list # List all users")
|
||||
print(" python utils/create_admin.py promote <username> # Promote user to admin")
|
||||
print("")
|
||||
print("Examples:")
|
||||
print(" python utils/create_admin.py create")
|
||||
print(" python utils/create_admin.py promote john_doe")
|
||||
|
||||
async def main():
|
||||
"""Main function"""
|
||||
if len(sys.argv) < 2:
|
||||
print_usage()
|
||||
return
|
||||
|
||||
command = sys.argv[1].lower()
|
||||
|
||||
if command == 'create':
|
||||
await create_admin_user()
|
||||
elif command == 'list':
|
||||
await list_users()
|
||||
elif command == 'promote':
|
||||
if len(sys.argv) < 3:
|
||||
print("❌ Please provide a username to promote.")
|
||||
print(" Usage: python utils/create_admin.py promote <username>")
|
||||
return
|
||||
username = sys.argv[2]
|
||||
await promote_user_to_admin(username)
|
||||
else:
|
||||
print(f"❌ Unknown command: {command}")
|
||||
print_usage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user