From 2e912729e70a15415b0dc1cb777a230bbdf73cf1 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Thu, 6 Jun 2024 14:59:36 +0200 Subject: [PATCH 1/6] Fix error for anonymous user listing jobs --- lib/galaxy/managers/jobs.py | 12 +++++++++++- lib/galaxy/webapps/galaxy/services/jobs.py | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/managers/jobs.py b/lib/galaxy/managers/jobs.py index 102d8b04f591..1ec323546b0e 100644 --- a/lib/galaxy/managers/jobs.py +++ b/lib/galaxy/managers/jobs.py @@ -37,6 +37,7 @@ Safety, ) from galaxy.managers.collections import DatasetCollectionManager +from galaxy.managers.context import ProvidesUserContext from galaxy.managers.datasets import DatasetManager from galaxy.managers.hdas import HDAManager from galaxy.managers.lddas import LDDAManager @@ -105,7 +106,9 @@ def __init__(self, app: StructuredApp): self.app = app self.dataset_manager = DatasetManager(app) - def index_query(self, trans, payload: JobIndexQueryPayload) -> sqlalchemy.engine.Result: + def index_query( + self, trans: ProvidesUserContext, payload: JobIndexQueryPayload + ) -> typing.Optional[sqlalchemy.engine.Result]: """The caller is responsible for security checks on the resulting job if history_id, invocation_id, or implicit_collection_jobs_id is set. Otherwise this will only return the user's jobs or all jobs if the requesting @@ -121,6 +124,13 @@ def index_query(self, trans, payload: JobIndexQueryPayload) -> sqlalchemy.engine search = payload.search order_by = payload.order_by + if trans.user is None: + # If the user is anonymous we can only return jobs for the current session history + if trans.galaxy_session and trans.galaxy_session.current_history_id: + history_id = trans.galaxy_session.current_history_id + else: + return None + def build_and_apply_filters(stmt, objects, filter_func): if objects is not None: if isinstance(objects, (str, date, datetime)): diff --git a/lib/galaxy/webapps/galaxy/services/jobs.py b/lib/galaxy/webapps/galaxy/services/jobs.py index 240d841a67ea..727497d12af8 100644 --- a/lib/galaxy/webapps/galaxy/services/jobs.py +++ b/lib/galaxy/webapps/galaxy/services/jobs.py @@ -81,7 +81,9 @@ def index( or payload.history_id is not None ) jobs = self.job_manager.index_query(trans, payload) - out = [] + out: List[Dict[str, Any]] = [] + if jobs is None: + return out for job in jobs.yield_per(model.YIELD_PER_ROWS): # TODO: optimize if this crucial if check_security_of_jobs and not security_check(trans, job.history, check_accessible=True): From 497ca2fc55ee739d1266aac70b7e2c0131de6258 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Thu, 6 Jun 2024 15:04:30 +0200 Subject: [PATCH 2/6] Fix mypy: now it catches this error thanks to the ProvidesUserContext type hint --- lib/galaxy/managers/jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/managers/jobs.py b/lib/galaxy/managers/jobs.py index 1ec323546b0e..8cb05b24aedb 100644 --- a/lib/galaxy/managers/jobs.py +++ b/lib/galaxy/managers/jobs.py @@ -217,7 +217,7 @@ def add_search_criteria(stmt): if user_details: stmt = stmt.outerjoin(Job.user) else: - if history_id is None and invocation_id is None and implicit_collection_jobs_id is None: + if history_id is None and invocation_id is None and implicit_collection_jobs_id is None and trans.user: stmt = stmt.where(Job.user_id == trans.user.id) # caller better check security From 7caee0b7511152937e51229c28cdb778824d122d Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Thu, 6 Jun 2024 16:03:35 +0200 Subject: [PATCH 3/6] Import from typing in preparation for more type annotations Co-authored-by: Nicola Soranzo --- lib/galaxy/managers/jobs.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/managers/jobs.py b/lib/galaxy/managers/jobs.py index 8cb05b24aedb..2b7b3d7a94e3 100644 --- a/lib/galaxy/managers/jobs.py +++ b/lib/galaxy/managers/jobs.py @@ -1,10 +1,13 @@ import json import logging -import typing from datetime import ( date, datetime, ) +from typing import ( + Dict, + Optional, +) import sqlalchemy from boltons.iterutils import remap @@ -108,7 +111,7 @@ def __init__(self, app: StructuredApp): def index_query( self, trans: ProvidesUserContext, payload: JobIndexQueryPayload - ) -> typing.Optional[sqlalchemy.engine.Result]: + ) -> Optional[sqlalchemy.engine.Result]: """The caller is responsible for security checks on the resulting job if history_id, invocation_id, or implicit_collection_jobs_id is set. Otherwise this will only return the user's jobs or all jobs if the requesting @@ -640,7 +643,7 @@ def replace_dataset_ids(path, key, value): return None -def view_show_job(trans, job: Job, full: bool) -> typing.Dict: +def view_show_job(trans, job: Job, full: bool) -> Dict: is_admin = trans.user_is_admin job_dict = job.to_dict("element", system_details=is_admin) if trans.app.config.expose_dataset_path and "command_line" not in job_dict: From dff6307e91c68550be97c802304f393091d30cb2 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Fri, 7 Jun 2024 17:26:20 +0200 Subject: [PATCH 4/6] Allow DCE as outer input to to_cwl --- lib/galaxy/workflow/modules.py | 4 ++-- test/unit/workflows/test_modules.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/workflow/modules.py b/lib/galaxy/workflow/modules.py index 79aac7f72115..882eaebde4f5 100644 --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -128,9 +128,9 @@ def to_cwl(value, hda_references, step): element_identifier = None if isinstance(value, model.HistoryDatasetCollectionAssociation): value = value.collection - if isinstance(value, model.DatasetCollectionElement) and value.hda: + if isinstance(value, model.DatasetCollectionElement): element_identifier = value.element_identifier - value = value.hda + value = value.element_object if isinstance(value, model.HistoryDatasetAssociation): # I think the following two checks are needed but they may # not be needed. diff --git a/test/unit/workflows/test_modules.py b/test/unit/workflows/test_modules.py index 8e0df5f81624..9e2bf5c4516e 100644 --- a/test/unit/workflows/test_modules.py +++ b/test/unit/workflows/test_modules.py @@ -274,6 +274,18 @@ def test_to_cwl_nested_collection(): assert result["outer"][0]["basename"] == "inner" +def test_to_cwl_dataset_collection_element(): + hda = model.HistoryDatasetAssociation(create_dataset=True, flush=False) + hda.dataset.state = model.Dataset.states.OK + dc_inner = model.DatasetCollection(collection_type="list") + model.DatasetCollectionElement(collection=dc_inner, element_identifier="inner", element=hda) + dc_outer = model.DatasetCollection(collection_type="list:list") + dce_outer = model.DatasetCollectionElement(collection=dc_outer, element_identifier="outer", element=dc_inner) + result = modules.to_cwl(dce_outer, [], model.WorkflowStep()) + assert result[0]["class"] == "File" + assert result[0]["basename"] == "inner" + + class MapOverTestCase(NamedTuple): data_input: str step_input_def: Union[str, List[str]] From 7acf35f9a56f8142ea666450517030868638f735 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Thu, 6 Jun 2024 11:21:59 -0400 Subject: [PATCH 5/6] Fix #18316... I think. --- lib/galaxy/files/__init__.py | 11 +++++++++++ lib/galaxy/managers/file_source_instances.py | 3 +++ 2 files changed, 14 insertions(+) diff --git a/lib/galaxy/files/__init__.py b/lib/galaxy/files/__init__.py index 58aea54181be..eb3542982883 100644 --- a/lib/galaxy/files/__init__.py +++ b/lib/galaxy/files/__init__.py @@ -360,6 +360,9 @@ def user_vault(self) -> Dict[str, Any]: ... @property def app_vault(self) -> Dict[str, Any]: ... + @property + def anonymous(self) -> bool: ... + OptionalUserContext = Optional[FileSourcesUserContext] @@ -422,6 +425,10 @@ def app_vault(self): def file_sources(self): return self.trans.app.file_sources + @property + def anonymous(self) -> bool: + return self.trans.anonymous + class DictFileSourcesUserContext(FileSourcesUserContext, FileSourceDictifiable): def __init__(self, **kwd): @@ -466,3 +473,7 @@ def app_vault(self): @property def file_sources(self): return self._kwd.get("file_sources") + + @property + def anonymous(self) -> bool: + return bool(self._kwd.get("username")) diff --git a/lib/galaxy/managers/file_source_instances.py b/lib/galaxy/managers/file_source_instances.py index ba3bacde540e..e4e938a457ec 100644 --- a/lib/galaxy/managers/file_source_instances.py +++ b/lib/galaxy/managers/file_source_instances.py @@ -483,6 +483,9 @@ def user_file_sources_to_dicts( exclude_kind: Optional[Set[PluginKind]] = None, ) -> List[FilesSourceProperties]: """Write out user file sources as list of config dictionaries.""" + if user_context.anonymous: + return [] + as_dicts = [] for files_source_properties in self._all_user_file_source_properties(user_context): plugin_kind = PluginKind.rfs From 189184e2aecbf52ae99a178fccd985e38ea30fe4 Mon Sep 17 00:00:00 2001 From: John Davis Date: Fri, 7 Jun 2024 17:03:50 -0400 Subject: [PATCH 6/6] Fix mypy error (surfaced after merge) --- lib/galaxy/managers/jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/managers/jobs.py b/lib/galaxy/managers/jobs.py index ac14b9949612..cd91861a7408 100644 --- a/lib/galaxy/managers/jobs.py +++ b/lib/galaxy/managers/jobs.py @@ -110,7 +110,7 @@ def __init__(self, app: StructuredApp): def index_query( self, trans: ProvidesUserContext, payload: JobIndexQueryPayload - ) -> Optional[sqlalchemy.engine.Result]: + ) -> Optional[sqlalchemy.engine.ScalarResult]: """The caller is responsible for security checks on the resulting job if history_id, invocation_id, or implicit_collection_jobs_id is set. Otherwise this will only return the user's jobs or all jobs if the requesting