This commit introduces major enhancements to Talk2Me: ## Database Integration - PostgreSQL support with SQLAlchemy ORM - Redis integration for caching and real-time analytics - Automated database initialization scripts - Migration support infrastructure ## User Authentication System - JWT-based API authentication - Session-based web authentication - API key authentication for programmatic access - User roles and permissions (admin/user) - Login history and session tracking - Rate limiting per user with customizable limits ## Admin Dashboard - Real-time analytics and monitoring - User management interface (create, edit, delete users) - System health monitoring - Request/error tracking - Language pair usage statistics - Performance metrics visualization ## Key Features - Dual authentication support (token + user accounts) - Graceful fallback for missing services - Non-blocking analytics middleware - Comprehensive error handling - Session management with security features ## Bug Fixes - Fixed rate limiting bypass for admin routes - Added missing email validation method - Improved error handling for missing database tables - Fixed session-based authentication for API endpoints 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
77 lines
2.5 KiB
Python
77 lines
2.5 KiB
Python
"""
|
|
Simple admin blueprint that works without Redis/PostgreSQL
|
|
"""
|
|
from flask import Blueprint, request, jsonify, render_template, redirect, url_for, session
|
|
from functools import wraps
|
|
import os
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Create admin blueprint
|
|
admin_bp = Blueprint('admin', __name__,
|
|
template_folder='admin/templates',
|
|
static_folder='admin/static',
|
|
static_url_path='/admin/static')
|
|
|
|
def init_admin(app):
|
|
"""Initialize admin module with app configuration"""
|
|
logger.info("Admin dashboard initialized (simple mode)")
|
|
|
|
def admin_required(f):
|
|
"""Decorator to require admin authentication"""
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
# Check if user is logged in as admin
|
|
if not session.get('admin_logged_in'):
|
|
# Check for admin token in headers (for API access)
|
|
auth_header = request.headers.get('Authorization', '')
|
|
if auth_header.startswith('Bearer '):
|
|
token = auth_header[7:]
|
|
expected_token = os.environ.get('ADMIN_TOKEN', 'default-admin-token')
|
|
if token == expected_token:
|
|
return f(*args, **kwargs)
|
|
|
|
# Redirect to login for web access
|
|
return redirect(url_for('admin.login', next=request.url))
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
@admin_bp.route('/')
|
|
@admin_required
|
|
def dashboard():
|
|
"""Main admin dashboard"""
|
|
# Use simple dashboard template
|
|
return render_template('dashboard_simple.html')
|
|
|
|
@admin_bp.route('/login', methods=['GET', 'POST'])
|
|
def login():
|
|
"""Admin login page"""
|
|
if request.method == 'POST':
|
|
token = request.form.get('token', '')
|
|
expected_token = os.environ.get('ADMIN_TOKEN', 'default-admin-token')
|
|
|
|
if token == expected_token:
|
|
session['admin_logged_in'] = True
|
|
next_page = request.args.get('next', url_for('admin.dashboard'))
|
|
return redirect(next_page)
|
|
else:
|
|
return render_template('login.html', error='Invalid admin token')
|
|
|
|
return render_template('login.html')
|
|
|
|
@admin_bp.route('/logout')
|
|
def logout():
|
|
"""Admin logout"""
|
|
session.pop('admin_logged_in', None)
|
|
return redirect(url_for('admin.login'))
|
|
|
|
@admin_bp.route('/health')
|
|
def health():
|
|
"""Check admin dashboard health"""
|
|
return jsonify({
|
|
'status': 'ok',
|
|
'mode': 'simple',
|
|
'redis': 'not configured',
|
|
'postgresql': 'not configured'
|
|
}) |