Admin user creation moved to scripts
This commit is contained in:
@@ -31,32 +31,6 @@ async def lifespan(app: FastAPI):
|
|||||||
# === STARTUP ===
|
# === STARTUP ===
|
||||||
app_logger = setup_logging()
|
app_logger = setup_logging()
|
||||||
app_logger.info("Starting up ecommerce API")
|
app_logger.info("Starting up ecommerce API")
|
||||||
|
|
||||||
# === REMOVED: Database table creation ===
|
|
||||||
# Base.metadata.create_all(bind=engine) # Removed - handled by Alembic
|
|
||||||
# create_indexes() # Removed - handled by Alembic
|
|
||||||
|
|
||||||
# === KEPT: Application-level initialization ===
|
|
||||||
|
|
||||||
# Create default admin user (after migrations have run)
|
|
||||||
db = SessionLocal()
|
|
||||||
try:
|
|
||||||
auth_manager.create_default_admin_user(db)
|
|
||||||
logger.info("Default admin user initialization completed")
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to create default admin user: {e}")
|
|
||||||
# In development, this might fail if tables don't exist yet
|
|
||||||
# That's OK - migrations should be run separately
|
|
||||||
finally:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
# Add any other application-level initialization here
|
|
||||||
# Examples:
|
|
||||||
# - Load configuration
|
|
||||||
# - Initialize caches
|
|
||||||
# - Set up external service connections
|
|
||||||
# - Load initial data (AFTER migrations)
|
|
||||||
|
|
||||||
logger.info("[OK] Application startup completed")
|
logger.info("[OK] Application startup completed")
|
||||||
|
|
||||||
yield
|
yield
|
||||||
@@ -66,13 +40,6 @@ async def lifespan(app: FastAPI):
|
|||||||
# Add cleanup tasks here if needed
|
# Add cleanup tasks here if needed
|
||||||
|
|
||||||
|
|
||||||
# === REMOVED FUNCTION ===
|
|
||||||
# def create_indexes():
|
|
||||||
# """Create database indexes."""
|
|
||||||
# # This is now handled by Alembic migrations
|
|
||||||
# pass
|
|
||||||
|
|
||||||
|
|
||||||
# === NEW HELPER FUNCTION ===
|
# === NEW HELPER FUNCTION ===
|
||||||
def check_database_ready():
|
def check_database_ready():
|
||||||
"""Check if database is ready (migrations have been run)."""
|
"""Check if database is ready (migrations have been run)."""
|
||||||
|
|||||||
167
scripts/create_admin.py
Normal file
167
scripts/create_admin.py
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Create default admin user for the platform.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python scripts/create_admin.py
|
||||||
|
|
||||||
|
This script:
|
||||||
|
- Creates a default admin user if one doesn't exist
|
||||||
|
- Can be run multiple times safely (idempotent)
|
||||||
|
- Should be run AFTER database migrations
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Add project root to path
|
||||||
|
project_root = Path(__file__).parent.parent
|
||||||
|
sys.path.insert(0, str(project_root))
|
||||||
|
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
|
from app.core.database import SessionLocal, engine
|
||||||
|
from models.database.user import User
|
||||||
|
from middleware.auth import AuthManager
|
||||||
|
|
||||||
|
# Default admin credentials
|
||||||
|
DEFAULT_ADMIN_EMAIL = "admin@platform.com"
|
||||||
|
DEFAULT_ADMIN_USERNAME = "admin"
|
||||||
|
DEFAULT_ADMIN_PASSWORD = "admin123" # Change this in production!
|
||||||
|
|
||||||
|
|
||||||
|
def create_admin_user(db: Session) -> bool:
|
||||||
|
"""
|
||||||
|
Create default admin user if it doesn't exist.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db: Database session
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if user was created, False if already exists
|
||||||
|
"""
|
||||||
|
auth_manager = AuthManager()
|
||||||
|
|
||||||
|
# Check if admin user already exists
|
||||||
|
existing_admin = db.execute(
|
||||||
|
select(User).where(User.username == DEFAULT_ADMIN_USERNAME)
|
||||||
|
).scalar_one_or_none()
|
||||||
|
|
||||||
|
if existing_admin:
|
||||||
|
print(f"ℹ️ Admin user '{DEFAULT_ADMIN_USERNAME}' already exists")
|
||||||
|
print(f" Email: {existing_admin.email}")
|
||||||
|
print(f" Role: {existing_admin.role}")
|
||||||
|
print(f" Active: {existing_admin.is_active}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Create new admin user
|
||||||
|
print(f"📝 Creating admin user...")
|
||||||
|
|
||||||
|
admin_user = User(
|
||||||
|
email=DEFAULT_ADMIN_EMAIL,
|
||||||
|
username=DEFAULT_ADMIN_USERNAME,
|
||||||
|
hashed_password=auth_manager.hash_password(DEFAULT_ADMIN_PASSWORD),
|
||||||
|
role="admin",
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(admin_user)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(admin_user)
|
||||||
|
|
||||||
|
print("\n✅ Admin user created successfully!")
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print(" Admin Credentials:")
|
||||||
|
print("=" * 50)
|
||||||
|
print(f" Email: {DEFAULT_ADMIN_EMAIL}")
|
||||||
|
print(f" Username: {DEFAULT_ADMIN_USERNAME}")
|
||||||
|
print(f" Password: {DEFAULT_ADMIN_PASSWORD}")
|
||||||
|
print("=" * 50)
|
||||||
|
print("\n⚠️ IMPORTANT: Change the password after first login!")
|
||||||
|
print(f" Login at: http://localhost:8000/static/admin/login.html")
|
||||||
|
print()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def verify_database_ready() -> bool:
|
||||||
|
"""
|
||||||
|
Verify that database tables exist.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if database is ready, False otherwise
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Try to query the users table
|
||||||
|
with engine.connect() as conn:
|
||||||
|
from sqlalchemy import text
|
||||||
|
result = conn.execute(
|
||||||
|
text("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
|
||||||
|
)
|
||||||
|
tables = result.fetchall()
|
||||||
|
return len(tables) > 0
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error checking database: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to create admin user."""
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print(" Admin User Creation Script")
|
||||||
|
print("=" * 50 + "\n")
|
||||||
|
|
||||||
|
# Step 1: Verify database is ready
|
||||||
|
print("1️⃣ Checking database...")
|
||||||
|
|
||||||
|
if not verify_database_ready():
|
||||||
|
print("\n❌ ERROR: Database not ready!")
|
||||||
|
print("\n The 'users' table doesn't exist yet.")
|
||||||
|
print(" Please run database migrations first:")
|
||||||
|
print()
|
||||||
|
print(" alembic upgrade head")
|
||||||
|
print()
|
||||||
|
print(" Or if using make:")
|
||||||
|
print(" make migrate-up")
|
||||||
|
print()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(" ✓ Database is ready")
|
||||||
|
|
||||||
|
# Step 2: Create admin user
|
||||||
|
print("\n2️⃣ Creating admin user...")
|
||||||
|
|
||||||
|
db = SessionLocal()
|
||||||
|
try:
|
||||||
|
created = create_admin_user(db)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
print("\n🎉 Setup complete! You can now:")
|
||||||
|
print(" 1. Start the server: uvicorn main:app --reload")
|
||||||
|
print(" 2. Login at: http://localhost:8000/static/admin/login.html")
|
||||||
|
print()
|
||||||
|
else:
|
||||||
|
print("\n✓ No changes needed - admin user already exists")
|
||||||
|
print()
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ ERROR: Failed to create admin user")
|
||||||
|
print(f" {type(e).__name__}: {e}")
|
||||||
|
print()
|
||||||
|
print(" Common issues:")
|
||||||
|
print(" - Database migrations not run")
|
||||||
|
print(" - Database connection issues")
|
||||||
|
print(" - Permissions problems")
|
||||||
|
print()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user