admin / Synapse-Cortex
publicSelf Hosted ITSM Tool with RBAC/Tenanting and MFA
Synapse-Cortex / synapse-cortex / app / routers / setup.py
2766 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | from fastapi import APIRouter, Depends, Form, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from .. import models from ..database import get_db from ..paths import TEMPLATES_DIR from ..security import hash_password router = APIRouter() templates = Jinja2Templates(directory=str(TEMPLATES_DIR)) # Sensible out-of-the-box SLA targets, seeded per-priority for every new tenant. # (response_minutes, resolution_minutes) DEFAULT_SLA_MATRIX = { models.TicketPriority.CRITICAL: (15, 240), models.TicketPriority.HIGH: (30, 480), models.TicketPriority.MEDIUM: (60, 1440), models.TicketPriority.LOW: (120, 4320), } def _admin_exists(db: Session) -> bool: return ( db.query(models.User).filter(models.User.role == models.UserRole.GLOBAL_ADMIN).first() is not None ) @router.get("/setup", response_class=HTMLResponse) def setup_form(request: Request, db: Session = Depends(get_db)): if _admin_exists(db): return RedirectResponse("/login", status_code=303) return templates.TemplateResponse("setup.html", {"request": request, "error": None}) @router.post("/setup") def setup_submit( request: Request, db: Session = Depends(get_db), tenant_name: str = Form(...), admin_full_name: str = Form(...), admin_email: str = Form(...), admin_password: str = Form(...), ): if _admin_exists(db): return RedirectResponse("/login", status_code=303) if len(admin_password) < 8: return templates.TemplateResponse( "setup.html", {"request": request, "error": "Password must be at least 8 characters."}, status_code=400, ) slug = tenant_name.strip().lower().replace(" ", "-") tenant = models.Tenant(name=tenant_name.strip(), slug=slug) db.add(tenant) db.flush() for priority, (response_minutes, resolution_minutes) in DEFAULT_SLA_MATRIX.items(): db.add( models.SLAPolicy( tenant_id=tenant.id, priority=priority, response_time_minutes=response_minutes, resolution_time_minutes=resolution_minutes, ) ) for type_name in models.DEFAULT_ASSET_TYPE_NAMES: db.add(models.AssetTypeOption(tenant_id=tenant.id, name=type_name)) admin = models.User( tenant_id=tenant.id, email=admin_email.strip().lower(), full_name=admin_full_name.strip(), hashed_password=hash_password(admin_password), role=models.UserRole.GLOBAL_ADMIN, ) db.add(admin) db.commit() request.session["user_id"] = str(admin.id) return RedirectResponse("/", status_code=303) |