Initial commit

This commit is contained in:
2025-07-11 13:52:19 +00:00
commit e0c489f625
362 changed files with 27286 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
from fastapi import APIRouter, Request, Response, HTTPException, Form, Body
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from typing import Dict
import os
from modules.logger_tool import initialise_logger
from modules.database.services.admin_service import AdminService
from modules.database.services.auth_service import auth_service
router = APIRouter()
templates = Jinja2Templates(directory="templates")
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
# Initialize services
admin_service = AdminService()
async def verify_admin(request: Request) -> Dict:
"""Verify that the user is an admin and has necessary permissions"""
session = request.cookies.get("sb-access-token")
return await auth_service.verify_admin(session)
@router.get("/admin", response_class=HTMLResponse)
async def admin_root(request: Request):
"""Root admin route - redirects to login or dashboard"""
try:
admin = await verify_admin(request)
return RedirectResponse(url="/api/admin/", status_code=303)
except HTTPException:
# Check if super admin exists
has_super_admin = await auth_service.check_super_admin_exists()
if not has_super_admin:
return RedirectResponse(url="/api/admin/login?init=true", status_code=303)
return RedirectResponse(url="/api/admin/login", status_code=303)
@router.get("/admin/login", response_class=HTMLResponse)
async def login_page(
request: Request,
error: str = None,
success: str = None,
init: bool = False
):
"""Render admin login page"""
# Check if super admin exists
has_super_admin = await auth_service.check_super_admin_exists()
# If no super admin and init flag is true, show initialization form
if not has_super_admin:
expected_email = os.getenv("VITE_SUPER_ADMIN_EMAIL")
return templates.TemplateResponse(
"admin/login.html",
{
"request": request,
"error": error,
"success": success,
"init_super_admin": True,
"expected_super_admin_email": expected_email
}
)
return templates.TemplateResponse(
"admin/login.html",
{
"request": request,
"error": error,
"success": success,
"init_super_admin": False
}
)
@router.post("/admin/login")
async def login(
request: Request,
response: Response,
email: str = Form(...),
password: str = Form(...)
):
"""Handle admin login"""
try:
# Login with auth service
auth_result = await auth_service.login_admin(email, password)
# Set session cookie and redirect
response = RedirectResponse(url="/api/admin/", status_code=303)
response.set_cookie(
"sb-access-token",
auth_result["access_token"],
httponly=True,
secure=True
)
return response
except HTTPException as e:
return RedirectResponse(
url=f"/api/admin/login?error={str(e.detail)}",
status_code=303
)
except Exception as e:
logger.error(f"Login error: {str(e)}")
return RedirectResponse(
url=f"/api/admin/login?error={str(e)}",
status_code=303
)
@router.post("/admin/logout")
async def logout(response: Response):
"""Handle admin logout"""
try:
response = RedirectResponse(url="/api/admin/login", status_code=303)
response.delete_cookie("sb-access-token")
return response
except Exception as e:
logger.error(f"Logout error: {str(e)}")
raise HTTPException(status_code=500, detail="Logout failed")
@router.post("/admin/initialize-super-admin")
async def initialize_super_admin(
admin_data: Dict = Body(...),
request: Request = None
):
"""Initialize the super admin account"""
try:
# Validate required fields
required_fields = ["email", "password", "display_name"]
for field in required_fields:
if field not in admin_data:
raise HTTPException(status_code=400, detail=f"Missing required field: {field}")
# Set up super admin
admin_service = AdminService()
result = admin_service.setup_super_admin(admin_data)
return {
"status": "success",
"message": "Super admin account created successfully! Please log in with your credentials.",
"admin": result
}
except Exception as e:
logger.error(f"Error initializing super admin: {str(e)}")
raise HTTPException(status_code=500, detail=str(e))