mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-31 02:28:09 +08:00
Fix tool output sharing when inputs come from public sources (#21802)
When a user's history is configured with private default permissions, running a tool on a dataset imported from a public library would fail with "Job attempted to create sharable output datasets in a storage location with sharing disabled". This happened because output permissions were derived solely from input datasets — public inputs produced outputs with no DATASET_ACCESS restrictions, which conflicted with the private object store. The fix ensures that the history's default DATASET_ACCESS restrictions are applied to tool outputs when the derived permissions from inputs lack them. This respects the user's privacy intent (expressed via history defaults) regardless of input origin.
This commit is contained in:
@@ -512,11 +512,19 @@ class DefaultToolAction(ToolAction):
|
||||
|
||||
if not completed_job:
|
||||
# Determine output dataset permission/roles list
|
||||
default_history_permissions = app.security_agent.history_get_default_permissions(history)
|
||||
if all_permissions:
|
||||
output_permissions = app.security_agent.guess_derived_permissions(all_permissions)
|
||||
# Ensure history default access restrictions are applied even when
|
||||
# inputs are less restrictive (e.g. public library datasets). The
|
||||
# history defaults reflect the user's intent for output privacy.
|
||||
# See https://github.com/galaxyproject/galaxy/issues/21802
|
||||
access_action = app.security_agent.get_action("access")
|
||||
if access_action in default_history_permissions and access_action not in output_permissions:
|
||||
output_permissions[access_action] = default_history_permissions[access_action]
|
||||
else:
|
||||
# No valid inputs, we will use history defaults
|
||||
output_permissions = app.security_agent.history_get_default_permissions(history)
|
||||
output_permissions = default_history_permissions
|
||||
|
||||
# Add the dbkey to the incoming parameters
|
||||
incoming["dbkey"] = input_dbkey
|
||||
|
||||
@@ -95,13 +95,11 @@ class TestToolOutputFromLibraryImportWithPrivateObjectStore(BaseObjectStoreInteg
|
||||
), f"Library import should retain default store, got {copied_storage['object_store_id']}"
|
||||
|
||||
# Make the imported dataset public — simulating a dataset from a public
|
||||
# data library where datasets are accessible to all users. This is the
|
||||
# crux of the bug: the input's access permissions (public) propagate to
|
||||
# tool outputs, which then conflict with the private object store.
|
||||
# data library where datasets are accessible to all users.
|
||||
response = self.dataset_populator.make_dataset_public_raw(history_id, copied_hda["id"])
|
||||
api_asserts.assert_status_code_is_ok(response)
|
||||
|
||||
# Run a tool on the library-imported dataset — this is the scenario from the bug
|
||||
# Run a tool on the library-imported dataset
|
||||
run_response = self.dataset_populator.run_tool(
|
||||
"cat1",
|
||||
inputs={"input1": {"src": "hda", "id": copied_hda["id"]}},
|
||||
@@ -110,9 +108,6 @@ class TestToolOutputFromLibraryImportWithPrivateObjectStore(BaseObjectStoreInteg
|
||||
self.dataset_populator.wait_for_history(history_id)
|
||||
job = run_response["jobs"][0]
|
||||
job_details = self.dataset_populator.get_job_details(job["id"], full=True).json()
|
||||
# This is the core assertion — the job should succeed, not fail with
|
||||
# "Job attempted to create sharable output datasets in a storage location
|
||||
# with sharing disabled"
|
||||
assert job_details["state"] == "ok", (
|
||||
f"Tool run on library-imported dataset failed with state '{job_details['state']}'. "
|
||||
f"Expected outputs to respect history's private store preference regardless of input origin."
|
||||
|
||||
Reference in New Issue
Block a user