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>
149 lines
4.5 KiB
Python
149 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Initialize authentication database and create default admin user"""
|
|
|
|
import os
|
|
import sys
|
|
import getpass
|
|
from flask import Flask
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
# Add parent directory to path
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from config import init_app as init_config
|
|
from database import db, init_db
|
|
from auth_models import User, bcrypt
|
|
from auth import create_user
|
|
|
|
def create_admin_user():
|
|
"""Create the default admin user"""
|
|
# Skip if running non-interactively
|
|
if not sys.stdin.isatty():
|
|
print("Running non-interactively, skipping interactive admin creation.")
|
|
return True
|
|
|
|
print("\n=== Talk2Me Admin User Setup ===\n")
|
|
|
|
# Get admin credentials
|
|
while True:
|
|
email = input("Admin email: ").strip()
|
|
if '@' in email and '.' in email:
|
|
break
|
|
print("Please enter a valid email address.")
|
|
|
|
while True:
|
|
username = input("Admin username: ").strip()
|
|
if len(username) >= 3:
|
|
break
|
|
print("Username must be at least 3 characters.")
|
|
|
|
while True:
|
|
password = getpass.getpass("Admin password (min 8 chars): ")
|
|
if len(password) >= 8:
|
|
password_confirm = getpass.getpass("Confirm password: ")
|
|
if password == password_confirm:
|
|
break
|
|
print("Passwords don't match. Try again.")
|
|
else:
|
|
print("Password must be at least 8 characters.")
|
|
|
|
full_name = input("Full name (optional): ").strip() or None
|
|
|
|
# Create admin user
|
|
print("\nCreating admin user...")
|
|
user, error = create_user(
|
|
email=email,
|
|
username=username,
|
|
password=password,
|
|
full_name=full_name,
|
|
role='admin',
|
|
is_verified=True
|
|
)
|
|
|
|
if error:
|
|
print(f"Error creating admin: {error}")
|
|
return False
|
|
|
|
# Set higher rate limits for admin
|
|
user.rate_limit_per_minute = 300
|
|
user.rate_limit_per_hour = 5000
|
|
user.rate_limit_per_day = 50000
|
|
|
|
# Add all permissions
|
|
user.permissions = ['all']
|
|
|
|
db.session.commit()
|
|
|
|
print(f"\n✅ Admin user created successfully!")
|
|
print(f" Email: {user.email}")
|
|
print(f" Username: {user.username}")
|
|
print(f" API Key: {user.api_key}")
|
|
print(f"\n📝 Save your API key securely. You can use it to authenticate API requests.")
|
|
print(f"\n🔐 Login at: http://localhost:5005/login")
|
|
print(f"📊 Admin dashboard: http://localhost:5005/admin/users")
|
|
|
|
return True
|
|
|
|
|
|
def init_database():
|
|
"""Initialize the database with all tables"""
|
|
# Create Flask app
|
|
app = Flask(__name__)
|
|
|
|
# Initialize configuration
|
|
init_config(app)
|
|
|
|
# Initialize bcrypt
|
|
bcrypt.init_app(app)
|
|
|
|
# Initialize database
|
|
init_db(app)
|
|
|
|
with app.app_context():
|
|
print("Creating database tables...")
|
|
|
|
# Import all models to ensure they're registered
|
|
from auth_models import User, LoginHistory, UserSession, RevokedToken
|
|
from database import Translation, Transcription, UserPreferences, UsageAnalytics, ApiKey
|
|
|
|
# Create all tables
|
|
db.create_all()
|
|
print("✅ Database tables created successfully!")
|
|
|
|
# Check if admin user already exists
|
|
admin_exists = User.query.filter_by(role='admin').first()
|
|
|
|
if admin_exists:
|
|
print(f"\n⚠️ Admin user already exists: {admin_exists.username}")
|
|
# Skip creating new admin if running non-interactively
|
|
if not sys.stdin.isatty():
|
|
print("Running non-interactively, skipping admin user creation.")
|
|
return
|
|
create_new = input("Create another admin user? (y/n): ").lower().strip()
|
|
if create_new != 'y':
|
|
print("\nExiting without creating new admin.")
|
|
return
|
|
|
|
# Create admin user
|
|
if not create_admin_user():
|
|
print("\n❌ Failed to create admin user.")
|
|
sys.exit(1)
|
|
|
|
print("\n✨ Authentication system initialized successfully!")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
init_database()
|
|
except KeyboardInterrupt:
|
|
print("\n\nSetup cancelled by user.")
|
|
sys.exit(0)
|
|
except Exception as e:
|
|
print(f"\n❌ Error during setup: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1) |