Copilot commented on code in PR #39303:
URL: https://github.com/apache/superset/pull/39303#discussion_r3190473252


##########
superset/views/datasource/views.py:
##########
@@ -223,6 +224,25 @@ def samples(self) -> FlaskResponse:
                 dashboard,
             ):
                 return json_error_response(_("Forbidden"), status=403)
+        else:
+            # Pre-fetch and access-check only for table-type datasources.
+            # Non-table types (query, saved_query) use a different access 
model;
+            # passing them to raise_for_access(datasource=...) would check the
+            # wrong attributes. Let get_samples() handle the lookup for those 
types.
+            if params["datasource_type"] == DatasourceType.TABLE:
+                try:
+                    dataset = DatasourceDAO.get_datasource(
+                        params["datasource_type"],
+                        params["datasource_id"],
+                    )
+                except (DatasourceNotFound, DatasourceTypeNotSupportedError):
+                    return self.response_404()
+                try:
+                    security_manager.raise_for_access(datasource=dataset)
+                except SupersetSecurityException:
+                    return json_error_response(_("Forbidden"), status=403)

Review Comment:
   This compares `params[\"datasource_type\"]` to `DatasourceType.TABLE`, but 
`params[\"datasource_type\"]` is commonly a string (e.g. `'table'`). If it’s a 
string here, this branch never executes, so the intended prefetch/access-check 
and redundant-lookup avoidance won’t happen. Normalize the type before 
comparing (e.g., compare to `DatasourceType.TABLE.value` or cast/convert 
`params[\"datasource_type\"]` to the enum). Also consider using keyword args 
for `DatasourceDAO.get_datasource(...)` to avoid signature/ordering issues and 
keep consistent with the helper usage.



##########
superset/views/datasource/utils.py:
##########
@@ -24,7 +24,7 @@
 from superset.common.query_context_factory import QueryContextFactory
 from superset.common.utils.query_cache_manager import QueryCacheManager
 from superset.constants import CacheRegion
-from superset.daos.datasource import DatasourceDAO
+from superset.daos.datasource import Datasource, DatasourceDAO

Review Comment:
   Importing `Datasource` at runtime just for typing can introduce import 
cycles and runtime failures if `Datasource` isn’t a concrete export in that 
module. Prefer a typing-only import (via `typing.TYPE_CHECKING`) and/or 
postponed evaluation of annotations, or type against a stable protocol/base 
class to keep this helper robust.



##########
superset/commands/report/base.py:
##########
@@ -50,6 +53,34 @@ def run(self) -> Any:
     def validate(self) -> None:
         pass
 
+    def _check_chart_access(
+        self, chart_id: int, exceptions: list[ValidationError]
+    ) -> None:
+        """Validate chart exists and the current user can access it."""
+        chart = ChartDAO.find_by_id(chart_id)
+        if not chart:
+            exceptions.append(ChartNotFoundValidationError())
+        else:
+            try:
+                security_manager.raise_for_access(viz=chart)

Review Comment:
   `security_manager.raise_for_access(viz=chart)` is inconsistent with the rest 
of this PR (which uses `chart=...` for `Slice` access checks). If 
`raise_for_access` doesn’t accept `viz` in this deployment, this will raise 
`TypeError` and return a 500. Use the same keyword used elsewhere (e.g., 
`chart=chart`) to ensure the access check is actually applied and doesn’t crash.
   



##########
superset/sqllab/api.py:
##########
@@ -338,7 +338,6 @@ def export_csv(self, client_id: str) -> CsvResponse:
 
     @expose("/export_streaming/", methods=("POST",))
     @protect()

Review Comment:
   Removing `@permission_name(\"read\")` changes how Flask-AppBuilder derives 
the permission for this endpoint (often defaulting to the method name). That 
can be a breaking change for existing roles/permissions and may unintentionally 
tighten/loosen access. If the intent is to change the permission model, 
add/update an integration test asserting the expected permission behavior; 
otherwise, consider restoring an explicit `@permission_name(...)`.
   



##########
superset/views/users/api.py:
##########
@@ -169,9 +169,11 @@ class UserRestApi(BaseSupersetApi):
 
     resource_name = "user"
     openapi_spec_tag = "User"
+    allow_browser_login = True
     openapi_spec_component_schemas = (UserResponseSchema,)
 
     @expose("/<int:user_id>/avatar.png", methods=("GET",))
+    @protect()

Review Comment:
   The PR description mentions adding `@protect()` to the avatar endpoint, but 
this change also sets `allow_browser_login = True` at the API class level 
(affecting all `UserRestApi` endpoints, not just avatar). Either document this 
broader behavioral change in the PR description or scope it more narrowly if 
only needed for the avatar route.



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