From dc783a87f487c3a84739eca6a021607d2c54a189 Mon Sep 17 00:00:00 2001
From: Lum
Date: Thu, 25 Jun 2026 17:01:45 -0700
Subject: [PATCH] Remove deprecated feature : R report sharing
---
api/src/org/labkey/api/query/QueryView.java | 26 ----
api/src/org/labkey/api/reports/Report.java | 7 -
.../org/labkey/api/reports/ReportService.java | 2 -
.../api/reports/report/AbstractReport.java | 9 +-
.../labkey/api/reports/report/ReportUrls.java | 1 -
.../labkey/api/reports/report/r/RReport.java | 14 --
.../report/view/ajaxScriptReportDesigner.jsp | 2 -
query/src/org/labkey/query/QueryModule.java | 10 --
.../query/reports/ReportsController.java | 123 ------------------
.../query/reports/view/reportDetails.jsp | 3 -
.../labkey/query/reports/view/shareReport.jsp | 94 -------------
query/webapp/reports/ScriptReportPanel.js | 13 --
.../labkey/study/view/reportPermission.jsp | 8 --
13 files changed, 1 insertion(+), 311 deletions(-)
delete mode 100644 query/src/org/labkey/query/reports/view/shareReport.jsp
diff --git a/api/src/org/labkey/api/query/QueryView.java b/api/src/org/labkey/api/query/QueryView.java
index 151110e5400..1b054a1137e 100644
--- a/api/src/org/labkey/api/query/QueryView.java
+++ b/api/src/org/labkey/api/query/QueryView.java
@@ -26,7 +26,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.action.ApiQueryResponse;
-import org.labkey.api.admin.notification.NotificationService;
import org.labkey.api.attachments.ByteArrayAttachmentFile;
import org.labkey.api.compliance.ComplianceService;
import org.labkey.api.data.AbstractTableInfo;
@@ -1132,17 +1131,6 @@ protected ActionButton createPrintButton()
return btnPrint;
}
- private ActionButton createShareButton(@NotNull ActionURL url, @Nullable String tooltip)
- {
- ActionButton shareBtn = new ActionButton(url, "Share");
- shareBtn.setActionType(ActionButton.Action.LINK);
- shareBtn.setIconCls("share");
- if (tooltip != null)
- shareBtn.setTooltip(tooltip);
-
- return shareBtn;
- }
-
/**
* Make all links rendered in columns target the specified browser window/tab
*/
@@ -2026,23 +2014,9 @@ private void renderReportView(HttpServletRequest request, HttpServletResponse re
ButtonBar bar = new ButtonBar();
populateReportButtonBar(bar);
-
- if (_report.allowShareButton(getUser(), getContainer()))
- {
- ActionURL shareUrl = PageFlowUtil.urlProvider(ReportUrls.class).urlShareReport(getContainer(), _report);
- if (shareUrl != null)
- bar.add(createShareButton(shareUrl, "Share report"));
- }
-
dr.setButtonBar(bar);
}
dr.render(ctx, request, response);
-
- // if the user is viewing a shared report, remove any notifications related to it
- NotificationService.get().removeNotifications(
- getContainer(), _report.getDescriptor().getReportId().toString(),
- Collections.singletonList(Report.SHARE_REPORT_TYPE), getUser().getUserId()
- );
}
catch (Exception e)
{
diff --git a/api/src/org/labkey/api/reports/Report.java b/api/src/org/labkey/api/reports/Report.java
index a6478027a11..c5cbd0e8da8 100644
--- a/api/src/org/labkey/api/reports/Report.java
+++ b/api/src/org/labkey/api/reports/Report.java
@@ -45,8 +45,6 @@
public interface Report extends AttachmentParent, ThumbnailProvider
{
- String SHARE_REPORT_TYPE = "Report.ShareReport";
-
Report clone();
String getType();
String getTypeDescription();
@@ -84,11 +82,6 @@ public interface Report extends AttachmentParent, ThumbnailProvider
boolean canShare(User user, Container container);
boolean canShare(User user, Container container, List errors);
- /**
- * Determine if this report type allows sharing via the shareReport action.
- */
- boolean allowShareButton(User user, Container container);
-
/**
* Determines whether the user can delete this report
*/
diff --git a/api/src/org/labkey/api/reports/ReportService.java b/api/src/org/labkey/api/reports/ReportService.java
index 3a7dc2df42a..5ffde921b02 100644
--- a/api/src/org/labkey/api/reports/ReportService.java
+++ b/api/src/org/labkey/api/reports/ReportService.java
@@ -46,8 +46,6 @@
public interface ReportService
{
- String R_REPORT_CUSTOM_SHARING = "rReportCustomSharing";
-
// this logger is to enable all report loggers in the admin ui (org.labkey.api.reports.*)
@SuppressWarnings({"UnusedDeclaration", "SSBasedInspection"})
Logger packageLogger = LogManager.getLogger(ReportService.class.getPackageName());
diff --git a/api/src/org/labkey/api/reports/report/AbstractReport.java b/api/src/org/labkey/api/reports/report/AbstractReport.java
index ae6affc91b5..b475d66cd65 100644
--- a/api/src/org/labkey/api/reports/report/AbstractReport.java
+++ b/api/src/org/labkey/api/reports/report/AbstractReport.java
@@ -20,8 +20,8 @@
import org.labkey.api.admin.FolderExportContext;
import org.labkey.api.attachments.Attachment;
import org.labkey.api.attachments.AttachmentFile;
-import org.labkey.api.attachments.AttachmentService;
import org.labkey.api.attachments.AttachmentParentType;
+import org.labkey.api.attachments.AttachmentService;
import org.labkey.api.attachments.InputStreamAttachmentFile;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerManager;
@@ -476,13 +476,6 @@ public boolean canShare(User user, Container container)
return canShare(user, container, new ArrayList<>());
}
- @Override
- public boolean allowShareButton(User user, Container container)
- {
- // See RReport, currently only allowing ShareReportAction for that report type
- return false;
- }
-
@Override
public boolean canDelete(User user, Container container)
{
diff --git a/api/src/org/labkey/api/reports/report/ReportUrls.java b/api/src/org/labkey/api/reports/report/ReportUrls.java
index 7227494e939..776385ca9e3 100644
--- a/api/src/org/labkey/api/reports/report/ReportUrls.java
+++ b/api/src/org/labkey/api/reports/report/ReportUrls.java
@@ -40,7 +40,6 @@ public interface ReportUrls extends UrlProvider
ActionURL urlReportSections(Container c);
ActionURL urlManageViews(Container c);
ActionURL urlExportCrosstab(Container c);
- ActionURL urlShareReport(Container c, Report r);
// Thumbnail or icon, depending on ImageType
ActionURL urlImage(Container c, Report r, ThumbnailService.ImageType type, @Nullable Integer revision);
ActionURL urlAttachmentReport(Container c, ActionURL returnUrl);
diff --git a/api/src/org/labkey/api/reports/report/r/RReport.java b/api/src/org/labkey/api/reports/report/r/RReport.java
index 770b3c758d9..2daa37aecd8 100644
--- a/api/src/org/labkey/api/reports/report/r/RReport.java
+++ b/api/src/org/labkey/api/reports/report/r/RReport.java
@@ -46,7 +46,6 @@
import org.labkey.api.rstudio.RStudioService;
import org.labkey.api.security.SecurityManager;
import org.labkey.api.security.User;
-import org.labkey.api.settings.OptionalFeatureService;
import org.labkey.api.thumbnail.Thumbnail;
import org.labkey.api.util.FileUtil;
import org.labkey.api.util.PageFlowUtil;
@@ -75,8 +74,6 @@
import java.util.Map;
import java.util.Set;
-import static org.labkey.api.reports.ReportService.R_REPORT_CUSTOM_SHARING;
-
public class RReport extends ExternalScriptEngineReport
{
public static final String TYPE = "ReportService.rReport";
@@ -939,17 +936,6 @@ public String getEditAreaSyntax()
return "text/x-rsrc";
}
- @Override
- public boolean allowShareButton(User user, Container container)
- {
- if (OptionalFeatureService.get().isFeatureEnabled(R_REPORT_CUSTOM_SHARING))
- {
- // allow sharing if this R report is a DB report and the user canShare
- return !getDescriptor().isModuleBased() && canShare(user, container);
- }
- return false;
- }
-
public static class TestCase extends Assert
{
@Test
diff --git a/api/src/org/labkey/api/reports/report/view/ajaxScriptReportDesigner.jsp b/api/src/org/labkey/api/reports/report/view/ajaxScriptReportDesigner.jsp
index 8683d8f326a..2ed37f750d2 100644
--- a/api/src/org/labkey/api/reports/report/view/ajaxScriptReportDesigner.jsp
+++ b/api/src/org/labkey/api/reports/report/view/ajaxScriptReportDesigner.jsp
@@ -69,7 +69,6 @@
List includedReports = bean.getIncludedReports();
String helpHtml = report.getDesignerHelpHtml();
boolean readOnly = bean.isReadOnly() || !report.canEdit(user, c);
- boolean allowShareReport = report.allowShareButton(user, c);
Mode mode = bean.getMode();
boolean sourceAndHelp = mode.showSourceAndHelp(ctx) || bean.isSourceTabVisible();
String knitrFormat = bean.getKnitrFormat() != null ? bean.getKnitrFormat() : "None";
@@ -188,7 +187,6 @@
var panel = Ext4.create('LABKEY.ext4.ScriptReportPanel', {
renderTo : <%=q(renderId)%>,
readOnly : <%=readOnly%>,
- allowShareReport: <%=allowShareReport%>,
minHeight : 500,
minWidth : 500,
initialURL : <%=q(initialViewURL)%>,
diff --git a/query/src/org/labkey/query/QueryModule.java b/query/src/org/labkey/query/QueryModule.java
index 7e787e990c7..9add4be9e64 100644
--- a/query/src/org/labkey/query/QueryModule.java
+++ b/query/src/org/labkey/query/QueryModule.java
@@ -77,7 +77,6 @@
import org.labkey.api.security.roles.PlatformDeveloperRole;
import org.labkey.api.security.roles.Role;
import org.labkey.api.security.roles.RoleManager;
-import org.labkey.api.settings.OptionalFeatureFlag;
import org.labkey.api.settings.OptionalFeatureService;
import org.labkey.api.stats.AnalyticsProviderRegistry;
import org.labkey.api.stats.SummaryStatisticRegistry;
@@ -149,7 +148,6 @@
import java.util.function.Supplier;
import static org.labkey.api.query.QueryService.USE_ROW_BY_ROW_UPDATE;
-import static org.labkey.api.reports.ReportService.R_REPORT_CUSTOM_SHARING;
public class QueryModule extends DefaultModule
{
@@ -352,14 +350,6 @@ public void doStartup(ModuleContext moduleContext)
if (null != trustedAnalystRole)
trustedAnalystRole.addPermission(EditQueriesPermission.class);
- OptionalFeatureService.get().addFeatureFlag(new OptionalFeatureFlag(R_REPORT_CUSTOM_SHARING,
- "Restore custom R report sharing",
- "Allows R reports to be shared on a per user basis. This option will be removed in LabKey Server 26.7.",
- false,
- false,
- OptionalFeatureService.FeatureType.Deprecated)
- );
-
McpService.get().register(new QueryMcp());
QueryUserSchema.register(this);
}
diff --git a/query/src/org/labkey/query/reports/ReportsController.java b/query/src/org/labkey/query/reports/ReportsController.java
index 8d940b94cb6..d4413d2302f 100644
--- a/query/src/org/labkey/query/reports/ReportsController.java
+++ b/query/src/org/labkey/query/reports/ReportsController.java
@@ -41,7 +41,6 @@
import org.labkey.api.action.ReturnUrlForm;
import org.labkey.api.action.SimpleViewAction;
import org.labkey.api.action.SpringActionController;
-import org.labkey.api.admin.notification.NotificationService;
import org.labkey.api.attachments.Attachment;
import org.labkey.api.attachments.AttachmentFile;
import org.labkey.api.attachments.AttachmentForm;
@@ -81,7 +80,6 @@
import org.labkey.api.reports.model.ViewCategory;
import org.labkey.api.reports.model.ViewCategoryManager;
import org.labkey.api.reports.model.ViewInfo;
-import org.labkey.api.reports.permissions.ShareReportPermission;
import org.labkey.api.reports.report.AbstractReport;
import org.labkey.api.reports.report.AbstractReportIdentifier;
import org.labkey.api.reports.report.ModuleReportIdentifier;
@@ -112,7 +110,6 @@
import org.labkey.api.security.RequiresNoPermission;
import org.labkey.api.security.RequiresPermission;
import org.labkey.api.security.RequiresSiteAdmin;
-import org.labkey.api.security.SecurityManager;
import org.labkey.api.security.User;
import org.labkey.api.security.UserManager;
import org.labkey.api.security.permissions.AdminOperationsPermission;
@@ -123,7 +120,6 @@
import org.labkey.api.study.Dataset;
import org.labkey.api.study.Study;
import org.labkey.api.study.StudyService;
-import org.labkey.api.study.StudyUrls;
import org.labkey.api.study.reports.CrosstabReport;
import org.labkey.api.thumbnail.BaseThumbnailAction;
import org.labkey.api.thumbnail.ThumbnailProvider;
@@ -281,16 +277,6 @@ public ActionURL urlExportCrosstab(Container c)
return new ActionURL(CrosstabExportAction.class, c);
}
- @Override
- public ActionURL urlShareReport(Container c, Report r)
- {
- if (r.getDescriptor().getReportId() == null)
- return null;
- ActionURL url = new ActionURL(ShareReportAction.class, c);
- url.addParameter("reportId", r.getDescriptor().getReportId().toString());
- return url;
- }
-
@Override
public ActionURL urlImage(Container c, Report r, ImageType type, @Nullable Integer revision)
{
@@ -1036,115 +1022,6 @@ public void addNavTrail(NavTree root)
}
}
- @RequiresPermission(ShareReportPermission.class)
- public static class ShareReportAction extends FormViewAction
- {
- Report _report = null;
- List _validRecipients = new ArrayList<>();
-
- @Override
- public ModelAndView getView(ShareReportForm form, boolean reshow, BindException errors)
- {
- return new JspView<>("/org/labkey/query/reports/view/shareReport.jsp", form, errors);
- }
-
- @Override
- public void validateCommand(ShareReportForm form, Errors errors)
- {
- _validRecipients = SecurityManager.parseRecipientListForContainer(getContainer(), form.getRecipientList(), errors);
- }
-
- @Override
- public boolean handlePost(ShareReportForm form, BindException errors) throws Exception
- {
- if (null != form.getReportId())
- _report = form.getReportId().getReport(getViewContext());
-
- if (!errors.hasErrors() && !_validRecipients.isEmpty() && _report != null)
- {
- for (User recipient : _validRecipients)
- {
- NotificationService.get().sendMessageForRecipient(
- getContainer(), getUser(), recipient,
- form.getMessageSubject(), form.getMessageBody(), _report.getRunReportURL(getViewContext()),
- form.getReportId().toString(), Report.SHARE_REPORT_TYPE
- );
-
- // if the report is already public, send the notification but don't update the policy
- if (!ReportDescriptor.REPORT_ACCESS_PUBLIC.equals(_report.getDescriptor().getAccess()))
- ReportUtil.updateReportSecurityPolicy(getViewContext(), _report, recipient.getUserId(), true);
-
- String auditMsg = "The following report was shared: recipient: " + recipient.getName() + " (" + recipient.getUserId() + ")"
- + ", reportId: " + _report.getDescriptor().getReportId()
- + ", name: " + _report.getDescriptor().getReportName();
- StudyService.get().addStudyAuditEvent(getContainer(), getUser(), auditMsg);
- }
- }
-
- return !errors.hasErrors();
- }
-
- @Override
- public URLHelper getSuccessURL(ShareReportForm form)
- {
- if (_report != null && getContainer().hasPermission(getUser(), AdminPermission.class))
- {
- return urlProvider(StudyUrls.class).getManageReportPermissions(getContainer()).
- addParameter(ReportDescriptor.Prop.reportId, _report.getDescriptor().getReportId().toString());
- }
-
- return form.getReturnActionURL(form.getDefaultUrl(getContainer()));
- }
-
- @Override
- public void addNavTrail(NavTree root)
- {
- root.addChild("Share Report");
- }
- }
-
- public static class ShareReportForm extends ReportDesignBean
- {
- private String _recipientList;
- private String _messageSubject;
- private String _messageBody;
-
- public String getRecipientList()
- {
- return _recipientList;
- }
-
- public void setRecipientList(String recipientList)
- {
- _recipientList = recipientList;
- }
-
- public String getMessageSubject()
- {
- return _messageSubject;
- }
-
- public void setMessageSubject(String messageSubject)
- {
- _messageSubject = messageSubject;
- }
-
- public String getMessageBody()
- {
- return _messageBody;
- }
-
- public void setMessageBody(String messageBody)
- {
- _messageBody = messageBody;
- }
-
- public ActionURL getDefaultUrl(Container container)
- {
- return new ActionURL(ManageViewsAction.class, container);
- }
- }
-
@RequiresPermission(ReadPermission.class)
public class DetailsAction extends SimpleViewAction>
{
diff --git a/query/src/org/labkey/query/reports/view/reportDetails.jsp b/query/src/org/labkey/query/reports/view/reportDetails.jsp
index e5d7a62c5a8..ef4354377fb 100644
--- a/query/src/org/labkey/query/reports/view/reportDetails.jsp
+++ b/query/src/org/labkey/query/reports/view/reportDetails.jsp
@@ -19,7 +19,6 @@
<%@ page import="org.labkey.api.reports.model.ReportPropsManager" %>
<%@ page import="org.labkey.api.reports.report.ModuleReportDescriptor" %>
<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %>
-<%@ page import="org.labkey.api.reports.report.ReportUrls" %>
<%@ page import="org.labkey.api.reports.report.view.ReportDesignBean" %>
<%@ page import="org.labkey.api.reports.report.view.ReportUtil" %>
<%@ page import="org.labkey.api.security.UserManager" %>
@@ -50,7 +49,6 @@
ActionURL vewReportURL = report.getRunReportURL(context);
ActionURL editReportURL = report.getEditReportURL(context, getActionURL());
- ActionURL shareReportURL = urlProvider(ReportUrls.class).urlShareReport(getContainer(), report);
String type = report.getTypeDescription();
String category = "";
@@ -253,7 +251,6 @@
<%= button("View Report").href(vewReportURL).target(report.getRunReportTarget()) %>
<%= report.canEdit(getUser(), getContainer()) && (editReportURL != null) ? button("Edit Report").href(editReportURL) : HtmlString.EMPTY_STRING%>
- <%= report.allowShareButton(getUser(), getContainer()) && (shareReportURL != null) ? button("Share Report").href(shareReportURL) : HtmlString.EMPTY_STRING%>
diff --git a/query/src/org/labkey/query/reports/view/shareReport.jsp b/query/src/org/labkey/query/reports/view/shareReport.jsp
deleted file mode 100644
index 46e0583c43e..00000000000
--- a/query/src/org/labkey/query/reports/view/shareReport.jsp
+++ /dev/null
@@ -1,94 +0,0 @@
-<%
-/*
- * Copyright (c) 2017-2026 LabKey Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-%>
-<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %>
-<%@ page import="org.labkey.api.data.Container" %>
-<%@ page import="org.labkey.api.reports.Report" %>
-<%@ page import="org.labkey.api.reports.report.ReportDescriptor" %>
-<%@ page import="org.labkey.api.security.SecurityUrls" %>
-<%@ page import="org.labkey.api.util.PageFlowUtil" %>
-<%@ page import="org.labkey.api.view.ActionURL" %>
-<%@ page import="org.labkey.api.view.HttpView" %>
-<%@ page import="org.labkey.api.view.JspView" %>
-<%@ page import="org.labkey.query.reports.ReportsController.ShareReportAction" %>
-<%@ page import="org.labkey.query.reports.ReportsController.ShareReportForm" %>
-<%@ page extends="org.labkey.api.jsp.JspBase" %>
-<%
- JspView me = HttpView.currentView();
- ShareReportForm bean = me.getModelBean();
-
- Report report = null;
- if (null != bean.getReportId())
- report = bean.getReportId().getReport(getViewContext());
-%>
-<%
- if (null == report || !report.allowShareButton(getUser(), getContainer()))
- {
-%>
- Invalid report identifier, unable to view share report options.
-<%
- }
- else
- {
- Container container = getContainer();
- String reportName = report.getDescriptor().getResourceName();
- ActionURL returnUrl = bean.getReturnActionURL(bean.getDefaultUrl(container));
- ActionURL completionUrl = urlProvider(SecurityUrls.class).getCompleteUserReadURL(container);
- ActionURL reportUrl = report.getRunReportURL(getViewContext());
-
- String messageSubject = bean.getMessageSubject() != null ? bean.getMessageSubject()
- : "A report has been sent: " + reportName;
- String messageBody = bean.getMessageBody() != null ? bean.getMessageBody()
- : getUser().getDisplayName(getUser()) + " has sent the following report to you: \"" + reportName + "\"."
- + "\n\nNote: if the sender has different permissions levels than you, you may see a different set of data."
- + "\n\nClick the link below to view the sent report: ";
-%>
- <%=h(report.getDescriptor().getReportName())%>
- Send a copy of your report to one or more users to save and edit on their own.
-
Note: if the recipient user has a different permissions level than you for the source data/container, that user may see a different set of data.
- Additionally, any further modifications to this report will be reflected in the link as viewed by the recipient.
-
-
-
- Recipients (one per line):
-
-
-
- Message Subject:
-
-
-
- Message Body:
-
-
-
- Message link:
- <%=h(reportUrl.getBaseServerURI() + PageFlowUtil.decode(reportUrl.toString()))%>
-
-
-
-
- <%=generateReturnUrlFormField(bean)%>
- <%= button("Submit").submit(true) %>
- <%= button("Cancel").href(returnUrl) %>
-
-<%
- }
-%>
\ No newline at end of file
diff --git a/query/webapp/reports/ScriptReportPanel.js b/query/webapp/reports/ScriptReportPanel.js
index d2ab63a1f54..2569e9e1668 100644
--- a/query/webapp/reports/ScriptReportPanel.js
+++ b/query/webapp/reports/ScriptReportPanel.js
@@ -601,19 +601,6 @@ Ext4.define('LABKEY.ext4.ScriptReportPanel', {
}
});
- items.push({
- xtype: 'button',
- text: 'Share Report',
- hidden: !this.allowShareReport || this.reportConfig.reportId == null,
- style: 'margin-left: 5px;',
- scope: this,
- handler: function() {
- window.location = LABKEY.ActionURL.buildURL('reports', 'shareReport', null, {
- reportId: this.reportConfig.reportId
- });
- }
- });
-
if (this.externalEditSettings) {
items.push(this.getExternalEditBtn());
}
diff --git a/study/src/org/labkey/study/view/reportPermission.jsp b/study/src/org/labkey/study/view/reportPermission.jsp
index a94d0ff6e4d..d0035c57c5d 100644
--- a/study/src/org/labkey/study/view/reportPermission.jsp
+++ b/study/src/org/labkey/study/view/reportPermission.jsp
@@ -213,14 +213,6 @@
access through this view.
- <% if (bean.allowShareButton(getUser(), getContainer())) { %>
-
- This report type allows for sharing with individual users. Any users that this report has already been shared with
- will be listed in the "Specific Users" section above. To add additional users, click the button below.
- <%= button("Share Report").href(urlProvider(ReportUrls.class).urlShareReport(getContainer(), bean)) %>
-
- <% } %>
-
For more information on study security, consult the main documentation: