Files
audiobook-maker-pro-v4/routes/admin_routes.py
Ashim Kumar 8e02b9ad09 first commit
2026-02-20 13:53:36 +06:00

176 lines
5.4 KiB
Python

# routes/admin_routes.py - Admin Dashboard Routes
from flask import Blueprint, request, jsonify, session, send_from_directory
from db import get_db
from auth import admin_required
admin_bp = Blueprint('admin', __name__)
@admin_bp.route('/admin')
@admin_required
def admin_page():
"""Serve admin dashboard page."""
return send_from_directory('templates', 'admin.html')
@admin_bp.route('/api/admin/users', methods=['GET'])
@admin_required
def list_users():
"""List all users."""
db = get_db()
cursor = db.cursor()
cursor.execute('''
SELECT id, username, role, is_active, created_at, last_login
FROM users ORDER BY created_at DESC
''')
users = []
for row in cursor.fetchall():
users.append({
'id': row['id'],
'username': row['username'],
'role': row['role'],
'is_active': bool(row['is_active']),
'created_at': row['created_at'],
'last_login': row['last_login']
})
return jsonify({'users': users})
@admin_bp.route('/api/admin/users', methods=['POST'])
@admin_required
def create_user():
"""Create a new user."""
data = request.json
username = data.get('username', '').strip()
password = data.get('password', '')
role = data.get('role', 'user')
if not username or not password:
return jsonify({'error': 'Username and password are required'}), 400
if len(username) < 3:
return jsonify({'error': 'Username must be at least 3 characters'}), 400
if len(password) < 4:
return jsonify({'error': 'Password must be at least 4 characters'}), 400
if role not in ('user', 'admin'):
return jsonify({'error': 'Role must be "user" or "admin"'}), 400
db = get_db()
cursor = db.cursor()
try:
cursor.execute('''
INSERT INTO users (username, password, role, is_active)
VALUES (?, ?, ?, 1)
''', (username, password, role))
db.commit()
print(f"✅ New user created: {username} (role: {role})")
return jsonify({
'success': True,
'user_id': cursor.lastrowid,
'message': f'User "{username}" created successfully'
})
except Exception as e:
if 'UNIQUE constraint' in str(e):
return jsonify({'error': f'Username "{username}" already exists'}), 400
return jsonify({'error': str(e)}), 500
@admin_bp.route('/api/admin/users/<int:user_id>', methods=['PUT'])
@admin_required
def update_user(user_id):
"""Update a user."""
data = request.json
db = get_db()
cursor = db.cursor()
cursor.execute('SELECT id, username FROM users WHERE id = ?', (user_id,))
user = cursor.fetchone()
if not user:
return jsonify({'error': 'User not found'}), 404
# Build update query dynamically
updates = []
params = []
if 'username' in data:
username = data['username'].strip()
if len(username) < 3:
return jsonify({'error': 'Username must be at least 3 characters'}), 400
updates.append('username = ?')
params.append(username)
if 'password' in data and data['password']:
password = data['password']
if len(password) < 4:
return jsonify({'error': 'Password must be at least 4 characters'}), 400
updates.append('password = ?')
params.append(password)
if 'role' in data:
role = data['role']
if role not in ('user', 'admin'):
return jsonify({'error': 'Role must be "user" or "admin"'}), 400
# Prevent demoting self
if user_id == session.get('user_id') and role != 'admin':
return jsonify({'error': 'Cannot change your own role'}), 400
updates.append('role = ?')
params.append(role)
if 'is_active' in data:
# Prevent deactivating self
if user_id == session.get('user_id') and not data['is_active']:
return jsonify({'error': 'Cannot deactivate your own account'}), 400
updates.append('is_active = ?')
params.append(1 if data['is_active'] else 0)
if not updates:
return jsonify({'error': 'No fields to update'}), 400
params.append(user_id)
try:
cursor.execute(f"UPDATE users SET {', '.join(updates)} WHERE id = ?", params)
db.commit()
return jsonify({'success': True, 'message': 'User updated successfully'})
except Exception as e:
if 'UNIQUE constraint' in str(e):
return jsonify({'error': 'Username already exists'}), 400
return jsonify({'error': str(e)}), 500
@admin_bp.route('/api/admin/users/<int:user_id>', methods=['DELETE'])
@admin_required
def delete_user(user_id):
"""Delete a user."""
# Prevent deleting self
if user_id == session.get('user_id'):
return jsonify({'error': 'Cannot delete your own account'}), 400
db = get_db()
cursor = db.cursor()
cursor.execute('SELECT id, username FROM users WHERE id = ?', (user_id,))
user = cursor.fetchone()
if not user:
return jsonify({'error': 'User not found'}), 404
cursor.execute('DELETE FROM users WHERE id = ?', (user_id,))
db.commit()
print(f"🗑️ User deleted: {user['username']}")
return jsonify({'success': True, 'message': f'User "{user["username"]}" deleted'})