150 lines
4.6 KiB
Python
150 lines
4.6 KiB
Python
from fastapi import APIRouter, Depends, status
|
|
from fastapi.responses import FileResponse
|
|
from sqlalchemy.orm import Session
|
|
from starlette.requests import Request
|
|
|
|
from app.core.rbac import require_permission
|
|
from app.db.database import get_db
|
|
from app.models.user import User
|
|
from app.schemas.api_response import ApiSuccess
|
|
from app.schemas.backup import BackupRestoreRequest
|
|
from app.services.audit_service import write_audit_log
|
|
from app.services.backup_service import BackupService
|
|
|
|
router = APIRouter(prefix="/backups", tags=["Backups"])
|
|
|
|
|
|
@router.get("", response_model=ApiSuccess)
|
|
def list_backups(
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.read")),
|
|
):
|
|
return ApiSuccess(data=BackupService.list_backups(), message="Backups geladen")
|
|
|
|
|
|
@router.post("/create", response_model=ApiSuccess, status_code=status.HTTP_201_CREATED)
|
|
def create_backup(
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.create")),
|
|
):
|
|
backup = BackupService.create_backup(actor=current_user)
|
|
write_audit_log(
|
|
db,
|
|
action="backups.create",
|
|
entity_type="backup",
|
|
entity_label=backup.filename,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={
|
|
"filename": backup.filename,
|
|
"size_bytes": backup.size_bytes,
|
|
"app_version": backup.app_version,
|
|
},
|
|
)
|
|
return ApiSuccess(data=backup, message="Backup erstellt")
|
|
|
|
|
|
@router.get("/{filename}/download")
|
|
def download_backup(
|
|
filename: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.download")),
|
|
):
|
|
path = BackupService.resolve_backup_path(filename)
|
|
write_audit_log(
|
|
db,
|
|
action="backups.download",
|
|
entity_type="backup",
|
|
entity_label=path.name,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": path.name, "size_bytes": path.stat().st_size},
|
|
)
|
|
return FileResponse(path=path, media_type="application/zip", filename=path.name)
|
|
|
|
|
|
@router.delete("/{filename}", response_model=ApiSuccess)
|
|
def delete_backup(
|
|
filename: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.delete")),
|
|
):
|
|
path = BackupService.resolve_backup_path(filename)
|
|
size_bytes = path.stat().st_size
|
|
BackupService.delete_backup(filename)
|
|
write_audit_log(
|
|
db,
|
|
action="backups.delete",
|
|
entity_type="backup",
|
|
entity_label=path.name,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": path.name, "size_bytes": size_bytes},
|
|
)
|
|
return ApiSuccess(message="Backup geloescht")
|
|
|
|
|
|
@router.post("/{filename}/restore/validate", response_model=ApiSuccess)
|
|
def validate_backup_restore(
|
|
filename: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.restore")),
|
|
):
|
|
validation = BackupService.validate_backup(filename)
|
|
write_audit_log(
|
|
db,
|
|
action="backups.validate",
|
|
entity_type="backup",
|
|
entity_label=filename,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": filename, "valid": validation.valid, "issues": validation.issues},
|
|
)
|
|
return ApiSuccess(data=validation, message=validation.message)
|
|
|
|
|
|
@router.post("/{filename}/restore", response_model=ApiSuccess)
|
|
def restore_backup(
|
|
filename: str,
|
|
payload: BackupRestoreRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_permission("backup.restore")),
|
|
):
|
|
write_audit_log(
|
|
db,
|
|
action="backups.restore_started",
|
|
entity_type="backup",
|
|
entity_label=filename,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": filename},
|
|
)
|
|
try:
|
|
validation = BackupService.restore_backup(filename, confirm_text=payload.confirm_text)
|
|
except Exception:
|
|
write_audit_log(
|
|
db,
|
|
action="backups.restore_failed",
|
|
entity_type="backup",
|
|
entity_label=filename,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": filename},
|
|
)
|
|
raise
|
|
|
|
write_audit_log(
|
|
db,
|
|
action="backups.restore_completed",
|
|
entity_type="backup",
|
|
entity_label=filename,
|
|
actor=current_user,
|
|
request=request,
|
|
metadata={"filename": filename},
|
|
)
|
|
return ApiSuccess(data=validation, message="Restore abgeschlossen")
|