Repository navigation
fix: add subdirectory deployment support for app icon and reports urls - #35098
Conversation
There was a problem hiding this comment.
Review by Korbit AI
Korbit automatically attempts to detect when you fix issues in new commits.
| Category | Issue | Status |
|---|---|---|
| Potential Double Slash in Swagger Redirect URL ▹ view | ✅ Fix detected |
Files scanned
| File Path | Reviewed |
|---|---|
| superset/app.py | ✅ |
| superset/views/core.py | ✅ |
Explore our documentation to understand the languages and file types we support and the files we ignore.
Check out our docs on how you can make Korbit work best for you and your team.
|
|
||
| # Flask-AppBuilder's swagger endpoint is typically /api/v1/swagger | ||
| # Redirect to it with the proper application root prefix | ||
| fab_swagger_path = f"{app_root}/api/v1/swagger" |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
@eschutho I approved your flask-appbuilder PR, it's probably better |
Thanks! I removed the subdirectory piece and added in alerts/reports urls here. |
There was a problem hiding this comment.
I've completed my review and didn't find any issues.
Files scanned
| File Path | Reviewed |
|---|---|
| superset/utils/urls.py | ✅ |
| superset/app.py | ✅ |
Explore our documentation to understand the languages and file types we support and the files we ignore.
Check out our docs on how you can make Korbit work best for you and your team.
b1b353b to
c2cccdc
Compare
d5697d5 to
a74206e
Compare
720f5d1 to
60e287d
Compare
- Fix get_url_path() in superset/utils/urls.py to include APPLICATION_ROOT when generating URLs outside of request context (e.g., in Celery tasks) - This fixes alert and report screenshot generation in subdirectory deployments - Add comprehensive tests for URL generation with various configurations - Tests verify subdirectory prefixing works correctly for both charts and dashboards 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Replace 'Fix subdirectory deployment' with descriptive comments - Comments now describe what the code does rather than framing as fixes - More direct and timeless language in code documentation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
The get_url_path function was incorrectly adding APPLICATION_ROOT prefix even when already in a request context. Flask's url_for already respects SCRIPT_NAME from the WSGI environment in request contexts, so manually adding the prefix caused incorrect URLs. This fix: - Only adds APPLICATION_ROOT prefix when creating a new request context - Trusts Flask's url_for when already in a request context - Fixes test failures where changing APPLICATION_ROOT didn't affect SCRIPT_NAME in the existing request context - Simplifies code by removing nullcontext dependency Also adds frontend tests for pathUtils functions following the project's "avoid nesting when testing" principle. Co-Authored-By: Claude <noreply@anthropic.com>
6f1aa0c to
f240868
Compare
|
CodeAnt AI is reviewing your PR. |
| const openQuery = (id: number) => { | ||
| const url = `/sqllab?queryId=${id}`; | ||
| const url = makeUrl(`/sqllab?queryId=${id}`); | ||
| window.open(url); |
There was a problem hiding this comment.
Suggestion: Security (reverse tabnabbing): opening a URL with window.open(url) without specifying a target and opener protection allows the opened page to access window.opener and potentially redirect the original page. Use window.open with target '_blank' and prevent access to window.opener by passing window features (e.g., 'noopener,noreferrer') so the newly opened page cannot manipulate the opener. [security]
Severity Level: Critical 🚨
| window.open(url); | |
| window.open(url, '_blank', 'noopener,noreferrer'); |
Why it matters? ⭐
The existing code calls window.open(url) which can expose the opener to the newly opened page in some browsers. The suggested change (adding '_blank' and 'noopener,noreferrer') prevents reverse tabnabbing by ensuring the opened window can't access or manipulate window.opener. This is a real security hardening (not just stylistic) and is safe and self-contained in this PR context.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/SqlLab/components/QueryTable/index.tsx
**Line:** 73:73
**Comment:**
*Security: Security (reverse tabnabbing): opening a URL with window.open(url) without specifying a target and opener protection allows the opened page to access window.opener and potentially redirect the original page. Use window.open with target '_blank' and prevent access to window.opener by passing window features (e.g., 'noopener,noreferrer') so the newly opened page cannot manipulate the opener.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
|
||
| const getExportCsvUrl = (clientId: string) => | ||
| ensureAppRoot(`/api/v1/sqllab/export/${clientId}/`); | ||
| makeUrl(`/api/v1/sqllab/export/${clientId}/`); |
There was a problem hiding this comment.
Suggestion: Path injection / malformed-URL risk: clientId is interpolated directly into the path passed to makeUrl. If clientId contains unexpected characters (slashes, spaces, query chars), the resulting URL can be malformed or allow unintentional path manipulation. Apply URL-encoding to clientId (encodeURIComponent) before building the URL. [security]
Severity Level: Critical 🚨
| makeUrl(`/api/v1/sqllab/export/${clientId}/`); | |
| makeUrl(`/api/v1/sqllab/export/${encodeURIComponent(clientId)}/`); |
Why it matters? ⭐
URL-encoding the clientId is a small, useful hardening: if clientId ever contains characters like slashes, spaces or query chars it could produce a malformed path. The current code interpolates raw input into a path; encodeURIComponent(clientId) is safe and doesn't change expected behavior for normal IDs (UUIDs/numeric/nanoid) while preventing accidental path manipulation. This is a real, low-risk security/robustness improvement.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/SqlLab/components/ResultSet/index.tsx
**Line:** 318:318
**Comment:**
*Security: Path injection / malformed-URL risk: `clientId` is interpolated directly into the path passed to `makeUrl`. If `clientId` contains unexpected characters (slashes, spaces, query chars), the resulting URL can be malformed or allow unintentional path manipulation. Apply URL-encoding to `clientId` (encodeURIComponent) before building the URL.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| window.open( | ||
| `/sqllab?datasourceKey=${datasource}&sql=${encodeURIComponent(currentSQL)}`, | ||
| makeUrl( | ||
| `/sqllab?datasourceKey=${datasource}&sql=${encodeURIComponent(currentSQL)}`, |
There was a problem hiding this comment.
Suggestion: The URL constructed for opening SQL Lab includes datasource raw; if datasource contains characters that must be URL-encoded the resulting URL can be malformed. Encode datasource with encodeURIComponent before interpolating it into the query string passed to makeUrl(...). [possible bug]
Severity Level: Critical 🚨
| `/sqllab?datasourceKey=${datasource}&sql=${encodeURIComponent(currentSQL)}`, | |
| `/sqllab?datasourceKey=${encodeURIComponent(datasource ?? '')}&sql=${encodeURIComponent(currentSQL)}`, |
Why it matters? ⭐
This is a straightforward bug: interpolating datasource directly into a query string can break URLs if it contains characters like '&', '?', or '#'. Using encodeURIComponent(datasource ?? '') is the correct and minimal fix to avoid malformed URLs and potential parameter injection.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/explore/components/controls/ViewQuery.tsx
**Line:** 142:142
**Comment:**
*Possible Bug: The URL constructed for opening SQL Lab includes `datasource` raw; if `datasource` contains characters that must be URL-encoded the resulting URL can be malformed. Encode `datasource` with `encodeURIComponent` before interpolating it into the query string passed to `makeUrl(...)`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| @@ -58,7 +59,7 @@ const REDIRECTS = { | |||
| create: { | |||
| [WelcomeTable.Charts]: '/chart/add', | |||
There was a problem hiding this comment.
Suggestion: The create redirect '/chart/add' is a raw path and will not include the application root for subdirectory deployments; wrap it with makeUrl so the navigation URL is correct when the app is served from a subdirectory. [logic error]
Severity Level: Minor
| [WelcomeTable.Charts]: '/chart/add', | |
| [WelcomeTable.Charts]: makeUrl('/chart/add'), |
Why it matters? ⭐
Using a raw '/chart/add' path will break when the app is served from a subdirectory. Converting to makeUrl('/chart/add') ensures the application root is prepended and is consistent with how SavedQueries.create is handled.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/features/home/EmptyState.tsx
**Line:** 60:60
**Comment:**
*Logic Error: The create redirect '/chart/add' is a raw path and will not include the application root for subdirectory deployments; wrap it with `makeUrl` so the navigation URL is correct when the app is served from a subdirectory.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| } from '@superset-ui/core/components'; | ||
| import type { ItemType, MenuItem } from '@superset-ui/core/components/Menu'; | ||
| import { ensureAppRoot } from 'src/utils/pathUtils'; | ||
| import { ensureAppRoot, makeUrl } from 'src/utils/pathUtils'; |
There was a problem hiding this comment.
Suggestion: The new import added makeUrl but if you revert the menu.url change (as suggested) makeUrl becomes unused. Keep imports minimal to avoid unused-import lint errors and confusion: only import ensureAppRoot here since other code in this file calls ensureAppRoot directly. [code quality]
Severity Level: Minor
| import { ensureAppRoot, makeUrl } from 'src/utils/pathUtils'; | |
| import { ensureAppRoot } from 'src/utils/pathUtils'; |
Why it matters? ⭐
This is a valid code-quality suggestion but conditional: as the file currently stands makeUrl is used (menu.url uses makeUrl). If you apply suggestion #1 (revert menu.url to the raw route), then makeUrl will become unused and should be removed to avoid lint errors and confusion. Removing the unused import is a small, correct cleanup.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/features/home/RightMenu.tsx
**Line:** 36:36
**Comment:**
*Code Quality: The new import added `makeUrl` but if you revert the menu.url change (as suggested) `makeUrl` becomes unused. Keep imports minimal to avoid unused-import lint errors and confusion: only import `ensureAppRoot` here since other code in this file calls `ensureAppRoot` directly.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| label: t('SQL query'), | ||
| url: '/sqllab?new=true', | ||
| url: makeUrl('/sqllab?new=true'), | ||
| icon: <Icons.SearchOutlined data-test={`menu-item-${t('SQL query')}`} />, |
There was a problem hiding this comment.
Suggestion: Using makeUrl to pre-prefix the SQL query URL stores an application-root-prefixed path into menu.url. Later code expects menu.url to be a raw route and calls ensureAppRoot(menu.url) when rendering external links (or passes it to isFrontendRoute). Because ensureAppRoot always prefixes the application root, this causes double-prefixing (e.g. '/superset/superset/sqllab...') or incorrect frontend-route detection in subdirectory deployments. Use the raw route here (e.g., '/sqllab?new=true') and let the existing rendering logic call ensureAppRoot where needed. [logic error]
Severity Level: Minor
| icon: <Icons.SearchOutlined data-test={`menu-item-${t('SQL query')}`} />, | |
| url: '/sqllab?new=true', |
Why it matters? ⭐
The suggestion is correct and fixes a real logic bug. makeUrl() is just a thin wrapper that calls ensureAppRoot(path) (see src/utils/pathUtils.ts where makeUrl returns ensureAppRoot(path)). In RightMenu.buildNewDropdownItems the code later calls ensureAppRoot(menu.url) when rendering non-frontend links (and also passes menu.url to isFrontendRoute). If menu.url is already prefixed via makeUrl, calling ensureAppRoot again double-prefixes the path (e.g. '/superset/sqllab' -> '/superset/superset/sqllab') and can also break frontend-route detection. I verified makeUrl usage and implementation (pathUtils.ts) and the RightMenu rendering sites that wrap menu.url with ensureAppRoot, so keeping the raw route ('/sqllab?new=true') here is the correct fix.
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/src/features/home/RightMenu.tsx
**Line:** 205:205
**Comment:**
*Logic Error: Using makeUrl to pre-prefix the SQL query URL stores an application-root-prefixed path into `menu.url`. Later code expects `menu.url` to be a raw route and calls `ensureAppRoot(menu.url)` when rendering external links (or passes it to `isFrontendRoute`). Because `ensureAppRoot` always prefixes the application root, this causes double-prefixing (e.g. '/superset/superset/sqllab...') or incorrect frontend-route detection in subdirectory deployments. Use the raw route here (e.g., '/sqllab?new=true') and let the existing rendering logic call `ensureAppRoot` where needed.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Nitpicks 🔍
|
|
CodeAnt AI finished reviewing your PR. |
apache#35098) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Daniel Gaspar <danielvazgaspar@gmail.com>
apache#35098) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Daniel Gaspar <danielvazgaspar@gmail.com> (cherry picked from commit b35b1d7)
apache#35098) Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Daniel Gaspar <danielvazgaspar@gmail.com>
User description
Summary
This PR fixes subdirectory deployments in Apache Superset by addressing two key issues:
1. App Icon Subdirectory Support
APP_ICONpath to include subdirectory prefix whenAPPLICATION_ROOTis not "/"/static/paths with the configured subdirectory/static/2. Alert/Report Screenshot URL Generation
Problem
When Superset is deployed in a subdirectory (e.g.,
https://example.com/superset/), two features don't work correctly:APP_ICON) uses hardcoded/static/paths that don't work in subdirectory deploymentsSolution
App Icon Fix
Added logic in
superset/app.pythat:APP_ICONpaths that start with/static/app_root != "/")Example behavior:
APP_ICON = "/static/assets/images/logo.png"→ unchangedAPP_ICON = "/static/assets/images/logo.png"→"/superset/static/assets/images/logo.png"Alert/Report Screenshot Fix
Enhanced
get_url_path()insuperset/utils/urls.pyto:APPLICATION_ROOTprefix when generating URLs outside request contextExample behavior:
http://localhost:8088/dashboard/123/http://localhost:8088/superset/dashboard/123/Test Plan
Additional Context
Files Changed:
superset/app.py- App icon subdirectory fixsuperset/utils/urls.py- Screenshot URL generation fixtests/integration_tests/test_subdirectory_deployments.py- Comprehensive test coverageTest Coverage:
This change follows existing patterns in Superset for subdirectory deployment support and ensures alerts, reports, and UI elements work correctly in all deployment scenarios.
🤖 Generated with Claude Code
CodeAnt-AI Description
Fix subdirectory deployments for app icon, SQL Lab links, and background URLs
What Changed
Impact
✅ App icon loads in subdirectory deployments✅ Fewer failed alert/report screenshots in subdirectory deployments✅ SQL Lab navigation, saved-query links, and exports work under subpath💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Fixes #35027
Fixes #34773