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)),
