From 9207f1e8d9de5237f30f70be67df99130fd35225 Mon Sep 17 00:00:00 2001 From: Lum Date: Thu, 11 Jun 2026 16:32:53 -0700 Subject: [PATCH 1/4] Container scoping for NAb including automation --- .../api/assay/nab/view/GraphSelectedAction.java | 9 +++++++++ .../labkey/api/assay/nab/view/MultiGraphAction.java | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/assay/api-src/org/labkey/api/assay/nab/view/GraphSelectedAction.java b/assay/api-src/org/labkey/api/assay/nab/view/GraphSelectedAction.java index 2db8d7c6c69..4c5e9a033e2 100644 --- a/assay/api-src/org/labkey/api/assay/nab/view/GraphSelectedAction.java +++ b/assay/api-src/org/labkey/api/assay/nab/view/GraphSelectedAction.java @@ -71,6 +71,8 @@ public ModelAndView getView(FormType form, BindException errors) throws Exceptio objectIds[idx++] = Integer.parseInt(objectIdString); } + // GitHub Issue #1892: (NAB-9) The object ids come straight from the request and getDilutionSummaries() resolves them to runs + verifyObjectIdsReadable(objectIds); Set cutoffSet = new HashSet<>(); DilutionAssayProvider provider = (DilutionAssayProvider) AssayService.get().getProvider(_protocol); Map summaries = provider.getDataHandler().getDilutionSummaries(getUser(), form.getFitTypeEnum(), objectIds); @@ -92,6 +94,13 @@ public ModelAndView getView(FormType form, BindException errors) throws Exceptio return new VBox(new AssayHeaderView(_protocol, provider, false, true, null), multiGraphView); } + /** + * Verify that the current user may view each of the requested object ids before any run data is loaded. + */ + protected void verifyObjectIdsReadable(int[] ids) throws Exception + { + } + protected abstract GraphSelectedBean createSelectionBean(ViewContext context, ExpProtocol protocol, int[] cutoffs, int[] dataObjectIds, String caption, String title); diff --git a/assay/api-src/org/labkey/api/assay/nab/view/MultiGraphAction.java b/assay/api-src/org/labkey/api/assay/nab/view/MultiGraphAction.java index 09924804c8c..ef6bbb09afc 100644 --- a/assay/api-src/org/labkey/api/assay/nab/view/MultiGraphAction.java +++ b/assay/api-src/org/labkey/api/assay/nab/view/MultiGraphAction.java @@ -16,13 +16,13 @@ package org.labkey.api.assay.nab.view; import org.labkey.api.action.SimpleViewAction; +import org.labkey.api.assay.AssayService; import org.labkey.api.assay.dilution.DilutionAssayProvider; import org.labkey.api.assay.dilution.DilutionAssayRun; import org.labkey.api.assay.dilution.DilutionSummary; import org.labkey.api.assay.nab.NabGraph; import org.labkey.api.exp.api.ExpProtocol; import org.labkey.api.exp.api.ExperimentService; -import org.labkey.api.assay.AssayService; import org.labkey.api.view.NavTree; import org.springframework.validation.BindException; import org.springframework.web.servlet.ModelAndView; @@ -35,12 +35,13 @@ * User: klum * Date: 6/11/13 */ -public class MultiGraphAction extends SimpleViewAction +public abstract class MultiGraphAction extends SimpleViewAction { @Override public ModelAndView getView(FormType form, BindException errors) throws Exception { int[] ids = form.getId(); + verifyObjectIdsReadable(ids); ExpProtocol protocol = ExperimentService.get().getExpProtocol(form.getProtocolId()); DilutionAssayProvider provider = (DilutionAssayProvider)AssayService.get().getProvider(protocol); Map summaries = provider.getDataHandler().getDilutionSummaries(getUser(), form.getFitTypeEnum(), ids); @@ -63,6 +64,13 @@ public ModelAndView getView(FormType form, BindException errors) throws Exceptio return null; } + /** + * Verify that the current user may view each of the requested object ids before any run data is loaded. + */ + protected void verifyObjectIdsReadable(int[] ids) throws Exception + { + } + protected NabGraph.Config getGraphConfig(FormType form) { NabGraph.Config config = new NabGraph.Config(); From 2e7d409ac94aa600cbe154b22ac9a3bb7d3e8703 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Fri, 12 Jun 2026 10:45:37 -0700 Subject: [PATCH 2/4] MockRequest: support getParameter() --- api/src/org/labkey/api/view/ViewServlet.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/src/org/labkey/api/view/ViewServlet.java b/api/src/org/labkey/api/view/ViewServlet.java index 2f446760067..48273010c3b 100644 --- a/api/src/org/labkey/api/view/ViewServlet.java +++ b/api/src/org/labkey/api/view/ViewServlet.java @@ -506,6 +506,12 @@ public void setActionURL(ActionURL actionURL) return _actionURL.getParameterMap(); } + @Override + public String getParameter(@NotNull String name) + { + return _actionURL.getParameter(name); + } + @Override public @NotNull String @NotNull [] getParameterValues(@NotNull String name) { From d3331f55e64bec8bc5ca0675cb37d9d8fdd69adf Mon Sep 17 00:00:00 2001 From: cnathe Date: Fri, 12 Jun 2026 13:26:30 -0500 Subject: [PATCH 3/4] ExperimentService getExpData() helper with container check --- .../org/labkey/api/exp/api/ExperimentService.java | 3 +++ .../experiment/api/ExperimentServiceImpl.java | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/api/src/org/labkey/api/exp/api/ExperimentService.java b/api/src/org/labkey/api/exp/api/ExperimentService.java index eb195043dee..b744dcbf3ca 100644 --- a/api/src/org/labkey/api/exp/api/ExperimentService.java +++ b/api/src/org/labkey/api/exp/api/ExperimentService.java @@ -163,6 +163,9 @@ enum DataTypeForExclusion @Nullable ExpRun getExpRun(int rowId); + @Nullable + ExpRun getExpRun(int rowId, @Nullable Container container); + List getExpRuns(Collection rowIds); @Nullable diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index fe53e505d8f..2ee92e64f89 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -374,10 +374,23 @@ public void clearDataClassCache(@Nullable Container c) @Override public @Nullable ExpRunImpl getExpRun(int rowId) + { + return getExpRun(rowId, null); + } + + @Override + public @Nullable ExpRunImpl getExpRun(int rowId, @Nullable Container container) { SimpleFilter filter = new SimpleFilter(FieldKey.fromParts(ExpRunTable.Column.RowId.name()), rowId); ExperimentRun run = new TableSelector(getTinfoExperimentRun(), filter, null).getObject(ExperimentRun.class); - return run == null ? null : new ExpRunImpl(run); + if (run == null) + return null; + + // GitHub Kanban #1892: if container provided, ensure the run belongs to the container + if (container != null && !run.getContainer().equals(container)) + return null; + + return new ExpRunImpl(run); } private List getExpRuns(SimpleFilter filter) From f7ecfdc3f0ab24336e7d305667363dbdcbcd6a60 Mon Sep 17 00:00:00 2001 From: cnathe Date: Fri, 12 Jun 2026 13:29:06 -0500 Subject: [PATCH 4/4] Nab action container scoping --- .../org/labkey/api/assay/nab/view/DilutionGraphAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assay/api-src/org/labkey/api/assay/nab/view/DilutionGraphAction.java b/assay/api-src/org/labkey/api/assay/nab/view/DilutionGraphAction.java index 43787be934c..935e8f9d70d 100644 --- a/assay/api-src/org/labkey/api/assay/nab/view/DilutionGraphAction.java +++ b/assay/api-src/org/labkey/api/assay/nab/view/DilutionGraphAction.java @@ -44,7 +44,8 @@ public ModelAndView getView(GraphForm form, BindException errors) throws Excepti { if (form.getRowId() == -1) throw new NotFoundException("Run ID not specified."); - ExpRun run = ExperimentService.get().getExpRun(form.getRowId()); + // GitHub Kanban #1892: Resolve the run scoped to the current container + ExpRun run = ExperimentService.get().getExpRun(form.getRowId(), getContainer()); if (run == null) throw new NotFoundException("Run " + form.getRowId() + " does not exist.");