This is an automated email from the ASF dual-hosted git repository.

msyavuz pushed a commit to branch msyavuz/fix/chart-dashboard-alert-recipient
in repository https://gitbox.apache.org/repos/asf/superset.git

commit a7e5352dfcf073e800b007b6095f01f97db330eb
Author: Mehmet Salih Yavuz <[email protected]>
AuthorDate: Thu Jan 8 15:47:31 2026 +0300

    fix(reports): Use authenticated user as recipient for chart/dashboard 
reports
---
 superset/commands/report/create.py     | 32 ++++++++++++++++++++++++++++++++
 superset/commands/report/exceptions.py | 13 +++++++++++++
 superset/reports/schemas.py            |  2 +-
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/superset/commands/report/create.py 
b/superset/commands/report/create.py
index e238102f90..9fee6bc4ce 100644
--- a/superset/commands/report/create.py
+++ b/superset/commands/report/create.py
@@ -18,6 +18,7 @@ import logging
 from functools import partial
 from typing import Any, Optional
 
+from flask import g
 from flask_babel import gettext as _
 from marshmallow import ValidationError
 
@@ -30,11 +31,13 @@ from superset.commands.report.exceptions import (
     ReportScheduleCreationMethodUniquenessValidationError,
     ReportScheduleInvalidError,
     ReportScheduleNameUniquenessValidationError,
+    ReportScheduleUserEmailNotFoundError,
 )
 from superset.daos.database import DatabaseDAO
 from superset.daos.report import ReportScheduleDAO
 from superset.reports.models import (
     ReportCreationMethod,
+    ReportRecipientType,
     ReportSchedule,
     ReportScheduleType,
 )
@@ -54,6 +57,32 @@ class CreateReportScheduleCommand(CreateMixin, 
BaseReportScheduleCommand):
         self.validate()
         return ReportScheduleDAO.create(attributes=self._properties)
 
+    def _populate_recipients(self, exceptions: list[ValidationError]) -> None:
+        """
+        Populate recipients based on creation method and current user.
+        
+        For reports initiated from charts or dashboards, always use
+        the current user's email as the recipient, ignoring any
+        client-provided recipient values. Raises validation error if
+        user has no email address.
+        """
+        creation_method = self._properties.get("creation_method")
+        
+        # For reports from charts/dashboards, always use current user
+        if creation_method in (ReportCreationMethod.CHARTS, 
ReportCreationMethod.DASHBOARDS):
+            if hasattr(g, "user") and g.user and g.user.email:
+                # Override any provided recipients with current user's email
+                self._properties["recipients"] = [
+                    {
+                        "type": ReportRecipientType.EMAIL,
+                        "recipient_config_json": json.dumps({"target": 
g.user.email}),
+                    }
+                ]
+            else:
+                # User doesn't have an email address - can't create report
+                exceptions.append(ReportScheduleUserEmailNotFoundError())
+        # For creation from alerts_reports view, keep the recipients as 
provided
+
     def validate(self) -> None:
         """
         Validates the properties of a report schedule configuration, including 
uniqueness
@@ -74,6 +103,9 @@ class CreateReportScheduleCommand(CreateMixin, 
BaseReportScheduleCommand):
         owner_ids: Optional[list[int]] = self._properties.get("owners")
 
         exceptions: list[ValidationError] = []
+        
+        # Populate recipients if needed (may add validation errors)
+        self._populate_recipients(exceptions)
 
         # Validate name type uniqueness
         if not ReportScheduleDAO.validate_update_uniqueness(name, report_type):
diff --git a/superset/commands/report/exceptions.py 
b/superset/commands/report/exceptions.py
index 8688627810..eeaa19e1d7 100644
--- a/superset/commands/report/exceptions.py
+++ b/superset/commands/report/exceptions.py
@@ -309,3 +309,16 @@ class ReportScheduleForbiddenError(ForbiddenError):
 
 class ReportSchedulePruneLogError(CommandException):
     message = _("An error occurred while pruning logs ")
+
+
+class ReportScheduleUserEmailNotFoundError(ValidationError):
+    """
+    Validation error when user email is required but not found
+    """
+
+    def __init__(self) -> None:
+        super().__init__(
+            _("Unable to create report: User email address is required but not 
found. "
+              "Please ensure your user profile has a valid email address."),
+            field_name="recipients",
+        )
diff --git a/superset/reports/schemas.py b/superset/reports/schemas.py
index cfccc579bc..76108f976f 100644
--- a/superset/reports/schemas.py
+++ b/superset/reports/schemas.py
@@ -224,7 +224,7 @@ class ReportSchedulePostSchema(Schema):
         validate=[Range(min=1, error=_("Value must be greater than 0"))],
     )
 
-    recipients = fields.List(fields.Nested(ReportRecipientSchema))
+    recipients = fields.List(fields.Nested(ReportRecipientSchema), 
required=False)
     report_format = fields.String(
         dump_default=ReportDataFormat.PNG,
         validate=validate.OneOf(choices=tuple(key.value for key in 
ReportDataFormat)),

Reply via email to