140 lines
4.7 KiB
Python
140 lines
4.7 KiB
Python
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("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))
|