mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
- Fix nav_menu translation key: 'Add Webpage(s)' -> 'Add Webpages' - Fix session persistence: sync baseApiService token on login/logout/load - Add admin user update script (scripts/update_admin_user.py) - Add Ollama memory optimization guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
142 lines
4.7 KiB
Python
142 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Utility script to update admin user password and status.
|
|
|
|
This script should be run on the VPS after deployment to:
|
|
1. Update the admin user's password
|
|
2. Ensure is_superuser, is_active, is_verified are all True
|
|
|
|
Usage:
|
|
cd /path/to/SurfSense/surfsense_backend
|
|
source venv/bin/activate # or your virtual environment
|
|
python scripts/update_admin_user.py
|
|
|
|
Note: Make sure the .env file is properly configured with DATABASE_URL
|
|
"""
|
|
|
|
import asyncio
|
|
import os
|
|
import sys
|
|
|
|
# Add the parent directory to path so we can import app modules
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
from passlib.context import CryptContext
|
|
from sqlalchemy import select, update
|
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
# Password hashing context (same as FastAPI-Users uses)
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
|
|
# Configuration
|
|
ADMIN_EMAIL = "ojars@kapteinis.lv"
|
|
NEW_PASSWORD = "^&U0yXLK1ypZOwLDGFeLT35kCrblITYyAVdVmF3!iJ%kkY1Nl^IS!P"
|
|
|
|
|
|
async def update_admin_user():
|
|
"""Update admin user password and status."""
|
|
|
|
# Get database URL from environment
|
|
database_url = os.getenv("DATABASE_URL")
|
|
if not database_url:
|
|
print("ERROR: DATABASE_URL not found in environment variables")
|
|
print("Make sure your .env file is configured correctly")
|
|
sys.exit(1)
|
|
|
|
# Convert postgres:// to postgresql+asyncpg:// if needed
|
|
if database_url.startswith("postgres://"):
|
|
database_url = database_url.replace("postgres://", "postgresql+asyncpg://", 1)
|
|
elif database_url.startswith("postgresql://"):
|
|
database_url = database_url.replace("postgresql://", "postgresql+asyncpg://", 1)
|
|
|
|
print(f"Connecting to database...")
|
|
|
|
# Create async engine
|
|
engine = create_async_engine(database_url, echo=False)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as session:
|
|
try:
|
|
# Hash the new password
|
|
hashed_password = pwd_context.hash(NEW_PASSWORD)
|
|
|
|
# Update the user
|
|
result = await session.execute(
|
|
update(UserTable)
|
|
.where(UserTable.email == ADMIN_EMAIL)
|
|
.values(
|
|
hashed_password=hashed_password,
|
|
is_superuser=True,
|
|
is_active=True,
|
|
is_verified=True
|
|
)
|
|
.returning(UserTable.id, UserTable.email)
|
|
)
|
|
|
|
updated_user = result.first()
|
|
|
|
if updated_user:
|
|
await session.commit()
|
|
print(f"\n✅ Successfully updated user: {ADMIN_EMAIL}")
|
|
print(f" - User ID: {updated_user.id}")
|
|
print(f" - Password: Updated to new value")
|
|
print(f" - is_superuser: True")
|
|
print(f" - is_active: True")
|
|
print(f" - is_verified: True")
|
|
else:
|
|
print(f"\n❌ User not found: {ADMIN_EMAIL}")
|
|
print(" Make sure the email address is correct")
|
|
|
|
# List existing users for debugging
|
|
from sqlalchemy import text
|
|
users_result = await session.execute(
|
|
text("SELECT email FROM \"user\" LIMIT 10")
|
|
)
|
|
users = users_result.fetchall()
|
|
if users:
|
|
print("\n Existing users in database:")
|
|
for user in users:
|
|
print(f" - {user[0]}")
|
|
|
|
except Exception as e:
|
|
print(f"\n❌ Error updating user: {e}")
|
|
await session.rollback()
|
|
raise
|
|
finally:
|
|
await engine.dispose()
|
|
|
|
|
|
# Import the User model after environment is loaded
|
|
# We need to do this here to ensure DATABASE_URL is available
|
|
if __name__ == "__main__":
|
|
print("=" * 50)
|
|
print("Admin User Update Script")
|
|
print("=" * 50)
|
|
print(f"\nTarget user: {ADMIN_EMAIL}")
|
|
print(f"New password: {'*' * 10} (hidden)")
|
|
print()
|
|
|
|
# Now import the User model
|
|
try:
|
|
from app.db import User as UserTable
|
|
except ImportError:
|
|
# Try alternative import if running from different directory
|
|
try:
|
|
from surfsense_backend.app.db import User as UserTable
|
|
except ImportError:
|
|
print("ERROR: Could not import User model")
|
|
print("Make sure you're running this script from the surfsense_backend directory")
|
|
sys.exit(1)
|
|
|
|
# Run the async update
|
|
asyncio.run(update_admin_user())
|
|
|
|
print("\n" + "=" * 50)
|
|
print("Done!")
|
|
print("=" * 50)
|