diff --git a/x-pack/test/saved_object_api_integration/common/config.js b/x-pack/test/saved_object_api_integration/common/config.js index eb1b1a9514ccc8..86580bdf77e88d 100644 --- a/x-pack/test/saved_object_api_integration/common/config.js +++ b/x-pack/test/saved_object_api_integration/common/config.js @@ -62,7 +62,8 @@ export function createTestConfig(name, { license = 'trial', disabledPlugins = [] ...config.xpack.api.get('kbnTestServer.serverArgs'), '--optimize.enabled=false', '--server.xsrf.disableProtection=true', - ...disabledPlugins.map(key => `--xpack.${key}.enabled=false`) + ...disabledPlugins.map(key => `--xpack.${key}.enabled=false`), + `--plugin-path=${path.join(__dirname, 'fixtures', 'namespace_agnostic_type_plugin')}` ], }, }; diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json index d2a13e30f473de..c80f1672ce09ac 100644 --- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json +++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json @@ -331,3 +331,19 @@ } } } + +{ + "type": "doc", + "value": { + "index": ".kibana", + "type": "doc", + "id": "chapo:8121a00-8efd-21e7-1cb3-34ab96643444", + "source": { + "type": "chapo", + "updated_at": "2017-09-21T18:59:16.270Z", + "chapo": { + "name": "El Chapo" + } + } + } +} diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json index 666798d6a894a1..8f77fccf872de7 100644 --- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json +++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/mappings.json @@ -302,6 +302,19 @@ "type": "text" } } + }, + "chapo": { + "properties": { + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 + } + } + } + } } } } diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/index.js b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/index.js new file mode 100644 index 00000000000000..7598fe587af7f9 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/index.js @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import mappings from './mappings.json'; + +export default function (kibana) { + return new kibana.Plugin({ + require: [], + name: 'namespace_agnostic_type_plugin', + uiExports: { + savedObjectsSchema: { + chapo: { + isNamespaceAgnostic: true + } + }, + mappings, + }, + + config() {}, + }); +} diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/mappings.json b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/mappings.json new file mode 100644 index 00000000000000..4a11c97b6432db --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/mappings.json @@ -0,0 +1,15 @@ +{ + "chapo": { + "properties": { + "name": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 2048 + } + } + } + } + } +} diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/package.json b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/package.json new file mode 100644 index 00000000000000..1a0afbc6bfcb30 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/fixtures/namespace_agnostic_type_plugin/package.json @@ -0,0 +1,7 @@ +{ + "name": "namespace_agnostic_type_plugin", + "version": "0.0.0", + "kibana": { + "version": "kibana" + } +} diff --git a/x-pack/test/saved_object_api_integration/common/lib/create_users_and_roles.js b/x-pack/test/saved_object_api_integration/common/lib/create_users_and_roles.js new file mode 100644 index 00000000000000..86b7646e375bb1 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/lib/create_users_and_roles.js @@ -0,0 +1,176 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { AUTHENTICATION } from './authentication'; + +export const createUsersAndRoles = async (es, supertest) => { + await supertest.put('/api/security/role/kibana_legacy_user') + .send({ + elasticsearch: { + indices: [{ + names: ['.kibana'], + privileges: ['manage', 'read', 'index', 'delete'] + }] + } + }); + + await supertest.put('/api/security/role/kibana_legacy_dashboard_only_user') + .send({ + elasticsearch: { + indices: [{ + names: ['.kibana'], + privileges: ['read', 'view_index_metadata'] + }] + } + }); + + await supertest.put('/api/security/role/kibana_dual_privileges_user') + .send({ + elasticsearch: { + indices: [{ + names: ['.kibana'], + privileges: ['manage', 'read', 'index', 'delete'] + }] + }, + kibana: { + global: ['all'] + } + }); + + await supertest.put('/api/security/role/kibana_dual_privileges_dashboard_only_user') + .send({ + elasticsearch: { + indices: [{ + names: ['.kibana'], + privileges: ['read', 'view_index_metadata'] + }] + }, + kibana: { + global: ['read'] + } + }); + + await supertest.put('/api/security/role/kibana_rbac_user') + .send({ + kibana: { + global: ['all'] + } + }); + + await supertest.put('/api/security/role/kibana_rbac_dashboard_only_user') + .send({ + kibana: { + global: ['read'] + } + }); + + await supertest.put('/api/security/role/kibana_rbac_default_space_user') + .send({ + kibana: { + space: { + default: ['all'] + } + } + }); + + await supertest.put('/api/security/role/kibana_rbac_space_1_read_user') + .send({ + kibana: { + space: { + space_1: ['read'] + } + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + body: { + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + roles: [], + full_name: 'not a kibana user', + email: 'not_a_kibana_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + roles: ['kibana_legacy_user'], + full_name: 'a kibana legacy user', + email: 'a_kibana_legacy_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + roles: ["kibana_legacy_dashboard_only_user"], + full_name: 'a kibana legacy dashboard only user', + email: 'a_kibana_legacy_dashboard_only_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + roles: ['kibana_dual_privileges_user'], + full_name: 'a kibana dual_privileges user', + email: 'a_kibana_dual_privileges_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, + roles: ["kibana_dual_privileges_dashboard_only_user"], + full_name: 'a kibana dual_privileges dashboard only user', + email: 'a_kibana_dual_privileges_dashboard_only_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + roles: ['kibana_rbac_user'], + full_name: 'a kibana user', + email: 'a_kibana_rbac_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + roles: ["kibana_rbac_dashboard_only_user"], + full_name: 'a kibana dashboard only user', + email: 'a_kibana_rbac_dashboard_only_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.PASSWORD, + roles: ['kibana_rbac_default_space_user'], + full_name: 'a kibana default space user', + email: 'a_kibana_rbac_default_space_user@elastic.co', + } + }); + + await es.shield.putUser({ + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME, + body: { + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.PASSWORD, + roles: ['kibana_rbac_space_1_read_user'], + full_name: 'a kibana rbac space 1 read-only user', + email: 'a_kibana_rbac_space_1_readonly_user@elastic.co', + } + }); +}; diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.js b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.js index f6d52f86f9ff19..4df092e523382f 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.js +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.js @@ -8,7 +8,10 @@ import { getUrlPrefix } from '../../lib/space_test_utils'; import { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; export function createTestSuiteFactory(es, esArchiver, supertest) { - const createTest = (description, { + const spaceAwareType = 'visualization'; + const notSpaceAwareType = 'chapo'; + + const makeCreateTest = describeFn => (description, { auth = { username: undefined, password: undefined @@ -16,12 +19,12 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { spaceId, tests, }) => { - describe(description, () => { + describeFn(description, () => { before(() => esArchiver.load('saved_objects/spaces')); after(() => esArchiver.unload('saved_objects/spaces')); it(`should return ${tests.spaceAware.statusCode} for a space-aware type`, async () => { await supertest - .post(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization`) + .post(`${getUrlPrefix(spaceId)}/api/saved_objects/${spaceAwareType}`) .auth(auth.username, auth.password) .send({ attributes: { @@ -34,11 +37,11 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { it(`should return ${tests.notSpaceAware.statusCode} for a non space-aware type`, async () => { await supertest - .post(`${getUrlPrefix(spaceId)}/api/saved_objects/space`) + .post(`${getUrlPrefix(spaceId)}/api/saved_objects/${notSpaceAwareType}`) .auth(auth.username, auth.password) .send({ attributes: { - name: 'My favorite space', + name: `Can't be contained to a space`, } }) .expect(tests.notSpaceAware.statusCode) @@ -48,6 +51,9 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { }); }; + const createTest = makeCreateTest(describe); + createTest.only = makeCreateTest(describe.only); + const createExpectSpaceAwareResults = (spaceId = DEFAULT_SPACE_ID) => async (resp) => { expect(resp.body).to.have.property('id').match(/^[0-9a-f-]{36}$/); @@ -56,7 +62,7 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { expect(resp.body).to.eql({ id: resp.body.id, - type: 'visualization', + type: spaceAwareType, updated_at: resp.body.updated_at, version: 1, attributes: { @@ -68,7 +74,7 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { // query ES directory to ensure namespace was or wasn't specified const { _source } = await es.get({ - id: `${expectedSpacePrefix}visualization:${resp.body.id}`, + id: `${expectedSpacePrefix}${spaceAwareType}:${resp.body.id}`, type: 'doc', index: '.kibana' }); @@ -92,17 +98,17 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { expect(resp.body).to.eql({ id: resp.body.id, - type: 'space', + type: notSpaceAwareType, updated_at: resp.body.updated_at, version: 1, attributes: { - name: 'My favorite space', + name: `Can't be contained to a space`, } }); // query ES directory to ensure namespace wasn't specified const { _source } = await es.get({ - id: `space:${resp.body.id}`, + id: `${notSpaceAwareType}:${resp.body.id}`, type: 'doc', index: '.kibana' }); @@ -114,10 +120,11 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { expect(actualNamespace).to.eql(undefined); }; - return { createTest, createExpectSpaceAwareResults, expectNotSpaceAwareResults, + notSpaceAwareType, + spaceAwareType, }; } diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.js b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.js new file mode 100644 index 00000000000000..a0c45c37a3b9ff --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.js @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { createUsersAndRoles } from "../../common/lib/create_users_and_roles"; + +export default function ({ loadTestFile, getService }) { + const es = getService('es'); + const supertest = getService('supertest'); + + describe('security and spaces enabled', () => { + before(async () => { + await createUsersAndRoles(es, supertest); + }); + + loadTestFile(require.resolve('./saved_objects')); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/create.js b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/create.js new file mode 100644 index 00000000000000..613ab7f605db53 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/create.js @@ -0,0 +1,408 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from 'expect.js'; +import { AUTHENTICATION } from '../../../common/lib/authentication'; +import { createTestSuiteFactory } from '../../../common/suites/saved_objects/create'; +import { SPACES } from '../../../common/lib/spaces'; + +export default function ({ getService }) { + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const es = getService('es'); + const esArchiver = getService('esArchiver'); + + const { + createTest, + createExpectSpaceAwareResults, + expectNotSpaceAwareResults, + notSpaceAwareType, + spaceAwareType, + } = createTestSuiteFactory(es, esArchiver, supertestWithoutAuth); + + describe('create', () => { + + const createExpectRbacForbidden = type => resp => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: `Unable to create ${type}, missing action:saved_objects/${type}/create` + }); + }; + + const createExpectLegacyForbidden = username => resp => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + //eslint-disable-next-line max-len + message: `action [indices:data/write/index] is unauthorized for user [${username}]: [security_exception] action [indices:data/write/index] is unauthorized for user [${username}]` + }); + }; + + describe(`${SPACES.DEFAULT.spaceId} space`, () => { + const spaceId = SPACES.DEFAULT.spaceId; + createTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + } + }); + + createTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults(), + }, + } + }); + + createTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + }, + } + }); + + createTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana dual-privileges dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac default space user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(spaceId), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults(), + }, + } + }); + + createTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + }); + + describe(`${SPACES.SPACE_1.spaceId} space`, () => { + const spaceId = SPACES.SPACE_1.spaceId; + createTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + } + }); + + createTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(spaceId), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults(), + }, + } + }); + + createTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(spaceId), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + }, + } + }); + + createTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(spaceId), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana dual-privileges dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: createExpectSpaceAwareResults(spaceId), + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + } + }); + + createTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac default space user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(spaceAwareType), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.js b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.js new file mode 100644 index 00000000000000..351e71bc38278d --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + + + +export default function ({ loadTestFile }) { + describe('saved_objects', () => { + loadTestFile(require.resolve('./create')); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/config.js b/x-pack/test/saved_object_api_integration/security_and_spaces/config.js new file mode 100644 index 00000000000000..d63841d2cec3cb --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/config.js @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createTestConfig } from '../common/config'; + +export default createTestConfig('security_and_spaces', { license: 'trial', securityEnabled: true }); diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/index.js b/x-pack/test/saved_object_api_integration/security_only/apis/index.js index 1ba53fb3de504d..5fbea60eb56291 100644 --- a/x-pack/test/saved_object_api_integration/security_only/apis/index.js +++ b/x-pack/test/saved_object_api_integration/security_only/apis/index.js @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { AUTHENTICATION } from "../../common/lib/authentication"; +import { createUsersAndRoles } from '../../common/lib/create_users_and_roles'; export default function ({ loadTestFile, getService }) { const es = getService('es'); @@ -11,174 +11,7 @@ export default function ({ loadTestFile, getService }) { describe('security only enabled', () => { before(async () => { - await supertest.put('/api/security/role/kibana_legacy_user') - .send({ - elasticsearch: { - indices: [{ - names: ['.kibana'], - privileges: ['manage', 'read', 'index', 'delete'] - }] - } - }); - - await supertest.put('/api/security/role/kibana_legacy_dashboard_only_user') - .send({ - elasticsearch: { - indices: [{ - names: ['.kibana'], - privileges: ['read', 'view_index_metadata'] - }] - } - }); - - await supertest.put('/api/security/role/kibana_dual_privileges_user') - .send({ - elasticsearch: { - indices: [{ - names: ['.kibana'], - privileges: ['manage', 'read', 'index', 'delete'] - }] - }, - kibana: { - global: ['all'] - } - }); - - await supertest.put('/api/security/role/kibana_dual_privileges_dashboard_only_user') - .send({ - elasticsearch: { - indices: [{ - names: ['.kibana'], - privileges: ['read', 'view_index_metadata'] - }] - }, - kibana: { - global: ['read'] - } - }); - - await supertest.put('/api/security/role/kibana_rbac_user') - .send({ - kibana: { - global: ['all'] - } - }); - - await supertest.put('/api/security/role/kibana_rbac_dashboard_only_user') - .send({ - kibana: { - global: ['read'] - } - }); - - await supertest.put('/api/security/role/kibana_rbac_default_space_user') - .send({ - kibana: { - space: { - default: ['all'] - } - } - }); - - await supertest.put('/api/security/role/kibana_rbac_space_1_read_user') - .send({ - kibana: { - space: { - space_1: ['read'] - } - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, - body: { - password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, - roles: [], - full_name: 'not a kibana user', - email: 'not_a_kibana_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, - roles: ['kibana_legacy_user'], - full_name: 'a kibana legacy user', - email: 'a_kibana_legacy_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, - roles: ["kibana_legacy_dashboard_only_user"], - full_name: 'a kibana legacy dashboard only user', - email: 'a_kibana_legacy_dashboard_only_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, - roles: ['kibana_dual_privileges_user'], - full_name: 'a kibana dual_privileges user', - email: 'a_kibana_dual_privileges_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, - roles: ["kibana_dual_privileges_dashboard_only_user"], - full_name: 'a kibana dual_privileges dashboard only user', - email: 'a_kibana_dual_privileges_dashboard_only_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, - roles: ['kibana_rbac_user'], - full_name: 'a kibana user', - email: 'a_kibana_rbac_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, - roles: ["kibana_rbac_dashboard_only_user"], - full_name: 'a kibana dashboard only user', - email: 'a_kibana_rbac_dashboard_only_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.PASSWORD, - roles: ['kibana_rbac_default_space_user'], - full_name: 'a kibana default space user', - email: 'a_kibana_rbac_default_space_user@elastic.co', - } - }); - - await es.shield.putUser({ - username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME, - body: { - password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.PASSWORD, - roles: ['kibana_rbac_space_1_read_user'], - full_name: 'a kibana rbac space 1 read-only user', - email: 'a_kibana_rbac_space_1_readonly_user@elastic.co', - } - }); - + await createUsersAndRoles(es, supertest); }); loadTestFile(require.resolve('./saved_objects')); diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.js index a1eadfbea96ecc..12709a3686107c 100644 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.js +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.js @@ -16,7 +16,9 @@ export default function ({ getService }) { const { createTest, createExpectSpaceAwareResults, - expectNotSpaceAwareResults + expectNotSpaceAwareResults, + notSpaceAwareType, + spaceAwareType, } = createTestSuiteFactory(es, esArchiver, supertestWithoutAuth); describe('create', () => { @@ -131,11 +133,11 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden('visualization'), + response: createExpectRbacForbidden(spaceAwareType), }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden('space'), + response: createExpectRbacForbidden(notSpaceAwareType), }, } }); @@ -165,11 +167,49 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden('visualization'), + response: createExpectRbacForbidden(spaceAwareType), }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden('space'), + response: createExpectRbacForbidden(notSpaceAwareType), + }, + } + }); + + createTest(`kibana rbac default space user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + // this will change to RBAC once the ES PR for checking all app privileges merges + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + // this will change to RBAC once the ES PR for checking all app privileges merges + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_USER.USERNAME), + }, + } + }); + + createTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + // this will change to RBAC once the ES PR for checking all app privileges merges + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + // this will change to RBAC once the ES PR for checking all app privileges merges + response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_RBAC_SPACE_1_READONLY_USER.USERNAME), }, } }); diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.js index b405a511b613ef..35d51ed49d61c6 100644 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.js +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.js @@ -35,7 +35,7 @@ export default function ({ getService }) { expect(resp.body).to.eql({ page: 1, per_page: 20, - total: 4, + total: 5, saved_objects: [ { id: '91200a00-9efd-11e7-acb3-3dab96693fab', @@ -65,6 +65,15 @@ export default function ({ getService }) { version: 1, attributes: resp.body.saved_objects[3].attributes }, + { + id: `8121a00-8efd-21e7-1cb3-34ab96643444`, + type: 'chapo', + updated_at: '2017-09-21T18:59:16.270Z', + version: 1, + attributes: { + 'name': 'El Chapo' + } + } ] }); }; diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.js index 01af05e5b08f1e..c92c85f3c7832c 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.js +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.js @@ -64,6 +64,11 @@ export default function ({ getService }) { type: 'visualization', updated_at: '2017-09-21T18:51:23.794Z', version: 1, + }, { + id: `8121a00-8efd-21e7-1cb3-34ab96643444`, + type: 'chapo', + updated_at: '2017-09-21T18:59:16.270Z', + version: 1, }] .sort(sortById);