sadpandajoe commented on code in PR #43340:
URL: https://github.com/apache/superset/pull/43340#discussion_r3867504892


##########
superset/tasks/export_dashboard_excel.py:
##########
@@ -441,6 +453,59 @@ def _handle_export_failure(
         logger.exception("Failed to record export failure status for %s", 
job_id)
 
 
+def _resolve_export_storage(
+    dashboard_id: int, job_id: str
+) -> tuple[ExportStorage, str, str]:
+    """The configured storage backend, bucket, and this export's object key.
+
+    The API already rejects the request with 501 when either the bucket or
+    the backend is unset, so reaching this unconfigured normally means
+    EXPORT_STORAGE was cleared after the job was enqueued (or the task
+    was invoked directly, bypassing the API). Fail with a clear message
+    instead of an opaque storage-SDK error.
+    """
+    storage_config = current_app.config["EXPORT_STORAGE"]
+    bucket = storage_config.get("bucket")
+    storage_backend = storage_config.get("backend")
+    if not bucket or storage_backend is None:
+        raise SupersetException(
+            "Excel export is not configured on this server: "
+            "EXPORT_STORAGE needs both a 'bucket' and a 'backend' "
+            "(e.g. superset.utils.s3.S3ExportStorage())."
+        )
+    key_prefix = storage_config.get("key_prefix", "dashboard-exports/")
+    if callable(key_prefix):
+        # A callable prefix is resolved per export, for deployments where it
+        # is only known in task context (e.g. a multi-tenant installation
+        # scoping a shared bucket per tenant).
+        key_prefix = key_prefix()
+    return storage_backend, bucket, f"{key_prefix}{dashboard_id}/{job_id}.xlsx"
+
+
+def _mark_running(job_id: str) -> None:
+    """Tell pollers execution has begun (vs. queued); best-effort, the export
+    must not fail over a status write."""
+    try:
+        expires_at = datetime.now(tz=timezone.utc) + timedelta(
+            seconds=EXPORT_HARD_TIME_LIMIT + 300
+        )
+        mark_export_running(uuid.UUID(job_id), expires_at.replace(tzinfo=None))
+    except Exception:  # pylint: disable=broad-except
+        logger.exception("Failed to record running status for %s", job_id)
+
+
+def _resolve_requesting_user(
+    user_id: int | None, guest_token: GuestToken | None
+) -> Any:
+    if user_id is not None:
+        return security_manager.get_user_by_id(user_id)
+    if guest_token:
+        return security_manager.get_guest_user_from_token(guest_token)

Review Comment:
   This rebuilds the guest principal from the already-decoded payload, so a 
task that waits in Celery can run after the token expires or is revoked. Could 
the worker revalidate the guest token/claims before querying chart data, so 
delayed exports do not continue using stale guest access?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to