feat: Implement auth user management API and UI for admin users

This commit introduces a new Auth User management feature, allowing admins to create, update, delete, and list users in the auth database. A dedicated API has been implemented with endpoints for managing auth users, including validation for unique email addresses. The frontend has been updated to include a Manage Users page with tabs for backend and frontend users, enhancing the user experience. Additionally, modals for creating and editing auth users have been added, along with appropriate error handling and loading states. Documentation has been updated to reflect these changes.
This commit is contained in:
tanyar09
2025-11-21 13:33:13 -05:00
parent e6c66e564e
commit 93cb4eda5b
15 changed files with 1348 additions and 188 deletions
+64
View File
@@ -0,0 +1,64 @@
#!/bin/bash
# Grant DELETE permission on auth database users table
set -e
echo "🔧 Granting DELETE permission on auth database users table..."
# Check if .env file exists
ENV_FILE=".env"
if [ ! -f "$ENV_FILE" ]; then
echo "❌ Error: .env file not found"
exit 1
fi
# Extract DATABASE_URL_AUTH from .env file
AUTH_DB_URL=$(grep "^DATABASE_URL_AUTH=" "$ENV_FILE" | cut -d '=' -f2- | tr -d '"' | tr -d "'")
if [ -z "$AUTH_DB_URL" ]; then
echo "❌ Error: DATABASE_URL_AUTH not found in .env file"
exit 1
fi
# Parse the database URL
# Format: postgresql+psycopg2://user:password@host:port/database
# or: postgresql://user:password@host:port/database
# Remove postgresql+psycopg2:// prefix if present
AUTH_DB_URL=${AUTH_DB_URL#postgresql+psycopg2://}
AUTH_DB_URL=${AUTH_DB_URL#postgresql://}
# Extract components
# Split by @ to get user:pass and host:port/db
IFS='@' read -r CREDENTIALS REST <<< "$AUTH_DB_URL"
IFS=':' read -r DB_USER DB_PASS <<< "$CREDENTIALS"
# Extract host, port, and database
IFS='/' read -r HOST_PORT DB_NAME <<< "$REST"
IFS=':' read -r DB_HOST DB_PORT <<< "$HOST_PORT"
# Set defaults
DB_PORT=${DB_PORT:-5432}
DB_HOST=${DB_HOST:-localhost}
echo "📋 Database information:"
echo " Host: $DB_HOST"
echo " Port: $DB_PORT"
echo " Database: $DB_NAME"
echo " User: $DB_USER"
echo ""
# Grant DELETE permission using psql as postgres superuser
echo "🔐 Granting DELETE permission (requires sudo)..."
sudo -u postgres psql -d "$DB_NAME" << EOF
GRANT DELETE ON TABLE users TO "$DB_USER";
\q
EOF
if [ $? -eq 0 ]; then
echo "✅ Successfully granted DELETE permission to user '$DB_USER'"
else
echo "❌ Failed to grant permission"
exit 1
fi
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""Grant DELETE permission on auth database users table.
This script grants DELETE permission to the database user specified in DATABASE_URL_AUTH.
It requires superuser access (postgres user) to grant permissions.
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
from urllib.parse import urlparse
from dotenv import load_dotenv
from sqlalchemy import create_engine, text
# Load environment variables
env_path = Path(__file__).parent.parent.parent / ".env"
load_dotenv(dotenv_path=env_path)
def parse_database_url(db_url: str) -> dict:
"""Parse database URL into components."""
# Handle postgresql+psycopg2:// format
if db_url.startswith("postgresql+psycopg2://"):
db_url = db_url.replace("postgresql+psycopg2://", "postgresql://")
parsed = urlparse(db_url)
return {
"user": parsed.username,
"password": parsed.password,
"host": parsed.hostname or "localhost",
"port": parsed.port or 5432,
"database": parsed.path.lstrip("/"),
}
def grant_delete_permission() -> None:
"""Grant DELETE permission on users table in auth database."""
auth_db_url = os.getenv("DATABASE_URL_AUTH")
if not auth_db_url:
print("❌ Error: DATABASE_URL_AUTH environment variable not set")
sys.exit(1)
if not auth_db_url.startswith("postgresql"):
print("ℹ️ Auth database is not PostgreSQL. No permissions to grant.")
return
db_info = parse_database_url(auth_db_url)
db_user = db_info["user"]
db_name = db_info["database"]
print(f"📋 Granting DELETE permission on users table...")
print(f" Database: {db_name}")
print(f" User: {db_user}")
# Connect as postgres superuser to grant permissions
# Try to connect as postgres user (superuser)
try:
# Try to get postgres password from environment or use peer authentication
postgres_url = f"postgresql://postgres@{db_info['host']}:{db_info['port']}/{db_name}"
engine = create_engine(postgres_url)
with engine.connect() as conn:
# Grant DELETE permission
conn.execute(text(f"""
GRANT DELETE ON TABLE users TO {db_user}
"""))
conn.commit()
print(f"✅ Successfully granted DELETE permission to user '{db_user}'")
return
except Exception as e:
# If connecting as postgres fails, try with the same user (might have grant privileges)
print(f"⚠️ Could not connect as postgres user: {e}")
print(f" Trying with current database user...")
try:
engine = create_engine(auth_db_url)
with engine.connect() as conn:
# Try to grant permission
conn.execute(text(f"""
GRANT DELETE ON TABLE users TO {db_user}
"""))
conn.commit()
print(f"✅ Successfully granted DELETE permission to user '{db_user}'")
return
except Exception as e2:
print(f"❌ Failed to grant permission: {e2}")
print(f"\n💡 To grant permission manually, run as postgres superuser:")
print(f" sudo -u postgres psql -d {db_name} -c \"GRANT DELETE ON TABLE users TO {db_user};\"")
sys.exit(1)
if __name__ == "__main__":
grant_delete_permission()
-15
View File
@@ -21,21 +21,6 @@ def recreate_tables():
Base.metadata.create_all(bind=engine)
print("✅ All tables created successfully!")
# Stamp Alembic to latest migration
print("\nMarking database as up-to-date with migrations...")
from alembic.config import Config
from alembic import command
from alembic.script import ScriptDirectory
alembic_cfg = Config("alembic.ini")
script = ScriptDirectory.from_config(alembic_cfg)
# Get the latest revision
head = script.get_current_head()
print(f"Stamping database to revision: {head}")
command.stamp(alembic_cfg, head)
print("✅ Database is now fresh and ready to use!")
+1
View File
@@ -59,3 +59,4 @@ echo "3. Run your application - it will connect to PostgreSQL automatically"