diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternGlobalTenantHeader.json b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternGlobalTenantHeader.json new file mode 100644 index 000000000..e6d6f36ef --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternGlobalTenantHeader.json @@ -0,0 +1,3 @@ +{ + "securitytenant": ["global"] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternPrivateTenantHeader.json b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternPrivateTenantHeader.json new file mode 100644 index 000000000..cb9bc7c6e --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternPrivateTenantHeader.json @@ -0,0 +1,3 @@ +{ + "securitytenant": ["private"] +} diff --git a/cypress/integration/plugins/security-dashboards-plugin/default_tenant.js b/cypress/integration/plugins/security-dashboards-plugin/default_tenant.js new file mode 100644 index 000000000..5a8162a74 --- /dev/null +++ b/cypress/integration/plugins/security-dashboards-plugin/default_tenant.js @@ -0,0 +1,33 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { SAVED_OBJECTS_PATH } from '../../../utils/dashboards/constants'; + +import { CURRENT_TENANT } from '../../../utils/commands'; +import tenantDescription from '../../../fixtures/plugins/security-dashboards-plugin/tenants/testTenant'; + +const tenantName = 'test'; + +if (Cypress.env('SECURITY_ENABLED')) { + describe('Multi Tenancy Default Tenant Tests: ', () => { + before(() => { + cy.server(); + cy.createTenant(tenantName, tenantDescription); + cy.changeDefaultTenant({ + multitenancy_enabled: true, + private_tenant_enabled: true, + default_tenant: tenantName, + }); + }); + it('Test Changed Default Tenant ', () => { + CURRENT_TENANT.newTenant = null; + cy.visit(SAVED_OBJECTS_PATH); + cy.waitForLoader(); + cy.get('#user-icon-btn').click(); + cy.wait(1000); + cy.get('#tenantName').contains(tenantName); + }); + }); +} diff --git a/cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js b/cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js new file mode 100644 index 000000000..988b84412 --- /dev/null +++ b/cypress/integration/plugins/security-dashboards-plugin/multi_tenancy.js @@ -0,0 +1,150 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + SAVED_OBJECTS_PATH, + TENANTS_MANAGE_PATH, +} from '../../../utils/dashboards/constants'; + +import { CURRENT_TENANT } from '../../../utils/commands'; + +import indexPatternPrivateTenantHeaderSetUp from '../../../fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternPrivateTenantHeader'; +import indexPatternGlobalTenantHeaderSetUp from '../../../fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternGlobalTenantHeader'; +import tenantDescription from '../../../fixtures/plugins/security-dashboards-plugin/tenants/testTenant.json'; + +const tenantName = 'test'; + +if (Cypress.env('SECURITY_ENABLED')) { + describe('Multi Tenancy Tests: ', () => { + before(() => { + cy.server(); + cy.createTenant(tenantName, tenantDescription); + cy.createIndexPattern( + 'index-pattern1', + { + title: 's*', + timeFieldName: 'timestamp', + }, + indexPatternGlobalTenantHeaderSetUp + ); + + cy.createIndexPattern( + 'index-pattern2', + { + title: 'se*', + timeFieldName: 'timestamp', + }, + indexPatternPrivateTenantHeaderSetUp + ); + }); + it('Test 1 Disable Multi Tenancy ', () => { + CURRENT_TENANT.newTenant = 'private'; + + // Load into Private Tenant initially and check if index Pattern matches to the one saved in Private tenant. + cy.visit(SAVED_OBJECTS_PATH); + cy.waitForLoader(); + cy.contains('a', 'Saved objects'); + cy.contains('a', 'se*'); + + // Switch tenants button should exist when multi-tenancy is enabled. + cy.get('#user-icon-btn').click(); + cy.contains('button', 'Switch tenants').should('exist'); + + // Disable multi-tenancy. + cy.visit(TENANTS_MANAGE_PATH); + cy.waitForLoader(); + + cy.contains('button', 'Configure').click(); + cy.waitForLoader(); + cy.get('#EnableMultitenancyCheckBox').uncheck({ force: true }); + cy.contains('button', 'Save Changes').click(); + + cy.get('#tenancyChangeCheckbox').check({ force: true }); + cy.contains('button', 'Apply changes').click(); + + cy.reload(); + cy.waitForLoader(); + + // Switch tenants button should not exist when multi-tenancy is disabled. + cy.get('#user-icon-btn').click(); + cy.contains('button', 'Switch tenants').should('not.exist'); + + //Tenancy disbaled warning should show on manage page. + cy.contains('Tenancy is disabled').should('exist'); + + // Saved index pattern should only have the ones saved in Global tenant. + cy.visit(SAVED_OBJECTS_PATH); + cy.waitForLoader(); + cy.contains('a', 'Saved objects'); + cy.contains('a', 's*'); + + // Enable Multi-tenancy before closing test. + cy.visit(TENANTS_MANAGE_PATH); + cy.waitForLoader(); + cy.contains('button', 'Configure').click(); + cy.waitForLoader(); + cy.get('#EnableMultitenancyCheckBox').check({ force: true }); + cy.contains('button', 'Save Changes').click(); + cy.get('#tenancyChangeCheckbox').check({ force: true }); + cy.contains('button', 'Apply changes').click(); + cy.reload(); + cy.waitForLoader(); + }); + it('Test 2 Disable Private Tenancy ', () => { + CURRENT_TENANT.newTenant = 'private'; + + // Load into Private Tenant initially and check if index Pattern matches to the one saved in Private tenant. + cy.visit(SAVED_OBJECTS_PATH); + cy.waitForLoader(); + cy.contains('a', 'Saved objects'); + cy.contains('a', 'se*'); + + // Check if switching to private tenant is enabled. + cy.get('#user-icon-btn').click(); + cy.contains('button', 'Switch tenants').click(); + cy.get('#private').should('be.enabled'); + cy.contains('button', 'Cancel').click(); + + // Disable private tenant. + cy.visit(TENANTS_MANAGE_PATH); + cy.waitForLoader(); + + cy.contains('button', 'Configure').click(); + cy.waitForLoader(); + cy.get('#EnablePrivateTenantCheckBox').uncheck({ force: true }); + cy.contains('button', 'Save Changes').click(); + + cy.get('#privateTenancyChangeCheckbox').check({ force: true }); + cy.contains('button', 'Apply changes').click(); + + cy.reload(); + cy.waitForLoader(); + + // Check if switching to private tenant is enabled. + cy.get('#user-icon-btn').click(); + cy.contains('button', 'Switch tenants').click(); + cy.get('#private').should('be.disabled'); + cy.contains('button', 'Cancel').click(); + + // Saved index pattern should only have the ones saved in Global tenant. + cy.visit(SAVED_OBJECTS_PATH); + cy.waitForLoader(); + cy.contains('a', 'Saved objects'); + cy.contains('a', 's*'); + + // Enable private tenant before exiting test. + cy.visit(TENANTS_MANAGE_PATH); + cy.waitForLoader(); + cy.contains('button', 'Configure').click(); + cy.waitForLoader(); + cy.get('#EnablePrivateTenantCheckBox').check({ force: true }); + cy.contains('button', 'Save Changes').click(); + cy.get('#privateTenancyChangeCheckbox').check({ force: true }); + cy.contains('button', 'Apply changes').click(); + cy.reload(); + cy.waitForLoader(); + }); + }); +} diff --git a/cypress/utils/commands.js b/cypress/utils/commands.js index 241912733..bc9cf9546 100644 --- a/cypress/utils/commands.js +++ b/cypress/utils/commands.js @@ -299,6 +299,22 @@ Cypress.Commands.add('createIndexPattern', (id, attributes, header = {}) => { }); }); +Cypress.Commands.add('changeDefaultTenant', (attributes, header = {}) => { + const url = + Cypress.env('openSearchUrl') + '/_plugins/_security/api/tenancy/config'; + + cy.request({ + method: 'PUT', + url, + headers: { + 'content-type': 'application/json;charset=UTF-8', + 'osd-xsrf': true, + ...header, + }, + body: JSON.stringify(attributes), + }); +}); + Cypress.Commands.add('deleteIndexPattern', (id, options = {}) => cy.deleteSavedObject('index-pattern', id, options) ); diff --git a/cypress/utils/dashboards/constants.js b/cypress/utils/dashboards/constants.js index 6f1382869..7b7b5b400 100644 --- a/cypress/utils/dashboards/constants.js +++ b/cypress/utils/dashboards/constants.js @@ -7,6 +7,8 @@ import { BASE_PATH } from '../base_constants'; // STACK MANAGEMENT PATH export const STACK_MANAGEMENT_PATH = BASE_PATH + '/app/management'; +export const TENANTS_MANAGE_PATH = + BASE_PATH + '/app/security-dashboards-plugin#/tenants'; export const INDEX_PATTERN_PATH = STACK_MANAGEMENT_PATH + '/opensearch-dashboards/indexPatterns'; diff --git a/cypress/utils/index.d.ts b/cypress/utils/index.d.ts index daad594d4..4f436c3e0 100644 --- a/cypress/utils/index.d.ts +++ b/cypress/utils/index.d.ts @@ -87,6 +87,22 @@ declare namespace Cypress { header: string, ): Chainable; + + /** + * Changes the Default tenant for the domain. + * @example + * cy.changeDefaultTenant({multitenancy_enabled: true, private_tenant_enabled: true, default_tenant: tenantName, }); + */ + changeDefaultTenant( + attributes: { + multitenancy_enabled: boolean, + private_tenant_enabled: boolean, + default_tenant: string; + }, + // header: string, + // default_tenant: string + ): Chainable; + /** * Delete an index pattern * @example