From 7bc1ca54cc6a4344d8a7774df0f28f6e42dcf7c9 Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 17:43:18 -0700 Subject: [PATCH 1/6] Remove odfe bwc test (#408) (#409) * removed odfe bwc test Signed-off-by: Shenoy Pratik * removed bwc test from workflows Signed-off-by: Shenoy Pratik (cherry picked from commit 556b5fb0a774534ec167dfb9e96f68855296ef75) Co-authored-by: Shenoy Pratik --- ...orts-scheduler-test-and-build-workflow.yml | 8 - reports-scheduler/build.gradle | 188 ------------------ 2 files changed, 196 deletions(-) diff --git a/.github/workflows/reports-scheduler-test-and-build-workflow.yml b/.github/workflows/reports-scheduler-test-and-build-workflow.yml index 2e78ad08..eaec60d8 100644 --- a/.github/workflows/reports-scheduler-test-and-build-workflow.yml +++ b/.github/workflows/reports-scheduler-test-and-build-workflow.yml @@ -21,13 +21,6 @@ jobs: - name: Checkout Reports Scheduler uses: actions/checkout@v2 - - name: RunBackwards Compatibility Tests - run: | - cd reports-scheduler - echo "Running backwards compatibility tests ..." - ./gradlew bwcTestSuite - - - name: Build with Gradle run: | cd reports-scheduler @@ -50,4 +43,3 @@ jobs: with: name: reports-scheduler path: reports-scheduler-builds - diff --git a/reports-scheduler/build.gradle b/reports-scheduler/build.gradle index ddc2a28f..df277e1d 100644 --- a/reports-scheduler/build.gradle +++ b/reports-scheduler/build.gradle @@ -315,194 +315,6 @@ testClusters.integTest { setting 'path.repo', repo.absolutePath } -// For job-scheduler and reports-scheduler, the latest opendistro releases appear to be 1.13.0.0. -String bwcVersion = "1.13.0.0" -String baseName = "reportsSchedulerBwcCluster" -String bwcFilePath = "src/test/resources/bwc" -String bwcJobSchedulerURL = "https://d3g5vo6xdbdb9a.cloudfront.net/downloads/elasticsearch-plugins/opendistro-job-scheduler/opendistro-job-scheduler-" + bwcVersion + ".zip" -String bwcReportsSchedulerURL = "https://d3g5vo6xdbdb9a.cloudfront.net/downloads/elasticsearch-plugins/opendistro-reports-scheduler/opendistro-reports-scheduler-" + bwcVersion + ".zip" - -2.times {i -> - testClusters { - "${baseName}$i" { - testDistribution = "ARCHIVE" - versions = ["7.10.2", opensearch_version] - numberOfNodes = 3 - plugin(provider(new Callable(){ - @Override - RegularFile call() throws Exception { - return new RegularFile() { - @Override - File getAsFile() { - File dir = new File(bwcFilePath + "/job-scheduler/" + bwcVersion) - if (!dir.exists()) { - dir.mkdirs() - } - File file = new File(dir, "opendistro-job-scheduler-" + bwcVersion + ".zip") - if (!file.exists()) { - new URL(bwcJobSchedulerURL).withInputStream{ ins -> file.withOutputStream{ it << ins }} - } - return fileTree(bwcFilePath + "/job-scheduler/" + bwcVersion).getSingleFile() - } - } - } - })) - plugin(provider(new Callable(){ - @Override - RegularFile call() throws Exception { - return new RegularFile() { - @Override - File getAsFile() { - File dir = new File(bwcFilePath + "/reports-scheduler/" + bwcVersion) - if (!dir.exists()) { - dir.mkdirs() - } - File file = new File(dir, "opendistro-reports-scheduler-" + bwcVersion + ".zip") - if (!file.exists()) { - new URL(bwcReportsSchedulerURL).withInputStream{ ins -> file.withOutputStream{ it << ins }} - } - return fileTree(bwcFilePath + "/reports-scheduler/" + bwcVersion).getSingleFile() - } - } - } - })) - setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}" - setting 'http.content_type.required', 'true' - } - } -} - -List> plugins = [] - -// Ensure the artifact for the current project version is available to be used for the bwc tests -task prepareBwcTests { - dependsOn bundle - doLast { - plugins = [ - provider(new Callable(){ - @Override - RegularFile call() throws Exception { - return new RegularFile() { - @Override - File getAsFile() { - File dir = new File(bwcFilePath + "/job-scheduler/" + project.version) - if (!dir.exists()) { - dir.mkdirs() - } - File file = new File(dir, "opendistro-reports-scheduler-" + project.version + ".zip") - if (!file.exists()) { - new URL(jobSchedulerURL).withInputStream{ ins -> file.withOutputStream{ it << ins }} - } - return fileTree(bwcFilePath + "/job-scheduler/" + project.version).getSingleFile() - } - } - } - }), - project.getObjects().fileProperty().value(bundle.getArchiveFile()) - ] - } -} - -// Create two test clusters with 3 nodes of the old version -2.times {i -> - task "${baseName}#oldVersionClusterTask$i"(type: StandaloneRestIntegTestTask) { - dependsOn 'prepareBwcTests' - useCluster testClusters."${baseName}$i" - filter { - includeTestsMatching "org.opensearch.integTest.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite', 'old_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'old' - systemProperty 'tests.plugin_bwc_version', bwcVersion - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}$i".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}$i".getName()}") - } -} - -// Upgrade one node of the old cluster to new OpenSearch version with upgraded plugin version. -// This results in a mixed cluster with 2 nodes on the old version and 1 upgraded node. -// This is also used as a one third upgraded cluster for a rolling upgrade. -task "${baseName}#mixedClusterTask"(type: StandaloneRestIntegTestTask) { - useCluster testClusters."${baseName}0" - dependsOn "${baseName}#oldVersionClusterTask0" - doFirst { - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.integTest.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'first' - systemProperty 'tests.plugin_bwc_version', bwcVersion - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrade the second node to new OpenSearch version with upgraded plugin version after the first node is upgraded. -// This results in a mixed cluster with 1 node on the old version and 2 upgraded nodes. -// This is used for rolling upgrade. -task "${baseName}#twoThirdsUpgradedClusterTask"(type: StandaloneRestIntegTestTask) { - dependsOn "${baseName}#mixedClusterTask" - useCluster testClusters."${baseName}0" - doFirst { - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.integTest.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'second' - systemProperty 'tests.plugin_bwc_version', bwcVersion - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrade the third node to new OpenSearch version with upgraded plugin version after the second node is upgraded. -// This results in a fully upgraded cluster. -// This is used for rolling upgrade. -task "${baseName}#rollingUpgradeClusterTask"(type: StandaloneRestIntegTestTask) { - dependsOn "${baseName}#twoThirdsUpgradedClusterTask" - useCluster testClusters."${baseName}0" - doFirst { - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.integTest.bwc.*IT" - } - mustRunAfter "${baseName}#mixedClusterTask" - systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'third' - systemProperty 'tests.plugin_bwc_version', bwcVersion - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrade all the nodes of the old cluster to new OpenSearch version with upgraded plugin version -// at the same time resulting in a fully upgraded cluster. -task "${baseName}#fullRestartClusterTask"(type: StandaloneRestIntegTestTask) { - dependsOn "${baseName}#oldVersionClusterTask1" - useCluster testClusters."${baseName}1" - doFirst { - testClusters."${baseName}1".upgradeAllNodesAndPluginsToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.integTest.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite', 'upgraded_cluster' - systemProperty 'tests.plugin_bwc_version', bwcVersion - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}1".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}1".getName()}") -} - -// A bwc test suite which runs all the bwc tasks combined -task bwcTestSuite(type: StandaloneRestIntegTestTask) { - exclude '**/*Test*' - exclude '**/*IT*' - dependsOn tasks.named("${baseName}#mixedClusterTask") - dependsOn tasks.named("${baseName}#rollingUpgradeClusterTask") - dependsOn tasks.named("${baseName}#fullRestartClusterTask") -} - task integTestRemote(type: RestIntegTestTask) { testClassesDirs = sourceSets.test.output.classesDirs classpath = sourceSets.test.runtimeClasspath From 51567f2ad4e717ebf282271cbf62934c14d98a90 Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Fri, 5 Aug 2022 18:14:39 -0700 Subject: [PATCH 2/6] Bump version 2.2.0 (#413) Signed-off-by: vamsi-amazon (cherry picked from commit c91534a67503e6c61ef6e1f53e852bb937f9fc14) Co-authored-by: vamsi-amazon --- .../workflows/dashboards-reports-test-and-build-workflow.yml | 2 +- .github/workflows/draft-release-notes-workflow.yml | 2 +- dashboards-reports/opensearch_dashboards.json | 4 ++-- dashboards-reports/package.json | 2 +- reports-scheduler/build.gradle | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dashboards-reports-test-and-build-workflow.yml b/.github/workflows/dashboards-reports-test-and-build-workflow.yml index 3d5ee688..5bb574fd 100644 --- a/.github/workflows/dashboards-reports-test-and-build-workflow.yml +++ b/.github/workflows/dashboards-reports-test-and-build-workflow.yml @@ -6,7 +6,7 @@ env: PLUGIN_NAME: reportsDashboards ARTIFACT_NAME: reports-dashboards OPENSEARCH_VERSION: 'main' - OPENSEARCH_PLUGIN_VERSION: 2.1.0.0 + OPENSEARCH_PLUGIN_VERSION: 2.2.0.0 jobs: build: diff --git a/.github/workflows/draft-release-notes-workflow.yml b/.github/workflows/draft-release-notes-workflow.yml index bdb4dd7d..126ff0b3 100644 --- a/.github/workflows/draft-release-notes-workflow.yml +++ b/.github/workflows/draft-release-notes-workflow.yml @@ -16,6 +16,6 @@ jobs: with: config-name: draft-release-notes-config.yml tag: (None) - version: 2.1.0.0 + version: 2.2.0.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/dashboards-reports/opensearch_dashboards.json b/dashboards-reports/opensearch_dashboards.json index a1d41172..ee5aeee6 100644 --- a/dashboards-reports/opensearch_dashboards.json +++ b/dashboards-reports/opensearch_dashboards.json @@ -1,7 +1,7 @@ { "id": "reportsDashboards", - "version": "2.1.0.0", - "opensearchDashboardsVersion": "2.1.0", + "version": "2.2.0.0", + "opensearchDashboardsVersion": "2.2.0", "requiredPlugins": ["navigation", "data", "opensearchDashboardsUtils"], "optionalPlugins": ["share"], "server": true, diff --git a/dashboards-reports/package.json b/dashboards-reports/package.json index e3a86862..f78b5601 100644 --- a/dashboards-reports/package.json +++ b/dashboards-reports/package.json @@ -1,6 +1,6 @@ { "name": "reports-dashboards", - "version": "2.1.0.0", + "version": "2.2.0.0", "description": "OpenSearch Dashboards Reports Plugin", "license": "Apache-2.0", "main": "index.ts", diff --git a/reports-scheduler/build.gradle b/reports-scheduler/build.gradle index df277e1d..36fa1984 100644 --- a/reports-scheduler/build.gradle +++ b/reports-scheduler/build.gradle @@ -12,7 +12,7 @@ buildscript { opensearch_group = "org.opensearch" isSnapshot = "true" == System.getProperty("build.snapshot", "true") - opensearch_version = System.getProperty("opensearch.version", "2.1.0-SNAPSHOT") + opensearch_version = System.getProperty("opensearch.version", "2.2.0-SNAPSHOT") buildVersionQualifier = System.getProperty("build.version_qualifier", "") // 2.0.0-rc1-SNAPSHOT -> 2.0.0.0-rc1-SNAPSHOT version_tokens = opensearch_version.tokenize('-') From 1d3980ab2d93a89acd0a5716f575a222389b9e8d Mon Sep 17 00:00:00 2001 From: vamsi-amazon Date: Fri, 5 Aug 2022 18:19:24 -0700 Subject: [PATCH 3/6] Release notes for 2.2.0 Signed-off-by: vamsi-amazon (cherry picked from commit f43f7de6eea93f8749eb08ce6cb248275ef78c85) --- .../opensearch-dashboards-reports.release-notes-2.2.0.0.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 release-notes/opensearch-dashboards-reports.release-notes-2.2.0.0.md diff --git a/release-notes/opensearch-dashboards-reports.release-notes-2.2.0.0.md b/release-notes/opensearch-dashboards-reports.release-notes-2.2.0.0.md new file mode 100644 index 00000000..98ab9da9 --- /dev/null +++ b/release-notes/opensearch-dashboards-reports.release-notes-2.2.0.0.md @@ -0,0 +1,5 @@ +## Version 2.2.0.0 Release Notes +Compatible with OpenSearch 2.2.0.0 + +### Maintenance +* Bump version to 2.0.0 ([#412](https://github.com/opensearch-project/dashboards-reports/pull/412)) \ No newline at end of file From 88084466936d2cebbbbe3db37eb5eb80923af7a8 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Thu, 18 Aug 2022 16:49:29 -0700 Subject: [PATCH 4/6] [2.2] Restrict chromium requests (#431) * Fix regex validation, detect iframe, embed, object tags Signed-off-by: Joshua Li * Disallow redirection to non-localhost urls Signed-off-by: Joshua Li * Disallow connection to non-allowlisted urls Signed-off-by: Joshua Li * Disable JIT Signed-off-by: Joshua Li * Fix workflow Signed-off-by: Joshua Li * Try to fix CI Signed-off-by: Joshua Li * Fix localstorage logic Signed-off-by: Joshua Li Signed-off-by: Joshua Li --- ...boards-reports-test-and-build-workflow.yml | 22 +++--- .../__tests__/visualReportHelper.test.ts | 8 +- .../server/routes/utils/constants.ts | 2 + .../routes/utils/visual_report/style.css | 4 + .../utils/visual_report/visualReportHelper.ts | 75 ++++++++++++++++--- .../utils/__tests__/validationHelper.test.ts | 36 ++++++++- .../server/utils/validationHelper.ts | 2 +- 7 files changed, 125 insertions(+), 24 deletions(-) diff --git a/.github/workflows/dashboards-reports-test-and-build-workflow.yml b/.github/workflows/dashboards-reports-test-and-build-workflow.yml index 5bb574fd..8f4cd6b3 100644 --- a/.github/workflows/dashboards-reports-test-and-build-workflow.yml +++ b/.github/workflows/dashboards-reports-test-and-build-workflow.yml @@ -20,12 +20,12 @@ jobs: with: repository: opensearch-project/Opensearch-Dashboards ref: ${{ env.OPENSEARCH_VERSION }} - path: dashboards-reports/OpenSearch-Dashboards + path: OpenSearch-Dashboards - name: Get node version id: versions_step run: - echo "::set-output name=node_version::$(node -p "(require('./OpenSearch-Dashboards/package.json').engines.node).match(/[.0-9]+/)[0]")" + echo "::set-output name=node_version::$(node -p "(require('../OpenSearch-Dashboards/package.json').engines.node).match(/[.0-9]+/)[0]")" - name: Setup Node uses: actions/setup-node@v1 @@ -35,13 +35,13 @@ jobs: - name: Move Dashboards Reports to Plugins Dir - run: mv dashboards-reports OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} + run: mv dashboards-reports ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} - name: Add Chromium Binary to Reporting for Testing run: | sudo apt update sudo apt install -y libnss3-dev fonts-liberation libfontconfig1 - cd OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} + cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} wget https://github.com/opendistro-for-elasticsearch/kibana-reports/releases/download/chromium-1.12.0.0/chromium-linux-x64.zip unzip chromium-linux-x64.zip rm chromium-linux-x64.zip @@ -51,25 +51,25 @@ jobs: with: timeout_minutes: 30 max_attempts: 3 - command: cd OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}; yarn osd bootstrap + command: cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}; yarn osd bootstrap - name: Test uses: nick-invision/retry@v1 with: timeout_minutes: 30 max_attempts: 3 - command: cd OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}; yarn test --coverage + command: cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}; yarn test --coverage - name: Upload coverage uses: codecov/codecov-action@v1 with: flags: dashboards-reports - directory: OpenSearch-Dashboards/plugins/ + directory: ../OpenSearch-Dashboards/plugins/ token: ${{ secrets.CODECOV_TOKEN }} - name: Build Artifact run: | - cd OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} + cd ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }} yarn build cd build @@ -103,16 +103,16 @@ jobs: uses: actions/upload-artifact@v1 with: name: dashboards-reports-linux-x64 - path: OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip + path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-x64.zip - name: Upload Artifact For Linux arm64 uses: actions/upload-artifact@v1 with: name: dashboards-reports-linux-arm64 - path: OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip + path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-linux-arm64.zip - name: Upload Artifact For Windows uses: actions/upload-artifact@v1 with: name: dashboards-reports-windows-x64 - path: OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip + path: ../OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}/build/${{ env.ARTIFACT_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}-windows-x64.zip diff --git a/dashboards-reports/server/routes/utils/__tests__/visualReportHelper.test.ts b/dashboards-reports/server/routes/utils/__tests__/visualReportHelper.test.ts index 81595979..4bf3cd0b 100644 --- a/dashboards-reports/server/routes/utils/__tests__/visualReportHelper.test.ts +++ b/dashboards-reports/server/routes/utils/__tests__/visualReportHelper.test.ts @@ -55,7 +55,9 @@ describe('test create visual report', () => { reportParams as ReportParamsSchemaType, mockHtmlPath, mockLogger, - mockHeader + mockHeader, + undefined, + /^(data:image|file:\/\/)/ ); expect(fileName).toContain(`${reportParams.report_name}`); expect(fileName).toContain('.png'); @@ -71,7 +73,9 @@ describe('test create visual report', () => { reportParams as ReportParamsSchemaType, mockHtmlPath, mockLogger, - mockHeader + mockHeader, + undefined, + /^(data:image|file:\/\/)/ ); expect(fileName).toContain(`${reportParams.report_name}`); expect(fileName).toContain('.pdf'); diff --git a/dashboards-reports/server/routes/utils/constants.ts b/dashboards-reports/server/routes/utils/constants.ts index dffb0cd1..6af81fd2 100644 --- a/dashboards-reports/server/routes/utils/constants.ts +++ b/dashboards-reports/server/routes/utils/constants.ts @@ -93,6 +93,8 @@ const ipv6Regex = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:) const localhostRegex = /localhost:([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])/g; const iframeRegex = /iframe/g; +export const ALLOWED_HOSTS = /^(0|0.0.0.0|127.0.0.1|localhost|(.*\.)?(opensearch.org|aws.a2z.com))$/; + export const replaceBlockedKeywords = (htmlString: string) => { // replace : htmlString = htmlString.replace(ipv4Regex, BLOCKED_KEYWORD); diff --git a/dashboards-reports/server/routes/utils/visual_report/style.css b/dashboards-reports/server/routes/utils/visual_report/style.css index 58628427..c329e281 100644 --- a/dashboards-reports/server/routes/utils/visual_report/style.css +++ b/dashboards-reports/server/routes/utils/visual_report/style.css @@ -4,6 +4,10 @@ body { padding: 0; } +iframe, embed, object { + display: none !important; +} + /* nice padding + matches Kibana default UI colors you could also set this to inherit if the wrapper gets inserted inside a kibana section. I might also remove the manual text color here as well, potentially */ .reportWrapper { diff --git a/dashboards-reports/server/routes/utils/visual_report/visualReportHelper.ts b/dashboards-reports/server/routes/utils/visual_report/visualReportHelper.ts index d98d1824..21b52c20 100644 --- a/dashboards-reports/server/routes/utils/visual_report/visualReportHelper.ts +++ b/dashboards-reports/server/routes/utils/visual_report/visualReportHelper.ts @@ -14,6 +14,7 @@ import { SELECTOR, CHROMIUM_PATH, SECURITY_CONSTANTS, + ALLOWED_HOSTS, } from '../constants'; import { getFileName } from '../helpers'; import { CreateReportResultType } from '../types'; @@ -27,7 +28,8 @@ export const createVisualReport = async ( queryUrl: string, logger: Logger, extraHeaders: Headers, - timezone?: string + timezone?: string, + validRequestProtocol = /^(data:image)/, ): Promise => { const { core_params, @@ -76,6 +78,8 @@ export const createVisualReport = async ( '--no-zygote', '--single-process', '--font-render-hinting=none', + '--js-flags="--jitless --no-opt"', + '--disable-features=V8OptimizeJavascript', ], executablePath: CHROMIUM_PATH, ignoreHTTPSErrors: true, @@ -84,6 +88,32 @@ export const createVisualReport = async ( }, }); const page = await browser.newPage(); + + await page.setRequestInterception(true); + let localStorageAvailable = true; + page.on('request', (req) => { + // disallow non-allowlisted connections. urls with valid protocols do not need ALLOWED_HOSTS check + if ( + !validRequestProtocol.test(req.url()) && + !ALLOWED_HOSTS.test(new URL(req.url()).hostname) + ) { + if (req.isNavigationRequest() && req.redirectChain().length > 0) { + localStorageAvailable = false; + logger.error( + 'Reporting does not allow redirections to outside of localhost, aborting. URL received: ' + + req.url() + ); + } else { + logger.warn( + 'Disabled connection to non-allowlist domains: ' + req.url() + ); + } + req.abort(); + } else { + req.continue(); + } + }); + page.setDefaultNavigationTimeout(0); page.setDefaultTimeout(100000); // use 100s timeout instead of default 30s // Set extra headers that are needed @@ -93,13 +123,25 @@ export const createVisualReport = async ( logger.info(`original queryUrl ${queryUrl}`); await page.goto(queryUrl, { waitUntil: 'networkidle0' }); // should add to local storage after page.goto, then access the page again - browser must have an url to register local storage item on it - await page.evaluate( - /* istanbul ignore next */ - (key) => { - localStorage.setItem(key, 'false'); - }, - SECURITY_CONSTANTS.TENANT_LOCAL_STORAGE_KEY - ); + try { + await page.evaluate( + /* istanbul ignore next */ + (key) => { + try { + if ( + localStorageAvailable && + typeof localStorage !== 'undefined' && + localStorage !== null + ) { + localStorage.setItem(key, 'false'); + } + } catch (err) {} + }, + SECURITY_CONSTANTS.TENANT_LOCAL_STORAGE_KEY + ); + } catch (err) { + logger.error(err); + } await page.goto(queryUrl, { waitUntil: 'networkidle0' }); logger.info(`page url ${page.url()}`); @@ -162,9 +204,24 @@ export const createVisualReport = async ( // wait for dynamic page content to render await waitForDynamicContent(page); - await addReportStyle(page); await addReportHeader(page, keywordFilteredHeader); await addReportFooter(page, keywordFilteredFooter); + await addReportStyle(page); + + // this causes UT to fail in github CI but works locally + try { + const numDisallowedTags = await page.evaluate( + () => + document.getElementsByTagName('iframe').length + + document.getElementsByTagName('embed').length + + document.getElementsByTagName('object').length + ); + if (numDisallowedTags > 0) { + throw Error('Reporting does not support "iframe", "embed", or "object" tags, aborting'); + } + } catch (error) { + logger.error(error); + } // create pdf or png accordingly if (reportFormat === FORMAT.pdf) { diff --git a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts index bc3ca73d..9bdb4fe0 100644 --- a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts +++ b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts @@ -10,7 +10,7 @@ import { REPORT_TYPE, TRIGGER_TYPE, } from '../../routes/utils/constants'; -import { validateReport, validateReportDefinition } from '../validationHelper'; +import { isValidRelativeUrl, validateReport, validateReportDefinition } from '../validationHelper'; const SAMPLE_SAVED_OBJECT_ID = '3ba638e0-b894-11e8-a6d9-e546fe2bba5f'; const createReportDefinitionInput: ReportDefinitionSchemaType = { @@ -152,7 +152,41 @@ describe('test input validation', () => { `saved object with id dashboard:${SAMPLE_SAVED_OBJECT_ID} does not exist` ); }); + + test('validation against query_url', async () => { + const urls: [string, boolean][] = [ + ['/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=', true], + [ + '/_plugin/kibana/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=', + true, + ], + [ + '/_dashboards/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=', + true, + ], + [ + '/_dashboards/app/dashboards#/edit/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=', + true, + ], + [ + '/app/observability-dashboards?security_tenant=private#/notebooks/NYdlPIIB0-fJ8Bh1nLdW?view=output_only', + true, + ], + [ + '/app/notebooks-dashboards?view=output_only&security_tenant=private#/M4dlPIIB0-fJ8Bh1nLc7?security_tenant=private', + true, + ], + [ + '/_dashboards/app/visualize&security_tenant=/.%2e/.%2e/.%2e/.%2e/_dashboards?#/view/id', + false, + ], + ]; + expect(urls.map((url) => isValidRelativeUrl(url[0]))).toEqual( + urls.map((url) => url[1]) + ); + }); }); + // TODO: merge this with other mock clients used in testing, to create some mock helpers file const mockOpenSearchClient = (mockSavedObjectIds: string[]) => { const client = { diff --git a/dashboards-reports/server/utils/validationHelper.ts b/dashboards-reports/server/utils/validationHelper.ts index aff53d41..2597ee4b 100644 --- a/dashboards-reports/server/utils/validationHelper.ts +++ b/dashboards-reports/server/utils/validationHelper.ts @@ -37,7 +37,7 @@ export const isValidRelativeUrl = (relativeUrl: string) => { export const regexDuration = /^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/; export const regexEmailAddress = /\S+@\S+\.\S+/; export const regexReportName = /^[\w\-\s\(\)\[\]\,\_\-+]+$/; -export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|observability-dashboards|notebooks-dashboards\?view=output_only)([?&]security_tenant=.+|)#\/(notebooks\/|view\/|edit\/)?[^\/]+$/; +export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|observability-dashboards|notebooks-dashboards\?view=output_only(&security_tenant=.+)?)(\?security_tenant=.+)?#\/(notebooks\/|view\/|edit\/)?[^\/]+$/; export const validateReport = async ( client: ILegacyScopedClusterClient, From d19fc7f37ec2c24c57d115a4b9e46a4b30836881 Mon Sep 17 00:00:00 2001 From: opensearch-ci-bot Date: Mon, 22 Aug 2022 21:41:02 +0000 Subject: [PATCH 5/6] Increment version to 2.2.1-SNAPSHOT Signed-off-by: opensearch-ci-bot --- .../workflows/dashboards-reports-test-and-build-workflow.yml | 2 +- .github/workflows/draft-release-notes-workflow.yml | 2 +- dashboards-reports/opensearch_dashboards.json | 4 ++-- dashboards-reports/package.json | 2 +- reports-scheduler/build.gradle | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dashboards-reports-test-and-build-workflow.yml b/.github/workflows/dashboards-reports-test-and-build-workflow.yml index 8f4cd6b3..b49a15bd 100644 --- a/.github/workflows/dashboards-reports-test-and-build-workflow.yml +++ b/.github/workflows/dashboards-reports-test-and-build-workflow.yml @@ -6,7 +6,7 @@ env: PLUGIN_NAME: reportsDashboards ARTIFACT_NAME: reports-dashboards OPENSEARCH_VERSION: 'main' - OPENSEARCH_PLUGIN_VERSION: 2.2.0.0 + OPENSEARCH_PLUGIN_VERSION: 2.2.1.0 jobs: build: diff --git a/.github/workflows/draft-release-notes-workflow.yml b/.github/workflows/draft-release-notes-workflow.yml index 126ff0b3..901c5f63 100644 --- a/.github/workflows/draft-release-notes-workflow.yml +++ b/.github/workflows/draft-release-notes-workflow.yml @@ -16,6 +16,6 @@ jobs: with: config-name: draft-release-notes-config.yml tag: (None) - version: 2.2.0.0 + version: 2.2.1.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/dashboards-reports/opensearch_dashboards.json b/dashboards-reports/opensearch_dashboards.json index ee5aeee6..d9a001ac 100644 --- a/dashboards-reports/opensearch_dashboards.json +++ b/dashboards-reports/opensearch_dashboards.json @@ -1,7 +1,7 @@ { "id": "reportsDashboards", - "version": "2.2.0.0", - "opensearchDashboardsVersion": "2.2.0", + "version": "2.2.1.0", + "opensearchDashboardsVersion": "2.2.1", "requiredPlugins": ["navigation", "data", "opensearchDashboardsUtils"], "optionalPlugins": ["share"], "server": true, diff --git a/dashboards-reports/package.json b/dashboards-reports/package.json index f78b5601..7a0c732c 100644 --- a/dashboards-reports/package.json +++ b/dashboards-reports/package.json @@ -1,6 +1,6 @@ { "name": "reports-dashboards", - "version": "2.2.0.0", + "version": "2.2.1.0", "description": "OpenSearch Dashboards Reports Plugin", "license": "Apache-2.0", "main": "index.ts", diff --git a/reports-scheduler/build.gradle b/reports-scheduler/build.gradle index 36fa1984..5536a069 100644 --- a/reports-scheduler/build.gradle +++ b/reports-scheduler/build.gradle @@ -12,7 +12,7 @@ buildscript { opensearch_group = "org.opensearch" isSnapshot = "true" == System.getProperty("build.snapshot", "true") - opensearch_version = System.getProperty("opensearch.version", "2.2.0-SNAPSHOT") + opensearch_version = System.getProperty("opensearch.version", "2.2.1-SNAPSHOT") buildVersionQualifier = System.getProperty("build.version_qualifier", "") // 2.0.0-rc1-SNAPSHOT -> 2.0.0.0-rc1-SNAPSHOT version_tokens = opensearch_version.tokenize('-') From 383c000b4c18b4ceb5d52d4c9fb2aad9d87f3c90 Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Fri, 9 Sep 2022 15:30:53 -0700 Subject: [PATCH 6/6] Merge pull request #459 from mengweieric/release-notes-2.3.0 Release notes for 2.3.0 (cherry picked from commit b0c564338323056d33fddf30e70a5b0e59b69c6a) --- .../opensearch-dashboards-reports.release-notes-2.3.0.0.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 release-notes/opensearch-dashboards-reports.release-notes-2.3.0.0.md diff --git a/release-notes/opensearch-dashboards-reports.release-notes-2.3.0.0.md b/release-notes/opensearch-dashboards-reports.release-notes-2.3.0.0.md new file mode 100644 index 00000000..9e81873e --- /dev/null +++ b/release-notes/opensearch-dashboards-reports.release-notes-2.3.0.0.md @@ -0,0 +1,5 @@ +## Version 2.3.0.0 Release Notes +Compatible with OpenSearch 2.3.0.0 + +### Maintenance +* Bump version to 2.3.0 ([#454](https://github.com/opensearch-project/dashboards-reports/pull/454)) \ No newline at end of file