auth via DB
This commit is contained in:
+22
-6
@@ -1,8 +1,9 @@
|
||||
import html
|
||||
|
||||
from fastapi import APIRouter, Form
|
||||
from fastapi import APIRouter, Depends, Form, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
from ..auth import require_user
|
||||
from ..config import (
|
||||
DEFAULT_APPFACTORY_HOST,
|
||||
DEFAULT_GITEA_ORG,
|
||||
@@ -20,7 +21,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse)
|
||||
def index():
|
||||
def index(request: Request, user=Depends(require_user)):
|
||||
apps = get_apps()
|
||||
|
||||
gitea_url = read_env_value("GITEA_URL", "")
|
||||
@@ -147,11 +148,12 @@ def index():
|
||||
</table>
|
||||
</div>
|
||||
""",
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/new-app", response_class=HTMLResponse)
|
||||
def new_app_form():
|
||||
def new_app_form(request: Request, user=Depends(require_user)):
|
||||
return page(
|
||||
"Nová aplikace",
|
||||
"""
|
||||
@@ -183,11 +185,17 @@ def new_app_form():
|
||||
<p><a href="/portal">← Zpět</a></p>
|
||||
</div>
|
||||
""",
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/new-app", response_class=HTMLResponse)
|
||||
def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str = Form(...)):
|
||||
def create_app(
|
||||
app_id: str = Form(...),
|
||||
app_name: str = Form(...),
|
||||
template: str = Form(...),
|
||||
user=Depends(require_user),
|
||||
):
|
||||
if template != "python-fastapi":
|
||||
return HTMLResponse("Nepodporovaná šablona", status_code=400)
|
||||
|
||||
@@ -207,11 +215,12 @@ def create_app(app_id: str = Form(...), app_name: str = Form(...), template: str
|
||||
],
|
||||
extra_link=f"/apps/{html.escape(app_id)}/docs",
|
||||
extra_label="Otevřít Swagger",
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/delete-app", response_class=HTMLResponse)
|
||||
def delete_app(app_id: str = Form(...)):
|
||||
def delete_app(app_id: str = Form(...), user=Depends(require_user)):
|
||||
result = run_command([DELETE_APP_SCRIPT, app_id])
|
||||
status = "OK" if result.returncode == 0 else "FAILED"
|
||||
|
||||
@@ -219,11 +228,17 @@ def delete_app(app_id: str = Form(...)):
|
||||
title=f"Smazání aplikace: {status}",
|
||||
back_url="/portal",
|
||||
sections=[("Výstup", result.stdout), ("Chyba", result.stderr)],
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/update-resources", response_class=HTMLResponse)
|
||||
def update_resources(app_id: str = Form(...), memory: str = Form(""), cpus: str = Form("")):
|
||||
def update_resources(
|
||||
app_id: str = Form(...),
|
||||
memory: str = Form(""),
|
||||
cpus: str = Form(""),
|
||||
user=Depends(require_user),
|
||||
):
|
||||
memory = memory.strip()
|
||||
cpus = cpus.strip()
|
||||
|
||||
@@ -250,4 +265,5 @@ def update_resources(app_id: str = Form(...), memory: str = Form(""), cpus: str
|
||||
("Výstup nasazení", deploy_result.stdout),
|
||||
("Chyba nasazení", deploy_result.stderr),
|
||||
],
|
||||
user=user,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import html
|
||||
|
||||
from fastapi import APIRouter, Form, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from app.auth import authenticate_user, current_user
|
||||
from app.templates.layout import page
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/login", response_class=HTMLResponse)
|
||||
def login_form(request: Request):
|
||||
if current_user(request):
|
||||
return RedirectResponse(url="/portal", status_code=303)
|
||||
|
||||
return _render_login()
|
||||
|
||||
|
||||
@router.post("/login", response_class=HTMLResponse)
|
||||
def login(request: Request, username: str = Form(...), password: str = Form(...)):
|
||||
user = authenticate_user(username, password)
|
||||
|
||||
if not user:
|
||||
return _render_login("Neplatné přihlašovací údaje.")
|
||||
|
||||
request.session.clear()
|
||||
request.session["user_id"] = user["id"]
|
||||
|
||||
return RedirectResponse(url="/portal", status_code=303)
|
||||
|
||||
|
||||
@router.post("/logout")
|
||||
def logout(request: Request):
|
||||
request.session.clear()
|
||||
return RedirectResponse(url="/portal/login", status_code=303)
|
||||
|
||||
|
||||
def _render_login(error: str | None = None) -> str:
|
||||
error_html = ""
|
||||
if error:
|
||||
error_html = f'<p class="alert alert-danger">{html.escape(error)}</p>'
|
||||
|
||||
return page(
|
||||
"Přihlášení",
|
||||
f"""
|
||||
<div class="auth-card card">
|
||||
<h2>Přihlášení do portálu</h2>
|
||||
<p class="muted">Přihlaste se interním účtem AppFactory.</p>
|
||||
{error_html}
|
||||
|
||||
<form method="post" action="/portal/login">
|
||||
<p>
|
||||
<label>Uživatelské jméno</label><br>
|
||||
<input name="username" autocomplete="username" required autofocus>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>Heslo</label><br>
|
||||
<input type="password" name="password" autocomplete="current-password" required>
|
||||
</p>
|
||||
|
||||
<button type="submit">Přihlásit</button>
|
||||
</form>
|
||||
</div>
|
||||
""",
|
||||
)
|
||||
@@ -1,9 +1,10 @@
|
||||
import html
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Form
|
||||
from fastapi import APIRouter, Depends, Form, Request
|
||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||
|
||||
from ..auth import require_user
|
||||
from ..backups import is_backup_path, list_backups
|
||||
from ..config import BACKUP_SCRIPT
|
||||
from ..shell import run_command
|
||||
@@ -13,7 +14,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/backups", response_class=HTMLResponse)
|
||||
def backups_page():
|
||||
def backups_page(request: Request, user=Depends(require_user)):
|
||||
rows = ""
|
||||
|
||||
for path in list_backups():
|
||||
@@ -86,11 +87,12 @@ def backups_page():
|
||||
</table>
|
||||
</div>
|
||||
""",
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/backups/create", response_class=HTMLResponse)
|
||||
def create_backup():
|
||||
def create_backup(user=Depends(require_user)):
|
||||
result = run_command([BACKUP_SCRIPT])
|
||||
status = "OK" if result.returncode == 0 else "FAILED"
|
||||
|
||||
@@ -98,11 +100,12 @@ def create_backup():
|
||||
title=f"Vytvoření zálohy: {status}",
|
||||
back_url="/portal/backups",
|
||||
sections=[("Výstup", result.stdout), ("Chyba", result.stderr)],
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/backups/delete")
|
||||
def delete_backup(backup_path: str = Form(...)):
|
||||
def delete_backup(backup_path: str = Form(...), user=Depends(require_user)):
|
||||
target = Path(backup_path)
|
||||
|
||||
if not is_backup_path(target):
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import html
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
from app.auth import require_user
|
||||
from app.db.apps import get_deployment, get_deployments
|
||||
from app.templates.layout import page
|
||||
|
||||
@@ -26,7 +27,7 @@ def render_status_pill(status: str | None) -> str:
|
||||
|
||||
|
||||
@router.get("/deployments", response_class=HTMLResponse)
|
||||
async def deployments_page():
|
||||
async def deployments_page(request: Request, user=Depends(require_user)):
|
||||
deployments = get_deployments()
|
||||
|
||||
rows = ""
|
||||
@@ -85,12 +86,15 @@ async def deployments_page():
|
||||
</table>
|
||||
</div>
|
||||
""",
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/deployments/{deployment_id}", response_class=HTMLResponse)
|
||||
async def deployment_detail_page(
|
||||
deployment_id: int,
|
||||
request: Request,
|
||||
user=Depends(require_user),
|
||||
):
|
||||
deployment = get_deployment(deployment_id)
|
||||
|
||||
@@ -139,4 +143,5 @@ async def deployment_detail_page(
|
||||
<pre>{stderr}</pre>
|
||||
</div>
|
||||
""",
|
||||
user=user,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user