From 2c2b9ad49be219a17f0b46da47f840c5c4cb2354 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:58:53 -0500 Subject: [PATCH] Run SAML Multi Auth integration tests in Cypress (#1729) (#1749) Signed-off-by: Craig Perkins Co-authored-by: Darshit Chanpura <35282393+DarshitChanpura@users.noreply.github.com> (cherry picked from commit a36ef1f15fad1ee6092ea32bed631e98b74caea5) Co-authored-by: Craig Perkins --- .github/actions/install-dashboards/action.yml | 2 +- .github/actions/run-cypress-tests/action.yml | 152 +++++++++ .../workflows/cypress-test-multiauth-e2e.yml | 101 ++++++ .github/workflows/cypress-test-saml-e2e.yml | 144 +-------- .github/workflows/integration-test.yml | 2 +- test/cypress/e2e/saml/saml_auth_test.spec.js | 7 +- test/cypress/support/commands.js | 12 + test/jest_integration/saml_multiauth.test.ts | 299 ------------------ 8 files changed, 286 insertions(+), 433 deletions(-) create mode 100644 .github/actions/run-cypress-tests/action.yml create mode 100644 .github/workflows/cypress-test-multiauth-e2e.yml delete mode 100644 test/jest_integration/saml_multiauth.test.ts diff --git a/.github/actions/install-dashboards/action.yml b/.github/actions/install-dashboards/action.yml index f30cf1e69..7834e7196 100644 --- a/.github/actions/install-dashboards/action.yml +++ b/.github/actions/install-dashboards/action.yml @@ -3,7 +3,7 @@ description: 'Installs OpenSearch Dashboard with a Plugin from github, then chec inputs: plugin_name: - description: 'The the name of the plugin to use, such as security-dashboards-plugin' + description: 'The name of the plugin to use, such as security-dashboards-plugin' required: true outputs: diff --git a/.github/actions/run-cypress-tests/action.yml b/.github/actions/run-cypress-tests/action.yml new file mode 100644 index 000000000..b006769da --- /dev/null +++ b/.github/actions/run-cypress-tests/action.yml @@ -0,0 +1,152 @@ +name: Run Cypress Tests +description: 'Runs Cypress tests for the security-dashboards-plugin with opensearch_dashboards.yml and security configuration provided' + +inputs: + security_config_file: + description: 'Name of the security plugin config file' + required: false + dashboards_config_file: + description: 'Name of OpenSearch Dashboards config file' + required: false + yarn_command: + description: 'The yarn command to start running cypress tests' + required: true + +runs: + using: "composite" + steps: + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Set env + run: | + opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version") + plugin_version=$(node -p "require('./package.json').version") + echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV + echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV + shell: bash + + - name: Download security plugin and create setup scripts + uses: ./.github/actions/download-plugin + with: + opensearch-version: ${{ env.OPENSEARCH_VERSION }} + plugin-name: ${{ env.PLUGIN_NAME }} + plugin-version: ${{ env.PLUGIN_VERSION }} + + # Download OpenSearch + - name: Download OpenSearch for Linux + uses: peternied/download-file@v2 + if: ${{ runner.os == 'Linux' }} + with: + url: https://artifacts.opensearch.org/snapshots/core/opensearch/${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/opensearch-min-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64-latest.tar.gz + + # Extract downloaded tar/zip + - name: Extract downloaded tar + if: ${{ runner.os == 'Linux' }} + run: | + tar -xzf opensearch-*.tar.gz + rm -f opensearch-*.tar.gz + shell: bash + + # Install the security plugin + - name: Install Plugin into OpenSearch for Linux + if: ${{ runner.os == 'Linux'}} + run: | + chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin + /bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin install file:$(pwd)/opensearch-security.zip" + shell: bash + + - name: Replace demo configuration + if: ${{ runner.os == 'Linux' }} + run: | + if [ -f ${{ inputs.security_config_file }} ]; then + mv ${{ inputs.security_config_file }} ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch-security/config.yml + fi + shell: bash + + # Run any configuration scripts + - name: Run Setup Script for Linux + if: ${{ runner.os == 'Linux' }} + run: | + echo "running linux setup" + chmod +x ./setup.sh + ./setup.sh + shell: bash + + # OSD bootstrap + - name: Run Dashboard with Security Dashboards Plugin + uses: ./.github/actions/install-dashboards + with: + plugin_name: security-dashboards-plugin + + - name: Replace dashboards configuration + if: ${{ runner.os == 'Linux' }} + run: | + if [ -f ${{ inputs.dashboards_config_file }} ]; then + mv ${{ inputs.dashboards_config_file }} ./OpenSearch-Dashboards/config/opensearch_dashboards.yml + fi + shell: bash + + - name: Run pretest script + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards/plugins/security-dashboards-plugin + yarn pretest:jest_server + shell: bash + + # Run OpenSearch + - name: Run OpenSearch with plugin on Linux + if: ${{ runner.os == 'Linux'}} + run: | + /bin/bash -c "./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch &" + shell: bash + + # Give the OpenSearch process some time to boot up before sending any requires, might need to increase the default time! + - name: Sleep while OpenSearch starts + uses: peternied/action-sleep@v1 + with: + seconds: 30 + + # Verify that the server is operational + - name: Check OpenSearch Running on Linux + if: ${{ runner.os != 'Windows'}} + run: curl https://localhost:9200/_cat/plugins -u 'admin:${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }}' -k -v + shell: bash + + - if: always() + run: cat ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/logs/opensearch.log + shell: bash + + - name: Run OpenSearch Dashboards with provided configuration + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + nohup yarn start --no-base-path --no-watch | tee dashboard.log & + shell: bash + + # Check if OSD is ready with a max timeout of 600 seconds + - name : Check If OpenSearch Dashboards Is Ready + if: ${{ runner.os == 'Linux' }} + run: | + cd ./OpenSearch-Dashboards + echo "Start checking OpenSearch Dashboards." + for i in {1..60}; do + if grep -q "bundles compiled successfully after" "dashboard.log"; then + echo "OpenSearch Dashboards compiled successfully." + break + fi + if [ $i -eq 60 ]; then + echo "Timeout for 600 seconds reached. OpenSearch Dashboards did not finish compiling." + exit 1 + fi + sleep 10 + done + shell: bash + + - name: Run Cypress + run : | + yarn add cypress --save-dev + eval ${{ inputs.yarn_command }} + shell: bash diff --git a/.github/workflows/cypress-test-multiauth-e2e.yml b/.github/workflows/cypress-test-multiauth-e2e.yml new file mode 100644 index 000000000..9d577be1e --- /dev/null +++ b/.github/workflows/cypress-test-multiauth-e2e.yml @@ -0,0 +1,101 @@ +name: Snapshot based E2E SAML multi-auth tests workflow + +on: [ push, pull_request ] + +env: + OPENSEARCH_VERSION: '3.0.0' + CI: 1 + # avoid warnings like "tput: No value for $TERM and no -T specified" + TERM: xterm + PLUGIN_NAME: opensearch-security + OPENSEARCH_INITIAL_ADMIN_PASSWORD: myStrongPassword123! + +jobs: + tests: + name: Run Cypress E2E SAML multi-auth tests + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout Branch + uses: actions/checkout@v3 + + # Add SAML Configuration + - name: Injecting SAML Configuration for Linux + if: ${{ runner.os == 'Linux'}} + run: | + echo "Creating new SAML configuration" + cat << 'EOT' > config_multiauth.yml + --- + _meta: + type: "config" + config_version: 2 + config: + dynamic: + http: + anonymous_auth_enabled: false + authc: + basic_internal_auth_domain: + description: "Authenticate via HTTP Basic against internal users database" + http_enabled: true + transport_enabled: true + order: 0 + http_authenticator: + type: basic + challenge: false + authentication_backend: + type: intern + saml_auth_domain: + http_enabled: true + transport_enabled: false + order: 1 + http_authenticator: + type: saml + challenge: true + config: + idp: + entity_id: urn:example:idp + metadata_url: http://localhost:7000/metadata + sp: + entity_id: https://localhost:9200 + kibana_url: http://localhost:5601 + exchange_key: 6aff3042-1327-4f3d-82f0-40a157ac4464 + authentication_backend: + type: noop + EOT + echo "THIS IS THE SECURITY CONFIG FILE: " + cat config_multiauth.yml + + # Configure the Dashboard for SAML setup + - name: Configure OpenSearch Dashboards with multi-auth configuration including SAML + if: ${{ runner.os == 'Linux' }} + run: | + cat << 'EOT' > opensearch_dashboards_multiauth.yml + server.host: "localhost" + opensearch.hosts: ["https://localhost:9200"] + opensearch.ssl.verificationMode: none + opensearch.username: "kibanaserver" + opensearch.password: "kibanaserver" + opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] + opensearch_security.multitenancy.enabled: true + opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] + opensearch_security.readonly_mode.roles: ["kibana_read_only"] + opensearch_security.cookie.secure: false + server.xsrf.allowlist: ["/_plugins/_security/api/authtoken", "/_opendistro/_security/api/authtoken", "/_opendistro/_security/saml/acs", "/_opendistro/_security/saml/acs/idpinitiated", "/_opendistro/_security/saml/logout"] + opensearch_security.auth.type: ["basicauth","saml"] + opensearch_security.auth.multiple_auth_enabled: true + opensearch_security.auth.anonymous_auth_enabled: false + home.disableWelcomeScreen: true + EOT + echo 'HERE IS THE DASHBOARD CONFIG FILE: ' + cat opensearch_dashboards_multiauth.yml + + - name: Run Cypress Tests + uses: ./.github/actions/run-cypress-tests + with: + security_config_file: config_multiauth.yml + dashboards_config_file: opensearch_dashboards_multiauth.yml + yarn_command: 'yarn cypress:run --browser chrome --headless --env loginMethod=saml_multiauth --spec "test/cypress/e2e/saml/*.js"' diff --git a/.github/workflows/cypress-test-saml-e2e.yml b/.github/workflows/cypress-test-saml-e2e.yml index ffa0df221..00743de4d 100644 --- a/.github/workflows/cypress-test-saml-e2e.yml +++ b/.github/workflows/cypress-test-saml-e2e.yml @@ -1,7 +1,7 @@ name: Snapshot based E2E SAML tests workflow -on: - pull_request: - branches: [ '**' ] + +on: [ push, pull_request ] + env: OPENSEARCH_VERSION: '2.12.0' CI: 1 @@ -20,67 +20,15 @@ jobs: runs-on: ${{ matrix.os }} steps: - - name: Set up JDK - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Checkout Branch uses: actions/checkout@v3 - - - name: Set env - run: | - opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version") - plugin_version=$(node -p "require('./package.json').version") - echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV - echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV - shell: bash - - - name: Download security plugin and create setup scripts - uses: ./.github/actions/download-plugin - with: - opensearch-version: ${{ env.OPENSEARCH_VERSION }} - plugin-name: ${{ env.PLUGIN_NAME }} - plugin-version: ${{ env.PLUGIN_VERSION }} - - # Download OpenSearch - - name: Download OpenSearch for Linux - uses: peternied/download-file@v2 - if: ${{ runner.os == 'Linux' }} - with: - url: https://artifacts.opensearch.org/snapshots/core/opensearch/${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/opensearch-min-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64-latest.tar.gz - - # Extract downloaded tar/zip - - name: Extract downloaded tar - if: ${{ runner.os == 'Linux' }} - run: | - tar -xzf opensearch-*.tar.gz - rm -f opensearch-*.tar.gz - shell: bash - - # TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT - - name: Write password to initialAdminPassword location - if: ${{ runner.os == 'Linux'}} - run: - echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt - shell: bash - - # Install the security plugin - - name: Install Plugin into OpenSearch for Linux - if: ${{ runner.os == 'Linux'}} - run: | - chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin - /bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin install file:$(pwd)/opensearch-security.zip" - shell: bash # Add SAML Configuration - - name: Injecting SAML Configuration for Linux + - name: Create SAML Configuration for Linux if: ${{ runner.os == 'Linux'}} run: | echo "Creating new SAML configuration" - cd ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch-security/ - rm -rf config.yml - cat << 'EOT' > config.yml + cat << 'EOT' > config_saml.yml --- _meta: type: "config" @@ -119,60 +67,13 @@ jobs: type: noop EOT echo "THIS IS THE SECURITY CONFIG FILE: " - cat config.yml - - # Run any configuration scripts - - name: Run Setup Script for Linux - if: ${{ runner.os == 'Linux' }} - run: | - echo "running linux setup" - chmod +x ./setup.sh - ./setup.sh - shell: bash - - # Run OpenSearch - - name: Run OpenSearch with plugin on Linux - if: ${{ runner.os == 'Linux'}} - run: | - /bin/bash -c "./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch &" - shell: bash - - # Give the OpenSearch process some time to boot up before sending any requires, might need to increase the default time! - - name: Sleep while OpenSearch starts - uses: peternied/action-sleep@v1 - with: - seconds: 30 - - # Verify that the server is operational - - name: Check OpenSearch Running on Linux - if: ${{ runner.os != 'Windows'}} - run: curl https://localhost:9200/_cat/plugins -u 'admin:${{ env.OPENSEARCH_INITIAL_ADMIN_PASSWORD }}' -k -v - shell: bash - - - if: always() - run: cat ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/logs/opensearch.log - shell: bash - - # OSD bootstrap - - name: Run Dashboard with Security Dashboards Plugin - uses: ./.github/actions/install-dashboards - with: - plugin_name: security-dashboards-plugin - - # Setup and Run SAML Idp - - name: Get and run SAML Idp on Linux - if: ${{ runner.os == 'Linux' }} - run: | - cd ./OpenSearch-Dashboards/plugins/security-dashboards-plugin - yarn pretest:jest_server + cat config_saml.yml # Configure the Dashboard for SAML setup - name: Configure and Run OpenSearch Dashboards with SAML Configuration if: ${{ runner.os == 'Linux' }} run: | - cd ./OpenSearch-Dashboards - rm -rf ./config/opensearch_dashboards.yml - cat << 'EOT' > ./config/opensearch_dashboards.yml + cat << 'EOT' > opensearch_dashboards_saml.yml server.host: "localhost" opensearch.hosts: ["https://localhost:9200"] opensearch.ssl.verificationMode: none @@ -190,28 +91,11 @@ jobs: home.disableWelcomeScreen: true EOT echo 'HERE IS THE DASHBOARD CONFIG FILE: ' - cat ./config/opensearch_dashboards.yml - nohup yarn start --no-base-path --no-watch | tee dashboard.log & + cat opensearch_dashboards_saml.yml - # Check if OSD is ready with a max timeout of 600 seconds - - name : Check If OpenSearch Dashboards Is Ready - if: ${{ runner.os == 'Linux' }} - run: | - cd ./OpenSearch-Dashboards - echo "Start checking OpenSearch Dashboards." - for i in {1..60}; do - if grep -q "bundles compiled successfully after" "dashboard.log"; then - echo "OpenSearch Dashboards compiled successfully." - break - fi - if [ $i -eq 60 ]; then - echo "Timeout for 600 seconds reached. OpenSearch Dashboards did not finish compiling." - exit 1 - fi - sleep 10 - done - - - name: Run Cypress - run : | - yarn add cypress --save-dev - yarn cypress:run --browser chrome --headless --spec 'test/cypress/e2e/saml/*.js' + - name: Run Cypress Tests + uses: ./.github/actions/run-cypress-tests + with: + security_config_file: config_saml.yml + dashboards_config_file: opensearch_dashboards_saml.yml + yarn_command: 'yarn cypress:run --browser chrome --headless --spec "test/cypress/e2e/saml/*.js"' diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index ce187826d..803af314c 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -100,5 +100,5 @@ jobs: run: | echo "check if opensearch is ready" curl -XGET https://localhost:9200 -u 'admin:admin' -k - node .\test\run_jest_tests.js --runInBand --detectOpenHandles --forceExit --config .\test\jest.config.server.js --testPathIgnorePatterns saml_auth.test.ts --testPathIgnorePatterns saml_multiauth.test.ts + node .\test\run_jest_tests.js --runInBand --detectOpenHandles --forceExit --config .\test\jest.config.server.js working-directory: ${{ steps.install-dashboards.outputs.plugin-directory }} diff --git a/test/cypress/e2e/saml/saml_auth_test.spec.js b/test/cypress/e2e/saml/saml_auth_test.spec.js index 925256ee8..733f65e52 100644 --- a/test/cypress/e2e/saml/saml_auth_test.spec.js +++ b/test/cypress/e2e/saml/saml_auth_test.spec.js @@ -41,8 +41,11 @@ afterEach(() => { describe('Log in via SAML', () => { const samlLogin = () => { - cy.get('input[id=userName]').should('be.visible'); - cy.get('button[id=btn-sign-in]').should('be.visible').click(); + if (Cypress.env('loginMethod') === 'saml_multiauth') { + cy.loginWithSamlMultiauth(); + } else { + cy.loginWithSaml(); + } }; it('Login to app/opensearch_dashboards_overview#/ when SAML is enabled', () => { diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index ade3591cf..6a258af67 100644 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -78,3 +78,15 @@ Cypress.Commands.add('createRoleMapping', (roleID, rolemappingJson) => { expect(response.status).to.eq(200); }); }); + +Cypress.Commands.add('loginWithSaml', () => { + cy.get('input[id=userName]').should('be.visible'); + cy.get('button[id=btn-sign-in]').should('be.visible').click(); +}); + +Cypress.Commands.add('loginWithSamlMultiauth', () => { + cy.get('a[aria-label="saml_login_button"]').should('be.visible'); + cy.get('a[aria-label="saml_login_button"]').should('be.visible').click(); + cy.get('input[id=userName]').should('be.visible'); + cy.get('button[id=btn-sign-in]').should('be.visible').click(); +}); diff --git a/test/jest_integration/saml_multiauth.test.ts b/test/jest_integration/saml_multiauth.test.ts deleted file mode 100644 index cd41a52d4..000000000 --- a/test/jest_integration/saml_multiauth.test.ts +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -import * as osdTestServer from '../../../../src/core/test_helpers/osd_server'; -import { Root } from '../../../../src/core/server/root'; -import { resolve } from 'path'; -import { describe, expect, it, beforeAll, afterAll } from '@jest/globals'; -import { - ADMIN_CREDENTIALS, - OPENSEARCH_DASHBOARDS_SERVER_USER, - OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, -} from '../constant'; -import wreck from '@hapi/wreck'; -import { Builder, By, until } from 'selenium-webdriver'; -import { Options } from 'selenium-webdriver/firefox'; -import { AuthType } from '../../common'; - -describe('start OpenSearch Dashboards server', () => { - let root: Root; - let config; - - // XPath Constants - const signInBtnXPath = '//*[@id="btn-sign-in"]'; - const samlLogInButton = '//a[@aria-label="saml_login_button"]'; - // Browser Settings - const browser = 'firefox'; - const options = new Options().headless(); - - beforeAll(async () => { - root = osdTestServer.createRootWithSettings( - { - plugins: { - scanDirs: [resolve(__dirname, '../..')], - }, - home: { disableWelcomeScreen: true }, - server: { - host: 'localhost', - port: 5601, - xsrf: { - whitelist: [ - '/_opendistro/_security/saml/acs/idpinitiated', - '/_opendistro/_security/saml/acs', - '/_opendistro/_security/saml/logout', - ], - }, - }, - logging: { - silent: true, - verbose: false, - }, - opensearch: { - hosts: ['https://localhost:9200'], - ignoreVersionMismatch: true, - ssl: { verificationMode: 'none' }, - username: OPENSEARCH_DASHBOARDS_SERVER_USER, - password: OPENSEARCH_DASHBOARDS_SERVER_PASSWORD, - requestHeadersWhitelist: ['authorization', 'securitytenant'], - }, - opensearch_security: { - auth: { - anonymous_auth_enabled: false, - type: [AuthType.BASIC, AuthType.SAML], - multiple_auth_enabled: true, - }, - multitenancy: { - enabled: true, - tenants: { - enable_global: true, - enable_private: true, - preferred: ['Private', 'Global'], - }, - }, - }, - }, - { - // to make ignoreVersionMismatch setting work - // can be removed when we have corresponding ES version - dev: true, - } - ); - - console.log('Starting OpenSearchDashboards server..'); - await root.setup(); - await root.start(); - - await wreck.patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { - payload: [ - { - op: 'add', - path: '/users', - value: ['saml.jackson@example.com'], - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }); - console.log('Starting to Download Flights Sample Data'); - await wreck.post('http://localhost:5601/api/sample_data/flights', { - payload: {}, - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - security_tenant: 'global', - }, - }); - console.log('Downloaded Sample Data'); - const getConfigResponse = await wreck.get( - 'https://localhost:9200/_plugins/_security/api/securityconfig', - { - rejectUnauthorized: false, - headers: { - authorization: ADMIN_CREDENTIALS, - }, - } - ); - const responseBody = (getConfigResponse.payload as Buffer).toString(); - config = JSON.parse(responseBody).config; - const samlConfig = { - http_enabled: true, - transport_enabled: false, - order: 5, - http_authenticator: { - challenge: true, - type: AuthType.SAML, - config: { - idp: { - metadata_url: 'http://localhost:7000/metadata', - entity_id: 'urn:example:idp', - }, - sp: { - entity_id: 'https://localhost:9200', - }, - kibana_url: 'http://localhost:5601', - exchange_key: '6aff3042-1327-4f3d-82f0-40a157ac4464', - }, - }, - authentication_backend: { - type: 'noop', - config: {}, - }, - }; - try { - config.dynamic!.authc!.saml_auth_domain = samlConfig; - config.dynamic!.authc!.basic_internal_auth_domain.http_authenticator.challenge = false; - config.dynamic!.http!.anonymous_auth_enabled = false; - await wreck.put('https://localhost:9200/_plugins/_security/api/securityconfig/config', { - payload: config, - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }); - } catch (error) { - console.log('Got an error while updating security config!!', error.stack); - fail(error); - } - }); - - afterAll(async () => { - console.log('Remove the Sample Data'); - await wreck - .delete('http://localhost:5601/api/sample_data/flights', { - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - console.log('Remove the Role Mapping'); - await wreck - .patch('https://localhost:9200/_plugins/_security/api/rolesmapping/all_access', { - payload: [ - { - op: 'remove', - path: '/users', - users: ['saml.jackson@example.com'], - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - console.log('Remove the Security Config'); - await wreck - .patch('https://localhost:9200/_plugins/_security/api/securityconfig', { - payload: [ - { - op: 'remove', - path: '/config/dynamic/authc/saml_auth_domain', - }, - ], - rejectUnauthorized: false, - headers: { - 'Content-Type': 'application/json', - authorization: ADMIN_CREDENTIALS, - }, - }) - .then((value) => { - Promise.resolve(value); - }) - .catch((value) => { - Promise.resolve(value); - }); - // shutdown OpenSearchDashboards server - await root.shutdown(); - }); - - it('Login to Dashboards and resume from nextUrl', async () => { - const urlWithHash = `http://localhost:5601/app/security-dashboards-plugin#/getstarted`; - const loginUrlWithNextUrl = `http://localhost:5601/app/login?nextUrl=%2Fapp%2Fsecurity-dashboards-plugin#/getstarted`; - const driver = getDriver(browser, options).build(); - await driver.manage().deleteAllCookies(); - await driver.get(loginUrlWithNextUrl); - await driver.wait(until.elementsLocated(By.xpath(samlLogInButton)), 20000); - await driver.findElement(By.xpath(samlLogInButton)).click(); - await driver.wait(until.elementsLocated(By.xpath(signInBtnXPath)), 20000); - await driver.findElement(By.xpath(signInBtnXPath)).click(); - // TODO Use a better XPath. - await driver.wait( - until.elementsLocated(By.xpath('/html/body/div[1]/div/header/div/div[2]')), - 20000 - ); - const windowHash = await driver.getCurrentUrl(); - console.log('windowHash: ' + windowHash); - expect(windowHash).toEqual(urlWithHash); - const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(3); - await driver.manage().deleteAllCookies(); - await driver.quit(); - }); - - it('Login to Dashboards without nextUrl', async () => { - const urlWithoutHash = `http://localhost:5601/app/home#/`; - const loginUrl = `http://localhost:5601/app/login`; - const driver = getDriver(browser, options).build(); - await driver.manage().deleteAllCookies(); - await driver.get(loginUrl); - await driver.wait(until.elementsLocated(By.xpath(samlLogInButton)), 20000); - await driver.findElement(By.xpath(samlLogInButton)).click(); - await driver.wait(until.elementsLocated(By.xpath(signInBtnXPath)), 20000); - await driver.findElement(By.xpath(signInBtnXPath)).click(); - // TODO Use a better XPath. - await driver.wait( - until.elementsLocated(By.xpath('/html/body/div[1]/div/header/div/div[2]')), - 20000 - ); - await driver.wait(until.elementsLocated(By.css('img[data-test-subj="defaultLogo"]')), 20000); - await driver.wait( - until.elementsLocated(By.css('section[aria-labelledby="homDataAdd__title"]')), - 20000 - ); - await driver.wait( - until.elementsLocated(By.css('section[aria-labelledby="homDataManage__title"]')), - 20000 - ); - const windowHash = await driver.getCurrentUrl(); - console.log('windowHash: ' + windowHash); - expect(windowHash).toEqual(urlWithoutHash); - const cookie = await driver.manage().getCookies(); - expect(cookie.length).toEqual(3); - await driver.manage().deleteAllCookies(); - await driver.quit(); - }); -}); - -function getDriver(browser: string, options: Options) { - return new Builder().forBrowser(browser).setFirefoxOptions(options); -}