diff --git a/cypress/integration/plugins/security-dashboards-plugin/readonly.js b/cypress/integration/plugins/security-dashboards-plugin/readonly.js new file mode 100644 index 000000000..6f7f8730d --- /dev/null +++ b/cypress/integration/plugins/security-dashboards-plugin/readonly.js @@ -0,0 +1,95 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import roleWithoutTestJson from '../../../fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest'; +import { BASE_PATH } from '../../../utils/base_constants'; +import { ADMIN_AUTH, CURRENT_TENANT } from '../../../utils/commands'; +import { switchTenantTo } from './switch_tenant'; + +const TEST_CONFIG = { + role: { + name: 'test_readonly_role', + json: Object.assign({}, roleWithoutTestJson, { + tenant_permissions: [ + { + tenant_patterns: ['test_readonly_tenant'], + allowed_actions: ['kibana_all_read'], + }, + ], + }), + }, + tenant: { + name: 'test_readonly_tenant', + description: 'Testing read-only tenant mode', + }, + user: { + username: 'test_readonly_user', + password: 'testUserPassword123', + }, +}; + +if (Cypress.env('SECURITY_ENABLED')) { + describe('Read Only mode', () => { + before(() => { + cy.server(); + + cy.createTenant(TEST_CONFIG.tenant.name, { + description: TEST_CONFIG.tenant.description, + }); + + cy.createInternalUser(TEST_CONFIG.user.username, { + password: TEST_CONFIG.user.password, + }); + + cy.createRole(TEST_CONFIG.role.name, TEST_CONFIG.role.json); + + cy.createRoleMapping(TEST_CONFIG.role.name, { + users: [ADMIN_AUTH.username, TEST_CONFIG.user.username], + }); + + /* Add sample data to testing tenant */ + CURRENT_TENANT.newTenant = TEST_CONFIG.tenant.name; + cy.visit(BASE_PATH, { + onBeforeLoad(window) { + window.sessionStorage.setItem( + 'opendistro::security::tenant::show_popup', + false + ); + window.localStorage.setItem( + 'opendistro::security::tenant::saved', + `"${TEST_CONFIG.tenant.name}"` + ); + window.localStorage.setItem('home:newThemeModal:show', false); + }, + }); + cy.waitForLoader(); + switchTenantTo(TEST_CONFIG.tenant.name); + cy.loadSampleData('logs'); + }); + + it('should be able to modify the dashboard as admin', () => { + cy.visit(BASE_PATH); + cy.waitForLoader(); + + cy.visitDashboard('[Logs] Web Traffic'); + + cy.getElementByTestId('dashboardClone').should('exist'); + cy.getElementByTestId('dashboardEditMode').should('exist'); + }); + + it('should not be able to modify the dashboard when is performing as a custom readonly tenant', () => { + ADMIN_AUTH.newUser = TEST_CONFIG.user.username; + ADMIN_AUTH.newPassword = TEST_CONFIG.user.password; + + cy.visit(BASE_PATH); + cy.waitForLoader(); + + cy.visitDashboard('[Logs] Web Traffic'); + + cy.getElementByTestId('dashboardClone').should('not.exist'); + cy.getElementByTestId('dashboardEditMode').should('not.exist'); + }); + }); +} diff --git a/cypress/integration/plugins/security-dashboards-plugin/switch_tenant.js b/cypress/integration/plugins/security-dashboards-plugin/switch_tenant.js new file mode 100644 index 000000000..8deda4a28 --- /dev/null +++ b/cypress/integration/plugins/security-dashboards-plugin/switch_tenant.js @@ -0,0 +1,52 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export function switchTenantTo(newTenant) { + cy.getElementByTestId('account-popover').click(); + cy.intercept({ + method: 'GET', + url: '/api/v1/auth/dashboardsinfo', + }).as('waitForDashboardsInfo'); + + cy.intercept({ + method: 'GET', + url: '/api/v1/configuration/account', + }).as('waitForAccountInfo'); + + cy.getElementByTestId('switch-tenants').click(); + + if (['global', 'private'].includes(newTenant)) { + cy.get('[id="' + newTenant + '"][name="tenantSwitchRadios"]').should( + 'be.enabled' + ); + cy.get('.euiRadio__label[for="' + newTenant + '"]').click(); + } else { + cy.get('[id="custom"][name="tenantSwitchRadios"]').should('be.enabled'); + + cy.getElementByTestId('tenant-switch-modal') + .find('[data-test-subj="comboBoxInput"]') + .click(); + + // typo in data-test-subj + cy.getElementByTestId('comboBoxOptionsList ') + .find(`[title="${newTenant}"]`) + .click(); + } + + cy.intercept({ + method: 'POST', + url: '/api/v1/multitenancy/tenant', + }).as('waitForUpdatingTenants'); + cy.getElementByTestId('tenant-switch-modal') + .find('[data-test-subj="confirm"]') + .click(); + + cy.wait('@waitForUpdatingTenants'); + + // Make sure dashboards has really reloaded. + // @waitForReloadAfterTenantSwitch should be triggered twice + cy.wait('@waitForDashboardsInfo'); + cy.wait('@waitForDashboardsInfo'); +} diff --git a/cypress/utils/commands.js b/cypress/utils/commands.js index 9a2cfba20..7b6beb8ce 100644 --- a/cypress/utils/commands.js +++ b/cypress/utils/commands.js @@ -493,3 +493,12 @@ Cypress.Commands.add( }); } ); + +// type: logs, ecommerce, flights +Cypress.Commands.add('loadSampleData', (type) => { + cy.request({ + method: 'POST', + headers: { 'osd-xsrf': 'opensearch-dashboards' }, + url: `${BASE_PATH}/api/sample_data/${type}`, + }); +});