From d60a9c4566da161aa83fadffa334539fcd189c09 Mon Sep 17 00:00:00 2001 From: Ryan Liang <109499885+RyanL1997@users.noreply.github.com> Date: Thu, 20 Oct 2022 22:21:38 -0400 Subject: [PATCH] Add test for aggregation view feature (#334) (cherry picked from commit 4ebfa3d995d8c984bf7508790ef965395b6196d3) --- cypress.json | 3 +- .../indexPatternTenantHeader.json | 3 + .../roles/roleWithTest.json | 24 ++++ .../roles/roleWithoutTest.json | 20 ++++ .../rolesmapping/kibanauserRoleMapping.json | 4 + .../rolesmapping/roleWithTestMapping.json | 3 + .../rolesmapping/roleWithoutTestMapping.json | 3 + .../tenants/testTenant.json | 3 + .../users/testUser.json | 3 + .../aggregation_view.js | 108 ++++++++++++++++++ cypress/support/index.js | 1 + cypress/utils/commands.js | 20 +++- cypress/utils/constants.js | 1 + cypress/utils/dashboards/constants.js | 8 ++ cypress/utils/index.d.ts | 5 +- .../security-dashboards-plugin/commands.js | 48 ++++++++ .../security-dashboards-plugin/constants.js | 19 +++ .../security-dashboards-plugin/index.d.ts | 52 +++++++++ cypress/utils/plugins/security/constants.js | 1 + package.json | 1 + 20 files changed, 324 insertions(+), 6 deletions(-) create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternTenantHeader.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithTest.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/kibanauserRoleMapping.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithTestMapping.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithoutTestMapping.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/tenants/testTenant.json create mode 100644 cypress/fixtures/plugins/security-dashboards-plugin/users/testUser.json create mode 100644 cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js create mode 100644 cypress/utils/plugins/security-dashboards-plugin/commands.js create mode 100644 cypress/utils/plugins/security-dashboards-plugin/constants.js create mode 100644 cypress/utils/plugins/security-dashboards-plugin/index.d.ts diff --git a/cypress.json b/cypress.json index 7698b3a30..42419584d 100644 --- a/cypress.json +++ b/cypress.json @@ -12,6 +12,7 @@ "env": { "openSearchUrl": "http://localhost:9200", "SECURITY_ENABLED": false, + "AGGREGATION_VIEW": false, "username": "admin", "password": "admin", "ENDPOINT_WITH_PROXY": false, @@ -19,4 +20,4 @@ "VISBUILDER_ENABLED": false, "DATASOURCE_MANAGEMENT_ENABLED": false } -} \ No newline at end of file +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternTenantHeader.json b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternTenantHeader.json new file mode 100644 index 000000000..2cc458c24 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternTenantHeader.json @@ -0,0 +1,3 @@ +{ + "securitytenant": ["test"] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithTest.json b/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithTest.json new file mode 100644 index 000000000..6f7c17249 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithTest.json @@ -0,0 +1,24 @@ +{ + "cluster_permissions": [ + "cluster_all" + ], + "index_permissions": [{ + "index_patterns": [ + "*" + ], + "dls": "", + "fls": [], + "masked_fields": [], + "allowed_actions": [ + "indices_all" + ] + }], + "tenant_permissions": [{ + "tenant_patterns": [ + "test" + ], + "allowed_actions": [ + "kibana_all_write" + ] + }] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest.json b/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest.json new file mode 100644 index 000000000..e2fb1f663 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest.json @@ -0,0 +1,20 @@ +{ + "cluster_permissions": [ + "cluster_all" + ], + "index_permissions": [{ + "index_patterns": [ + "*" + ], + "dls": "", + "fls": [], + "masked_fields": [], + "allowed_actions": [ + "indices_all" + ] + }], + "tenant_permissions": [{ + "tenant_patterns": [], + "allowed_actions": [] + }] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/kibanauserRoleMapping.json b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/kibanauserRoleMapping.json new file mode 100644 index 000000000..ffc55576c --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/kibanauserRoleMapping.json @@ -0,0 +1,4 @@ +{ + "backend_roles" : [ "kibanauser" ], + "users" : [ "test1", "test2" ] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithTestMapping.json b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithTestMapping.json new file mode 100644 index 000000000..5d5417d57 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithTestMapping.json @@ -0,0 +1,3 @@ +{ + "users" : [ "test1" ] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithoutTestMapping.json b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithoutTestMapping.json new file mode 100644 index 000000000..f8a3c10b7 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithoutTestMapping.json @@ -0,0 +1,3 @@ +{ + "users" : [ "test2" ] +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/tenants/testTenant.json b/cypress/fixtures/plugins/security-dashboards-plugin/tenants/testTenant.json new file mode 100644 index 000000000..343803a12 --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/tenants/testTenant.json @@ -0,0 +1,3 @@ +{ + "description": "This test tenant for aggregation view feature testing." +} diff --git a/cypress/fixtures/plugins/security-dashboards-plugin/users/testUser.json b/cypress/fixtures/plugins/security-dashboards-plugin/users/testUser.json new file mode 100644 index 000000000..2ac6068af --- /dev/null +++ b/cypress/fixtures/plugins/security-dashboards-plugin/users/testUser.json @@ -0,0 +1,3 @@ +{ + "password": "password" +} \ No newline at end of file diff --git a/cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js b/cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js new file mode 100644 index 000000000..8c5750a96 --- /dev/null +++ b/cypress/integration/plugins/security-dashboards-plugin/aggregation_view.js @@ -0,0 +1,108 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + SAVED_OBJECTS_PATH, +} from '../../../utils/dashboards/constants'; + +import { + ADMIN_AUTH, + CURRENT_TENANT, + } from '../../../utils/commands'; + +import tenantDescription from '../../../fixtures/plugins/security-dashboards-plugin/tenants/testTenant'; +import testUsersSetUp from '../../../fixtures/plugins/security-dashboards-plugin/users/testUser'; +import roleWithTestSetUp from '../../../fixtures/plugins/security-dashboards-plugin/roles/roleWithTest'; +import roleWithoutTestSetUp from '../../../fixtures/plugins/security-dashboards-plugin/roles/roleWithoutTest'; +import kibanaRoleMappingSetUp from '../../../fixtures/plugins/security-dashboards-plugin/rolesmapping/kibanauserRoleMapping'; +import roleWithTestMappingSetUp from '../../../fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithTestMapping'; +import roleWithoutTestMappingSetUp from '../../../fixtures/plugins/security-dashboards-plugin/rolesmapping/roleWithoutTestMapping'; +import indexPatternTenantHeaderSetUp from '../../../fixtures/plugins/security-dashboards-plugin/indexpatterns/indexPatternTenantHeader'; + +const tenantName = 'test'; +const userName1 = 'test1'; +const userName2 = 'test2'; +const password = 'password'; +const roleName1 = 'roleWithTest'; +const roleName2 = 'roleWithoutTest'; +const kibanaRoleName = 'kibana_user' + +if (Cypress.env('SECURITY_ENABLED') && Cypress.env('AGGREGATION_VIEW')) { + describe('Saved objects table test', () => { + // start a server so that server responses can be mocked via fixtures + // in all of the below test cases + before(() => { + cy.server(); + cy.createTenant(tenantName, tenantDescription); + + cy.createIndexPattern('index-pattern1', { + title: 's*', + timeFieldName: 'timestamp', + }); + cy.createIndexPattern('index-pattern2', { + title: 'se*', + timeFieldName: 'timestamp', + }, + indexPatternTenantHeaderSetUp + ); + + cy.createInternalUser(userName1, testUsersSetUp); + cy.createInternalUser(userName2, testUsersSetUp); + + cy.createRole(roleName1, roleWithTestSetUp); + cy.createRole(roleName2, roleWithoutTestSetUp); + + cy.createRoleMapping(kibanaRoleName, kibanaRoleMappingSetUp); + cy.createRoleMapping(roleName1, roleWithTestMappingSetUp); + cy.createRoleMapping(roleName2, roleWithoutTestMappingSetUp); + + cy.wait(300000); + }); + + it('should check the saved objects as global tenant', () => { + CURRENT_TENANT.newTenant = 'global'; + cy.visit(SAVED_OBJECTS_PATH); + cy.contains('a', 'Saved objects'); + cy.contains('a', 's*'); + cy.contains('a', 'se*'); + }); + + it('should login as test1 and check saved object', () =>{ + CURRENT_TENANT.newTenant = 'private'; + ADMIN_AUTH.newUser = userName1; + ADMIN_AUTH.newPassword = password; + + cy.visit(SAVED_OBJECTS_PATH); + cy.url().should((url) => { + expect(url).to.contain('/management'); + }); + + cy.wait(5000); + cy.contains('a', 'se*'); + cy.contains('a', 's*').should('not.exist'); + }); + + it('should login as test2 and check saved object', () =>{ + CURRENT_TENANT.newTenant = 'private'; + ADMIN_AUTH.newUser = userName2; + ADMIN_AUTH.newPassword = password; + + cy.visit(SAVED_OBJECTS_PATH); + cy.url().should((url) => { + expect(url).to.contain('/management'); + }); + + cy.wait(5000); + cy.contains('a', 'se*').should('not.exist'); + cy.contains('a', 's*').should('not.exist'); + }); + + after(() => { + ADMIN_AUTH.newUser = Cypress.env('username'); + ADMIN_AUTH.newPassword = Cypress.env('password'); + CURRENT_TENANT.newTenant = 'private'; + }); + }); +} diff --git a/cypress/support/index.js b/cypress/support/index.js index 7de1674d4..a65a3d41d 100644 --- a/cypress/support/index.js +++ b/cypress/support/index.js @@ -25,6 +25,7 @@ import '../utils/dashboards/datasource-management-dashboards-plugin/commands'; import '../utils/plugins/index-management-dashboards-plugin/commands'; import '../utils/plugins/anomaly-detection-dashboards-plugin/commands'; import '../utils/plugins/security/commands'; +import '../utils/plugins/security-dashboards-plugin/commands'; import '../utils/plugins/alerting-dashboards-plugin/commands'; // Alternatively you can use CommonJS syntax: diff --git a/cypress/utils/commands.js b/cypress/utils/commands.js index 720496c3d..c9d9003cb 100644 --- a/cypress/utils/commands.js +++ b/cypress/utils/commands.js @@ -5,11 +5,24 @@ import { BASE_PATH, IM_API } from './constants'; -const ADMIN_AUTH = { +export const ADMIN_AUTH = { username: Cypress.env('username'), password: Cypress.env('password'), + set newUser(changedUsername) { + this.username = changedUsername + }, + set newPassword(changedPassword) { + this.password = changedPassword; + }, }; +export const CURRENT_TENANT = { + defaultTenant:'private', + set newTenant(changedTenant) { + this.defaultTenant = changedTenant; + }, +} + export const supressNoRequestOccurred = () => { cy.on('fail', (err) => { if (err.message.includes('No request ever occurred.')) return false; @@ -33,7 +46,7 @@ Cypress.Commands.overwrite('visit', (orig, url, options) => { auth: ADMIN_AUTH, }; } - newOptions.qs = { security_tenant: 'private' }; + newOptions.qs = { security_tenant: CURRENT_TENANT.defaultTenant }; if (waitForGetTenant) { cy.intercept('GET', '/api/v1/multitenancy/tenant').as('getTenant'); orig(url, newOptions); @@ -185,7 +198,7 @@ Cypress.Commands.add('bulkUploadDocs', (fixturePath, index) => { }); }); -Cypress.Commands.add('createIndexPattern', (id, attributes) => { +Cypress.Commands.add('createIndexPattern', (id, attributes, header = {}) => { const url = `${ Cypress.config().baseUrl }/api/saved_objects/index-pattern/${id}`; @@ -196,6 +209,7 @@ Cypress.Commands.add('createIndexPattern', (id, attributes) => { headers: { 'content-type': 'application/json;charset=UTF-8', 'osd-xsrf': true, + ...header, }, body: JSON.stringify({ attributes, diff --git a/cypress/utils/constants.js b/cypress/utils/constants.js index 87cca9549..bc2caef6d 100644 --- a/cypress/utils/constants.js +++ b/cypress/utils/constants.js @@ -12,3 +12,4 @@ export * from './plugins/reports-dashboards/constants'; export * from './plugins/query-workbench-dashboards/constants'; export * from './plugins/security/constants'; export * from './plugins/notifications-dashboards/constants'; +export * from './plugins/security-dashboards-plugin/constants'; diff --git a/cypress/utils/dashboards/constants.js b/cypress/utils/dashboards/constants.js index a850c1690..9b2450cdd 100644 --- a/cypress/utils/dashboards/constants.js +++ b/cypress/utils/dashboards/constants.js @@ -2,3 +2,11 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ + +import { BASE_PATH } from '../base_constants'; + +// STACK MANAGEMENT PATH +export const STACK_MANAGEMENT_PATH = BASE_PATH + '/app/management'; + +export const INDEX_PATTERN_PATH = STACK_MANAGEMENT_PATH + '/opensearch-dashboards/indexPatterns'; +export const SAVED_OBJECTS_PATH = STACK_MANAGEMENT_PATH + '/opensearch-dashboards/objects'; diff --git a/cypress/utils/index.d.ts b/cypress/utils/index.d.ts index 4fa3c0d44..5b314b6e5 100644 --- a/cypress/utils/index.d.ts +++ b/cypress/utils/index.d.ts @@ -46,7 +46,7 @@ declare namespace Cypress { /** * Adds an index pattern * @example - * cy.createIndexPattern('patterId', 'patt*', 'timestamp') + * cy.createIndexPattern('patterId', { title: 'patt*', timeFieldName: 'timestamp' }) */ createIndexPattern( id: string, @@ -54,7 +54,8 @@ declare namespace Cypress { title: string; timeFieldName?: string; [key: string]: any; - } + }, + header: string, ): Chainable; /** diff --git a/cypress/utils/plugins/security-dashboards-plugin/commands.js b/cypress/utils/plugins/security-dashboards-plugin/commands.js new file mode 100644 index 000000000..4d432210b --- /dev/null +++ b/cypress/utils/plugins/security-dashboards-plugin/commands.js @@ -0,0 +1,48 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { SEC_API } from '../../constants'; + +/** + ***************************** + SECURITY DASHBOARDS PLUGIN COMMANDS + ***************************** + */ + + Cypress.Commands.add('createTenant', (tenantID, tenantJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.TENANTS_BASE}/${tenantID}`, + tenantJson + ); + cy.wait(10000); +}); + +Cypress.Commands.add('createInternalUser', (userID, userJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.INTERNALUSERS_BASE}/${userID}`, + userJson + ); + cy.wait(10000); +}); + +Cypress.Commands.add('createRole', (roleID, roleJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_BASE}/${roleID}`, + roleJson + ); + cy.wait(10000); +}); + +Cypress.Commands.add('createRoleMapping', (roleID, rolemappingJson) => { + cy.request( + 'PUT', + `${Cypress.env('openSearchUrl')}${SEC_API.ROLE_MAPPING_BASE}/${roleID}`, + rolemappingJson + ); + cy.wait(10000); +}); diff --git a/cypress/utils/plugins/security-dashboards-plugin/constants.js b/cypress/utils/plugins/security-dashboards-plugin/constants.js new file mode 100644 index 000000000..b065c523a --- /dev/null +++ b/cypress/utils/plugins/security-dashboards-plugin/constants.js @@ -0,0 +1,19 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + ***************************** + SECURITY DASHBOARDS PLUGIN CONSTANTS + ***************************** + */ + +//Security API Constants +export const SEC_API_PREFIX = '/_plugins/_security/api'; +export const SEC_API = { + TENANTS_BASE: `${SEC_API_PREFIX}/tenants`, + INTERNALUSERS_BASE: `${SEC_API_PREFIX}/internalusers`, + ROLE_BASE: `${SEC_API_PREFIX}/roles`, + ROLE_MAPPING_BASE: `${SEC_API_PREFIX}/rolesmapping`, +} diff --git a/cypress/utils/plugins/security-dashboards-plugin/index.d.ts b/cypress/utils/plugins/security-dashboards-plugin/index.d.ts new file mode 100644 index 000000000..e54a2991c --- /dev/null +++ b/cypress/utils/plugins/security-dashboards-plugin/index.d.ts @@ -0,0 +1,52 @@ +// type definitions for custom commands like "createDefaultTodos" +/// + +declare namespace Cypress { + interface Chainable { + /** + * Create a test tenant by calling REST API + * @example + * cy.createTenant('test_tenant', tenantJsonFixture ) + */ + createTenant( + tenantID: string, + tenantJson: string + ): Chainable; + } + + interface Chainable { + /** + * Create an internal user by calling REST API + * @example + * cy.createInternalUser('test_user', userJsonFixture ) + */ + createInternalUser( + userID: string, + userJson: string + ): Chainable; + } + + interface Chainable { + /** + * Create a role by calling REST API + * @example + * cy.createRole('role_name', roleJsonFixture ) + */ + createRole( + roleID: string, + roleJson: string + ): Chainable; + } + + interface Chainable { + /** + * Create a role mapping by calling REST API + * @example + * cy.createRoleMapping('role_name', rolemappingJsonFixture ) + */ + createRoleMapping( + roleID: string, + rolemappingJson: string + ): Chainable; + } +} diff --git a/cypress/utils/plugins/security/constants.js b/cypress/utils/plugins/security/constants.js index 0ad090023..1f8009ba0 100644 --- a/cypress/utils/plugins/security/constants.js +++ b/cypress/utils/plugins/security/constants.js @@ -28,6 +28,7 @@ export const SEC_UI_AUTH_PATH = BASE_SEC_UI_PATH + '/auth'; export const SEC_UI_ROLES_PATH = BASE_SEC_UI_PATH + '/roles'; export const SEC_UI_ROLES_CREATE_PATH = SEC_UI_ROLES_PATH + '/create'; +export const SEC_UI_ROLE_EDIT_PATH = SEC_UI_ROLES_PATH + '/edit'; export const SEC_UI_INTERNAL_USERS_PATH = BASE_SEC_UI_PATH + '/users'; export const SEC_UI_USER_EDIT_PATH = SEC_UI_INTERNAL_USERS_PATH + '/edit'; diff --git a/package.json b/package.json index a3ca5ed4c..99e0cc6a3 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "cypress:open": "cypress open", "cypress:run-without-security": "env TZ=America/Los_Angeles NO_COLOR=1 cypress run --headless --env SECURITY_ENABLED=false", "cypress:run-with-security": "env TZ=America/Los_Angeles NO_COLOR=1 cypress run --headless --env SECURITY_ENABLED=true,openSearchUrl=https://localhost:9200", + "cypress:run-with-security-and-aggregation-view": "env TZ=America/Los_Angeles NO_COLOR=1 cypress run --headless --env SECURITY_ENABLED=true,openSearchUrl=https://localhost:9200,AGGREGATION_VIEW=true", "cypress:run-plugin-tests-without-security": "yarn cypress:run-without-security --spec 'cypress/integration/plugins/*/*.js'", "cypress:run-plugin-tests-with-security": "yarn cypress:run-with-security --spec 'cypress/integration/plugins/*/*.js'", "cypress:release-chrome": "yarn cypress:run-with-security --browser chrome --spec 'cypress/integration/core-opensearch-dashboards/opensearch-dashboards/*.js,cypress/integration/plugins/*/*'",