From dc1c10f44b8c3f22386acc63e614b239e9849830 Mon Sep 17 00:00:00 2001 From: HotSwapp <47397945+HotSwapp@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:07:04 -0500 Subject: [PATCH] feat: Add delete button for uploaded CSV files in admin panel - Added delete button (trash icon) next to each uploaded file in the import section - Implemented DELETE endpoint at /admin/delete-file/{filename} with authentication and validation - Added JavaScript function to handle file deletion with confirmation dialog - Includes security checks for directory traversal and file existence - Logs file deletion actions with username for audit trail - UI automatically refreshes after successful deletion --- app/main.py | 55 ++++++++++++++++++++++++++++++++++++++++ app/templates/admin.html | 38 ++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index ddd8af9..c2baa4a 100644 --- a/app/main.py +++ b/app/main.py @@ -1803,6 +1803,61 @@ async def admin_sync_data( }) +@app.delete("/admin/delete-file/{filename}") +async def admin_delete_file( + request: Request, + filename: str, + db: Session = Depends(get_db) +): + """ + Delete an uploaded CSV file from the data-import directory. + + Requires authentication and validates that the file exists. + """ + # Check authentication + user = get_current_user_from_session(request.session) + if not user: + raise HTTPException(status_code=401, detail="Unauthorized") + + # Validate filename to prevent directory traversal + if ".." in filename or "/" in filename or "\\" in filename: + raise HTTPException(status_code=400, detail="Invalid filename") + + # Construct file path + import_dir = "data-import" + file_path = os.path.join(import_dir, filename) + + # Check if file exists + if not os.path.exists(file_path): + raise HTTPException(status_code=404, detail="File not found") + + # Check if it's actually a file (not a directory) + if not os.path.isfile(file_path): + raise HTTPException(status_code=400, detail="Not a file") + + try: + # Delete the file + os.remove(file_path) + + # Log the deletion + logger.info( + "admin_delete_file", + filename=filename, + username=user.username, + ) + + return {"success": True, "message": f"File '{filename}' deleted successfully"} + + except Exception as e: + logger.error( + "admin_delete_file_error", + filename=filename, + username=user.username, + error=str(e) + ) + raise HTTPException(status_code=500, detail=f"Error deleting file: {str(e)}") + + @app.get("/admin") async def admin_panel(request: Request, db: Session = Depends(get_db)): """ diff --git a/app/templates/admin.html b/app/templates/admin.html index 37aeb4f..62d5f0f 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -475,13 +475,18 @@
{% for file in files %}