From 0b68e32b6ce0bf51b121a9199a97edf76e469a0a Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 25 Aug 2026 12:00:37 -0500 Subject: [PATCH 1/2] GitHub Issue #1462: QCStateAction to check for AssayReadPermission for run container --- .../src/org/labkey/assay/AssayController.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/assay/src/org/labkey/assay/AssayController.java b/assay/src/org/labkey/assay/AssayController.java index 18fc7e38194..2c5439fd5b3 100644 --- a/assay/src/org/labkey/assay/AssayController.java +++ b/assay/src/org/labkey/assay/AssayController.java @@ -1443,6 +1443,18 @@ public ModelAndView getView(UpdateQCStateForm form, BindException errors) throws if (form.getRuns() != null && !form.getRuns().isEmpty()) { + // GitHub Issue #1462: check permission in each run's own container + List runs = new ArrayList<>(); + for (Long runId : form.getRuns()) + { + ExpRun run = ExperimentService.get().getExpRun(runId); + if (run == null) + throw new NotFoundException("Run " + runId + " not found."); + if (!run.getContainer().hasPermission(getUser(), AssayReadPermission.class)) + throw new UnauthorizedException("User does not have " + AssayReadPermission.class.getSimpleName() + " for run " + runId); + runs.add(run); + } + if (getContainer().hasPermission(getUser(), QCAnalystPermission.class)) { JspView jspView = new JspView<>("/org/labkey/assay/view/updateQCState.jsp", form, errors); @@ -1450,13 +1462,13 @@ public ModelAndView getView(UpdateQCStateForm form, BindException errors) throws view.addView(jspView); } - if (form.getRuns().size() == 1) + if (runs.size() == 1) { - // construct the audit log query view + // construct the audit log query view. Note: ensureCanSeeAuditLogRole grants the role in every container User user = ElevatedUser.ensureCanSeeAuditLogRole(getContainer(), getUser()); UserSchema schema = AuditLogService.getAuditLogSchema(user, getContainer()); - ExpRun run = ExperimentService.get().getExpRun(form.getRuns().stream().findFirst().get()); - if (run != null && schema != null) + ExpRun run = runs.getFirst(); + if (schema != null) { QuerySettings settings = new QuerySettings(getViewContext(), "auditHistory"); SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("RunLsid"), run.getLSID()); From 949b959121f7a84b07861bef21832bf2cbb1e545 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 25 Aug 2026 13:35:27 -0500 Subject: [PATCH 2/2] claude CR feedback --- assay/src/org/labkey/assay/AssayController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assay/src/org/labkey/assay/AssayController.java b/assay/src/org/labkey/assay/AssayController.java index 2c5439fd5b3..57609dd23b3 100644 --- a/assay/src/org/labkey/assay/AssayController.java +++ b/assay/src/org/labkey/assay/AssayController.java @@ -1448,10 +1448,8 @@ public ModelAndView getView(UpdateQCStateForm form, BindException errors) throws for (Long runId : form.getRuns()) { ExpRun run = ExperimentService.get().getExpRun(runId); - if (run == null) + if (run == null || !run.getContainer().hasPermission(getUser(), AssayReadPermission.class)) throw new NotFoundException("Run " + runId + " not found."); - if (!run.getContainer().hasPermission(getUser(), AssayReadPermission.class)) - throw new UnauthorizedException("User does not have " + AssayReadPermission.class.getSimpleName() + " for run " + runId); runs.add(run); }