From 8aadf1a87a38f45f9f02f4ebd29758b566e4e3f5 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Mon, 18 Nov 2024 21:14:00 -0500 Subject: [PATCH] Ensure accessibility of job, scope get to user. (e.g. -- admins could query for shared/errored datasets, etc) --- lib/galaxy/managers/chat.py | 11 ++++++++--- lib/galaxy/webapps/galaxy/api/chat.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/galaxy/managers/chat.py b/lib/galaxy/managers/chat.py index 92851da28bdc..f3447e9aca72 100644 --- a/lib/galaxy/managers/chat.py +++ b/lib/galaxy/managers/chat.py @@ -1,7 +1,10 @@ from typing import Optional from fastapi import Path -from sqlalchemy import select +from sqlalchemy import ( + and_, + select, +) from sqlalchemy.exc import ( MultipleResultsFound, NoResultFound, @@ -66,10 +69,12 @@ def get(self, trans: ProvidesUserContext, job_id: JobIdPathParam) -> ChatExchang :raises: InconsistentDatabase, InternalServerError """ try: - stmt = select(ChatExchange).where(ChatExchange.job_id == job_id) + stmt = select(ChatExchange).where( + and_(ChatExchange.job_id == job_id, ChatExchange.user_id == trans.user.id) + ) chat_response = trans.sa_session.execute(stmt).scalar_one() except MultipleResultsFound: - # TODO: Unsure about this, isn't this more applicable when we're getting the response for response.id instead of response.job_id? + # TODO: Unsure about this, isn't this more applicable when we're getting the response for response.id instead of response. raise InconsistentDatabase("Multiple chat responses found with the same job id.") except NoResultFound: # TODO: Would there be cases where we raise an exception here? Or, is there a better way to return None? diff --git a/lib/galaxy/webapps/galaxy/api/chat.py b/lib/galaxy/webapps/galaxy/api/chat.py index 7db4e9404581..5723fbf4815c 100644 --- a/lib/galaxy/webapps/galaxy/api/chat.py +++ b/lib/galaxy/webapps/galaxy/api/chat.py @@ -11,6 +11,7 @@ JobIdPathParam, ) from galaxy.managers.context import ProvidesUserContext +from galaxy.managers.jobs import JobManager from galaxy.schema.schema import ChatPayload from galaxy.webapps.galaxy.api import ( depends, @@ -36,6 +37,7 @@ class ChatAPI: config: GalaxyAppConfiguration = depends(GalaxyAppConfiguration) chat_manager: ChatManager = depends(ChatManager) + job_manager: JobManager = depends(JobManager) @router.post("/api/chat") def query( @@ -47,8 +49,8 @@ def query( """We're off to ask the wizard""" # Currently job-based chat exchanges are the only ones supported, # and will only have the one message. - - if job_id: + job = self.job_manager.get_accessible_job(trans, job_id) + if job: # If there's an existing response for this job, just return that one for now. # TODO: Support regenerating the response as a new message, and # asking follow-up questions. @@ -62,8 +64,8 @@ def query( response = self._call_openai(messages) answer = response.choices[0].message.content - if job_id: - self.chat_manager.create(trans, job_id, answer) + if job: + self.chat_manager.create(trans, job.id, answer) return answer @@ -75,7 +77,8 @@ def feedback( trans: ProvidesUserContext = DependsOnTrans, ) -> int | None: """Provide feedback on the chatbot response.""" - chat_response = self.chat_manager.set_feedback_for_job(trans, job_id, feedback) + job = self.job_manager.get_accessible_job(trans, job_id) + chat_response = self.chat_manager.set_feedback_for_job(trans, job.id, feedback) return chat_response.messages[0].feedback def _ensure_openai_configured(self):