From 661374d8d98cf0c4079c8d9421f7da009da8148b Mon Sep 17 00:00:00 2001 From: signebedi Date: Sat, 23 Mar 2024 19:20:47 -0500 Subject: [PATCH] Added: working read_all api route (#41) --- libreforms_fastapi/app/__init__.py | 49 +++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/libreforms_fastapi/app/__init__.py b/libreforms_fastapi/app/__init__.py index f556c24..3519ccf 100644 --- a/libreforms_fastapi/app/__init__.py +++ b/libreforms_fastapi/app/__init__.py @@ -514,7 +514,54 @@ async def api_form_read_one(form_name: str, document_id: str, background_tasks: # Read all forms @app.get("/api/form/read_all/{form_name}", dependencies=[Depends(api_key_auth)]) async def api_form_read_all(form_name: str, background_tasks: BackgroundTasks, request: Request, session: SessionLocal = Depends(get_db), key: str = Depends(X_API_KEY)): - pass + + if form_name not in get_form_names(): + raise HTTPException(status_code=404, detail=f"Form '{form_name}' not found") + + # Ugh, I'd like to find a more efficient way to get the user data. But alas, that + # the sqlalchemy-signing table is not optimized alongside the user model... + user = session.query(User).filter_by(api_key=key).first() + + # Here we validate the user groups permit them to see their own forms, which they + # should do as a matter of bureaucratic best practice, but might sometimes limit. + try: + user.validate_permission(form_name=form_name, required_permission="read_own") + except Exception as e: + raise HTTPException(status_code=403, detail=f"{e}") + + # Here, if the user is not able to see other user's data, then we denote the constraint. + try: + user.validate_permission(form_name=form_name, required_permission="read_all") + limit_query_to_users_own = False + except Exception as e: + limit_query_to_users_own = user.username + + documents = DocumentDatabase.get_all_documents( + form_name=form_name, + limit_users=limit_query_to_users_own + ) + + # Write this query to the TransactionLog + if config.COLLECT_USAGE_STATISTICS: + + endpoint = request.url.path + remote_addr = request.client.host + + background_tasks.add_task( + write_api_call_to_transaction_log, + api_key=key, + endpoint=endpoint, + remote_addr=remote_addr, + query_params="{}", + ) + + if not documents: + raise HTTPException(status_code=404, detail=f"Requested data could not be found") + + return { + "message": "Data successfully retrieved", + "documents": documents, + } # Update form # # *** Should we use PATCH instead of PUT? In libreForms-flask, we only pass