diff --git a/x-pack/package.json b/x-pack/package.json index 9411a9b5c71f83..a4da3fe05765ef 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -27,8 +27,8 @@ "@kbn/es": "link:../packages/kbn-es", "@kbn/plugin-helpers": "link:../packages/kbn-plugin-helpers", "@kbn/test": "link:../packages/kbn-test", - "@types/expect.js": "~0.3.29", - "@types/jest": "^22.2.3", + "@types/expect.js": "^0.3.29", + "@types/jest": "^23.3.1", "@types/mocha": "^5.2.5", "@types/pngjs": "^3.3.1", "@types/supertest": "^2.0.5", diff --git a/x-pack/plugins/security/common/model/kibana_application_privilege.ts b/x-pack/plugins/security/common/model/kibana_application_privilege.ts deleted file mode 100644 index 54350ec2abcef0..00000000000000 --- a/x-pack/plugins/security/common/model/kibana_application_privilege.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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 { KibanaPrivilege } from './kibana_privilege'; - -export interface KibanaApplicationPrivilege { - name: KibanaPrivilege; -} diff --git a/x-pack/plugins/security/common/model/kibana_privilege.ts b/x-pack/plugins/security/common/model/kibana_privilege.ts index 834e62570fe263..20cac65b4ca792 100644 --- a/x-pack/plugins/security/common/model/kibana_privilege.ts +++ b/x-pack/plugins/security/common/model/kibana_privilege.ts @@ -5,3 +5,5 @@ */ export type KibanaPrivilege = 'none' | 'read' | 'all'; + +export const KibanaAppPrivileges: KibanaPrivilege[] = ['read', 'all']; diff --git a/x-pack/plugins/security/index.js b/x-pack/plugins/security/index.js index 6ee655f8b0426b..7262eadb999c63 100644 --- a/x-pack/plugins/security/index.js +++ b/x-pack/plugins/security/index.js @@ -16,7 +16,6 @@ import { validateConfig } from './server/lib/validate_config'; import { authenticateFactory } from './server/lib/auth_redirect'; import { checkLicense } from './server/lib/check_license'; import { initAuthenticator } from './server/lib/authentication/authenticator'; -import { initPrivilegesApi } from './server/routes/api/v1/privileges'; import { SecurityAuditLogger } from './server/lib/audit_logger'; import { AuditLogger } from '../../server/lib/audit_logger'; import { createAuthorizationService, registerPrivilegesWithCluster } from './server/lib/authorization'; @@ -161,7 +160,6 @@ export const security = (kibana) => new kibana.Plugin({ initUsersApi(server); initPublicRolesApi(server); initIndicesApi(server); - initPrivilegesApi(server); initLoginView(server, xpackMainPlugin); initLogoutView(server); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.tsx b/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.tsx index d4497582a75119..74396481e27ba5 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.tsx +++ b/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.tsx @@ -24,7 +24,7 @@ import React, { ChangeEvent, Component, HTMLProps } from 'react'; import { toastNotifications } from 'ui/notify'; import { Space } from '../../../../../../spaces/common/model/space'; import { IndexPrivilege } from '../../../../../common/model/index_privilege'; -import { KibanaApplicationPrivilege } from '../../../../../common/model/kibana_application_privilege'; +import { KibanaPrivilege } from '../../../../../common/model/kibana_privilege'; import { Role } from '../../../../../common/model/role'; import { isReservedRole } from '../../../../lib/role'; import { deleteRole, saveRole } from '../../../../objects'; @@ -42,7 +42,7 @@ interface Props { rbacEnabled: boolean; allowDocumentLevelSecurity: boolean; allowFieldLevelSecurity: boolean; - kibanaAppPrivileges: KibanaApplicationPrivilege[]; + kibanaAppPrivileges: KibanaPrivilege[]; notifier: any; spaces?: Space[]; spacesEnabled: boolean; diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/kibana_privileges.tsx b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/kibana_privileges.tsx index d9a4ba73af9639..1ff7b62f715a7a 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/kibana_privileges.tsx +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/kibana_privileges.tsx @@ -6,7 +6,7 @@ import React, { Component } from 'react'; import { Space } from '../../../../../../../../spaces/common/model/space'; -import { KibanaApplicationPrivilege } from '../../../../../../../common/model/kibana_application_privilege'; +import { KibanaPrivilege } from '../../../../../../../common/model/kibana_privilege'; import { Role } from '../../../../../../../common/model/role'; import { RoleValidator } from '../../../lib/validate_role'; import { CollapsiblePanel } from '../../collapsible_panel'; @@ -18,7 +18,7 @@ interface Props { spacesEnabled: boolean; spaces?: Space[]; editable: boolean; - kibanaAppPrivileges: KibanaApplicationPrivilege[]; + kibanaAppPrivileges: KibanaPrivilege[]; onChange: (role: Role) => void; validator: RoleValidator; } diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.test.tsx b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.test.tsx index 018aed7df9bb18..d6ecbdb705b746 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.test.tsx +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.test.tsx @@ -24,14 +24,7 @@ const buildProps = (customProps?: any) => { }, }, editable: true, - kibanaAppPrivileges: [ - { - name: 'all', - }, - { - name: 'read', - }, - ], + kibanaAppPrivileges: ['all', 'read'], onChange: jest.fn(), ...customProps, }; diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.tsx b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.tsx index 4d8892d88fce4d..71b881c4a85efe 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.tsx +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/simple_privilege_form.tsx @@ -10,7 +10,6 @@ import { EuiFormRow, } from '@elastic/eui'; import React, { Component, Fragment } from 'react'; -import { KibanaApplicationPrivilege } from '../../../../../../../common/model/kibana_application_privilege'; import { KibanaPrivilege } from '../../../../../../../common/model/kibana_privilege'; import { Role } from '../../../../../../../common/model/role'; import { isReservedRole } from '../../../../../../lib/role'; @@ -19,7 +18,7 @@ import { copyRole } from '../../../lib/copy_role'; import { PrivilegeSelector } from './privilege_selector'; interface Props { - kibanaAppPrivileges: KibanaApplicationPrivilege[]; + kibanaAppPrivileges: KibanaPrivilege[]; role: Role; onChange: (role: Role) => void; editable: boolean; @@ -30,7 +29,6 @@ export class SimplePrivilegeForm extends Component { const { kibanaAppPrivileges, role } = this.props; const assignedPrivileges = role.kibana; - const availablePrivileges = kibanaAppPrivileges.map(privilege => privilege.name); const kibanaPrivilege: KibanaPrivilege = assignedPrivileges.global.length > 0 @@ -45,7 +43,7 @@ export class SimplePrivilegeForm extends Component { { }, ], editable: true, - kibanaAppPrivileges: [ - { - name: 'all', - }, - { - name: 'read', - }, - ], + kibanaAppPrivileges: ['all', 'read'], onChange: jest.fn(), validator: new RoleValidator(), ...customProps, diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_form.tsx b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_form.tsx index af76691b060f59..c48aa6d2047797 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_form.tsx +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_form.tsx @@ -17,7 +17,6 @@ import { } from '@elastic/eui'; import React, { Component, Fragment } from 'react'; import { Space } from '../../../../../../../../spaces/common/model/space'; -import { KibanaApplicationPrivilege } from '../../../../../../../common/model/kibana_application_privilege'; import { KibanaPrivilege } from '../../../../../../../common/model/kibana_privilege'; import { Role } from '../../../../../../../common/model/role'; import { isReservedRole } from '../../../../../../lib/role'; @@ -32,7 +31,7 @@ import { PrivilegeSpaceForm } from './privilege_space_form'; import { PrivilegeSpaceTable } from './privilege_space_table'; interface Props { - kibanaAppPrivileges: KibanaApplicationPrivilege[]; + kibanaAppPrivileges: KibanaPrivilege[]; role: Role; spaces: Space[]; onChange: (role: Role) => void; @@ -74,7 +73,6 @@ export class SpaceAwarePrivilegeForm extends Component { const { kibanaAppPrivileges, role } = this.props; const assignedPrivileges = role.kibana; - const availablePrivileges = kibanaAppPrivileges.map(privilege => privilege.name); const basePrivilege = assignedPrivileges.global.length > 0 ? assignedPrivileges.global[0] : NO_PRIVILEGE_VALUE; @@ -101,7 +99,7 @@ export class SpaceAwarePrivilegeForm extends Component { { - {this.renderSpacePrivileges(basePrivilege, availablePrivileges)} + {this.renderSpacePrivileges(basePrivilege, kibanaAppPrivileges)} ); } diff --git a/x-pack/plugins/security/public/views/management/edit_role/index.js b/x-pack/plugins/security/public/views/management/edit_role/index.js index 4fa4aaba4e2b08..5c744c908824cd 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/index.js +++ b/x-pack/plugins/security/public/views/management/edit_role/index.js @@ -27,6 +27,7 @@ import { EditRolePage } from './components'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; +import { KibanaAppPrivileges } from '../../../../common/model/kibana_privilege'; routes.when(`${EDIT_ROLES_PATH}/:name?`, { template, @@ -120,16 +121,13 @@ routes.when(`${EDIT_ROLES_PATH}/:name?`, { spaces, } = $route.current.locals; - // todo: don't hard-code this... - const kibanaApplicationPrivilege = [{ name: 'all' }, { name: 'read' } ]; - $scope.$$postDigest(() => { const domNode = document.getElementById('editRoleReactRoot'); render( { const privileges = Array.isArray(privilegeOrPrivileges) ? privilegeOrPrivileges : [privilegeOrPrivileges]; const allApplicationPrivileges = uniq([actions.version, actions.login, ...privileges]); + const hasPrivilegesResponse = await callWithRequest(request, 'shield.hasPrivileges', { body: { applications: [{ diff --git a/x-pack/plugins/security/server/routes/api/v1/privileges.js b/x-pack/plugins/security/server/routes/api/v1/privileges.js deleted file mode 100644 index 37dd160ec1311d..00000000000000 --- a/x-pack/plugins/security/server/routes/api/v1/privileges.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 { buildPrivilegeMap } from '../../../lib/authorization'; - -export function initPrivilegesApi(server) { - const { authorization } = server.plugins.security; - const savedObjectTypes = server.savedObjects.types; - - server.route({ - method: 'GET', - path: '/api/security/v1/privileges', - handler(request, reply) { - // we're returning our representation of the privileges, as opposed to the ones that are stored - // in Elasticsearch because our current thinking is that we'll associate additional structure/metadata - // with our view of them to allow users to more efficiently edit privileges for roles, and serialize it - // into a different structure for enforcement within Elasticsearch - const privileges = buildPrivilegeMap(savedObjectTypes, authorization.actions); - reply(privileges); - } - }); -} diff --git a/x-pack/test/rbac_api_integration/apis/es/has_privileges.js b/x-pack/test/api_integration/apis/es/has_privileges.js similarity index 100% rename from x-pack/test/rbac_api_integration/apis/es/has_privileges.js rename to x-pack/test/api_integration/apis/es/has_privileges.js diff --git a/x-pack/test/rbac_api_integration/apis/es/index.js b/x-pack/test/api_integration/apis/es/index.js similarity index 100% rename from x-pack/test/rbac_api_integration/apis/es/index.js rename to x-pack/test/api_integration/apis/es/index.js diff --git a/x-pack/test/rbac_api_integration/apis/es/post_privileges.js b/x-pack/test/api_integration/apis/es/post_privileges.js similarity index 100% rename from x-pack/test/rbac_api_integration/apis/es/post_privileges.js rename to x-pack/test/api_integration/apis/es/post_privileges.js diff --git a/x-pack/test/api_integration/apis/index.js b/x-pack/test/api_integration/apis/index.js index 7f105650141d95..85b11bb9ef71eb 100644 --- a/x-pack/test/api_integration/apis/index.js +++ b/x-pack/test/api_integration/apis/index.js @@ -6,6 +6,7 @@ export default function ({ loadTestFile }) { describe('apis', () => { + loadTestFile(require.resolve('./es')); loadTestFile(require.resolve('./security')); loadTestFile(require.resolve('./monitoring')); loadTestFile(require.resolve('./xpack_main')); diff --git a/x-pack/test/rbac_api_integration/apis/index.js b/x-pack/test/rbac_api_integration/apis/index.js index f28f18b83c90df..5642b33982c99c 100644 --- a/x-pack/test/rbac_api_integration/apis/index.js +++ b/x-pack/test/rbac_api_integration/apis/index.js @@ -180,8 +180,6 @@ export default function ({ loadTestFile, getService }) { }); }); - loadTestFile(require.resolve('./es')); - loadTestFile(require.resolve('./privileges')); loadTestFile(require.resolve('./saved_objects')); loadTestFile(require.resolve('./spaces')); }); diff --git a/x-pack/test/rbac_api_integration/apis/privileges/index.js b/x-pack/test/rbac_api_integration/apis/privileges/index.js deleted file mode 100644 index 60d674e48cd6b5..00000000000000 --- a/x-pack/test/rbac_api_integration/apis/privileges/index.js +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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'; - -export default function ({ getService }) { - describe('privileges', () => { - it(`get should return privileges`, async () => { - const supertest = getService('supertest'); - const kibanaServer = getService('kibanaServer'); - const version = await kibanaServer.version.get(); - - await supertest - .get(`/api/security/v1/privileges`) - .expect(200) - .then(resp => { - expect(resp.body).to.eql({ - global: { - all: [`version:${version}`, 'action:*'], - read: [ - `version:${version}`, - 'action:login', - 'action:saved_objects/config/get', - 'action:saved_objects/config/bulk_get', - 'action:saved_objects/config/find', - 'action:saved_objects/timelion-sheet/get', - 'action:saved_objects/timelion-sheet/bulk_get', - 'action:saved_objects/timelion-sheet/find', - 'action:saved_objects/graph-workspace/get', - 'action:saved_objects/graph-workspace/bulk_get', - 'action:saved_objects/graph-workspace/find', - 'action:saved_objects/index-pattern/get', - 'action:saved_objects/index-pattern/bulk_get', - 'action:saved_objects/index-pattern/find', - 'action:saved_objects/visualization/get', - 'action:saved_objects/visualization/bulk_get', - 'action:saved_objects/visualization/find', - 'action:saved_objects/search/get', - 'action:saved_objects/search/bulk_get', - 'action:saved_objects/search/find', - 'action:saved_objects/dashboard/get', - 'action:saved_objects/dashboard/bulk_get', - 'action:saved_objects/dashboard/find', - 'action:saved_objects/url/get', - 'action:saved_objects/url/bulk_get', - 'action:saved_objects/url/find', - 'action:saved_objects/server/get', - 'action:saved_objects/server/bulk_get', - 'action:saved_objects/server/find', - ], - }, - space: { - all: [ - `version:${version}`, - 'action:login', - 'action:saved_objects/config/create', - 'action:saved_objects/config/bulk_create', - 'action:saved_objects/config/delete', - 'action:saved_objects/config/get', - 'action:saved_objects/config/bulk_get', - 'action:saved_objects/config/find', - 'action:saved_objects/config/update', - 'action:saved_objects/timelion-sheet/create', - 'action:saved_objects/timelion-sheet/bulk_create', - 'action:saved_objects/timelion-sheet/delete', - 'action:saved_objects/timelion-sheet/get', - 'action:saved_objects/timelion-sheet/bulk_get', - 'action:saved_objects/timelion-sheet/find', - 'action:saved_objects/timelion-sheet/update', - 'action:saved_objects/graph-workspace/create', - 'action:saved_objects/graph-workspace/bulk_create', - 'action:saved_objects/graph-workspace/delete', - 'action:saved_objects/graph-workspace/get', - 'action:saved_objects/graph-workspace/bulk_get', - 'action:saved_objects/graph-workspace/find', - 'action:saved_objects/graph-workspace/update', - 'action:saved_objects/index-pattern/create', - 'action:saved_objects/index-pattern/bulk_create', - 'action:saved_objects/index-pattern/delete', - 'action:saved_objects/index-pattern/get', - 'action:saved_objects/index-pattern/bulk_get', - 'action:saved_objects/index-pattern/find', - 'action:saved_objects/index-pattern/update', - 'action:saved_objects/visualization/create', - 'action:saved_objects/visualization/bulk_create', - 'action:saved_objects/visualization/delete', - 'action:saved_objects/visualization/get', - 'action:saved_objects/visualization/bulk_get', - 'action:saved_objects/visualization/find', - 'action:saved_objects/visualization/update', - 'action:saved_objects/search/create', - 'action:saved_objects/search/bulk_create', - 'action:saved_objects/search/delete', - 'action:saved_objects/search/get', - 'action:saved_objects/search/bulk_get', - 'action:saved_objects/search/find', - 'action:saved_objects/search/update', - 'action:saved_objects/dashboard/create', - 'action:saved_objects/dashboard/bulk_create', - 'action:saved_objects/dashboard/delete', - 'action:saved_objects/dashboard/get', - 'action:saved_objects/dashboard/bulk_get', - 'action:saved_objects/dashboard/find', - 'action:saved_objects/dashboard/update', - 'action:saved_objects/url/create', - 'action:saved_objects/url/bulk_create', - 'action:saved_objects/url/delete', - 'action:saved_objects/url/get', - 'action:saved_objects/url/bulk_get', - 'action:saved_objects/url/find', - 'action:saved_objects/url/update', - 'action:saved_objects/server/create', - 'action:saved_objects/server/bulk_create', - 'action:saved_objects/server/delete', - 'action:saved_objects/server/get', - 'action:saved_objects/server/bulk_get', - 'action:saved_objects/server/find', - 'action:saved_objects/server/update', - ], - read: [ - `version:${version}`, - 'action:login', - 'action:saved_objects/config/get', - 'action:saved_objects/config/bulk_get', - 'action:saved_objects/config/find', - 'action:saved_objects/timelion-sheet/get', - 'action:saved_objects/timelion-sheet/bulk_get', - 'action:saved_objects/timelion-sheet/find', - 'action:saved_objects/graph-workspace/get', - 'action:saved_objects/graph-workspace/bulk_get', - 'action:saved_objects/graph-workspace/find', - 'action:saved_objects/space/get', - 'action:saved_objects/space/bulk_get', - 'action:saved_objects/space/find', - 'action:saved_objects/index-pattern/get', - 'action:saved_objects/index-pattern/bulk_get', - 'action:saved_objects/index-pattern/find', - 'action:saved_objects/visualization/get', - 'action:saved_objects/visualization/bulk_get', - 'action:saved_objects/visualization/find', - 'action:saved_objects/search/get', - 'action:saved_objects/search/bulk_get', - 'action:saved_objects/search/find', - 'action:saved_objects/dashboard/get', - 'action:saved_objects/dashboard/bulk_get', - 'action:saved_objects/dashboard/find', - 'action:saved_objects/url/get', - 'action:saved_objects/url/bulk_get', - 'action:saved_objects/url/find', - 'action:saved_objects/server/get', - 'action:saved_objects/server/bulk_get', - 'action:saved_objects/server/find', - ], - }, - }); - }); - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/common/config.js b/x-pack/test/saved_object_api_integration/common/config.ts similarity index 84% rename from x-pack/test/saved_object_api_integration/common/config.js rename to x-pack/test/saved_object_api_integration/common/config.ts index 15dce485d5dc21..48bf64f54c8fd9 100644 --- a/x-pack/test/saved_object_api_integration/common/config.js +++ b/x-pack/test/saved_object_api_integration/common/config.ts @@ -4,23 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import path from 'path'; import { resolveKibanaPath } from '@kbn/plugin-helpers'; +import path from 'path'; +import { TestInvoker } from './lib/types'; import { EsProvider } from './services/es'; +interface CreateTestConfigOptions { + license: string; + disabledPlugins?: [string]; +} -export function createTestConfig(name, { license = 'trial', disabledPlugins = [] } = {}) { - - return async function ({ readConfigFile }) { +export function createTestConfig(name: string, options: CreateTestConfigOptions) { + const { license = 'trial', disabledPlugins = [] } = options; + return async ({ readConfigFile }: TestInvoker) => { const config = { kibana: { api: await readConfigFile(resolveKibanaPath('test/api_integration/config.js')), - functional: await readConfigFile(require.resolve('../../../../test/functional/config.js')) + functional: await readConfigFile(require.resolve('../../../../test/functional/config.js')), }, xpack: { - api: await readConfigFile(require.resolve('../../api_integration/config.js')) - } + api: await readConfigFile(require.resolve('../../api_integration/config.js')), + }, }; return { @@ -39,7 +44,7 @@ export function createTestConfig(name, { license = 'trial', disabledPlugins = [] }, esArchiver: { - directory: path.join(__dirname, 'fixtures', 'es_archiver') + directory: path.join(__dirname, 'fixtures', 'es_archiver'), }, esTestCluster: { 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 c80f1672ce09ac..5da6fb43ff1d45 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 @@ -337,12 +337,12 @@ "value": { "index": ".kibana", "type": "doc", - "id": "chapo:8121a00-8efd-21e7-1cb3-34ab96643444", + "id": "globaltype:8121a00-8efd-21e7-1cb3-34ab966434445", "source": { - "type": "chapo", + "type": "globaltype", "updated_at": "2017-09-21T18:59:16.270Z", - "chapo": { - "name": "El Chapo" + "globaltype": { + "name": "My favorite global object" } } } 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 8f77fccf872de7..6cd530559c8f2d 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 @@ -303,7 +303,7 @@ } } }, - "chapo": { + "globaltype": { "properties": { "name": { "type": "text", 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 index 7598fe587af7f9..1417444df0661f 100644 --- 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 @@ -12,7 +12,7 @@ export default function (kibana) { name: 'namespace_agnostic_type_plugin', uiExports: { savedObjectsSchema: { - chapo: { + globaltype: { isNamespaceAgnostic: true } }, 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 index 4a11c97b6432db..b30a2c3877b885 100644 --- 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 @@ -1,5 +1,5 @@ { - "chapo": { + "globaltype": { "properties": { "name": { "type": "text", diff --git a/x-pack/test/saved_object_api_integration/common/lib/authentication.js b/x-pack/test/saved_object_api_integration/common/lib/authentication.ts similarity index 80% rename from x-pack/test/saved_object_api_integration/common/lib/authentication.js rename to x-pack/test/saved_object_api_integration/common/lib/authentication.ts index af32ecdce466ea..92888f3263ed9c 100644 --- a/x-pack/test/saved_object_api_integration/common/lib/authentication.js +++ b/x-pack/test/saved_object_api_integration/common/lib/authentication.ts @@ -7,50 +7,50 @@ export const AUTHENTICATION = { NOT_A_KIBANA_USER: { USERNAME: 'not_a_kibana_user', - PASSWORD: 'password' + PASSWORD: 'password', }, SUPERUSER: { USERNAME: 'elastic', - PASSWORD: 'changeme' + PASSWORD: 'changeme', }, KIBANA_LEGACY_USER: { USERNAME: 'a_kibana_legacy_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_LEGACY_DASHBOARD_ONLY_USER: { USERNAME: 'a_kibana_legacy_dashboard_only_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_DUAL_PRIVILEGES_USER: { USERNAME: 'a_kibana_dual_privileges_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER: { USERNAME: 'a_kibana_dual_privileges_dashboard_only_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_USER: { USERNAME: 'a_kibana_rbac_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_DASHBOARD_ONLY_USER: { USERNAME: 'a_kibana_rbac_dashboard_only_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_DEFAULT_SPACE_ALL_USER: { USERNAME: 'a_kibana_rbac_default_space_all_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_DEFAULT_SPACE_READ_USER: { USERNAME: 'a_kibana_rbac_default_space_read_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_SPACE_1_ALL_USER: { USERNAME: 'a_kibana_rbac_space_1_all_user', - PASSWORD: 'password' + PASSWORD: 'password', }, KIBANA_RBAC_SPACE_1_READ_USER: { USERNAME: 'a_kibana_rbac_space_1_read_user', - PASSWORD: 'password' + PASSWORD: 'password', }, }; 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.ts similarity index 72% rename from x-pack/test/saved_object_api_integration/common/lib/create_users_and_roles.js rename to x-pack/test/saved_object_api_integration/common/lib/create_users_and_roles.ts index 1074ae12cb4967..66bcd0e5364291 100644 --- 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.ts @@ -5,102 +5,100 @@ */ import { AUTHENTICATION } from './authentication'; -export const createUsersAndRoles = async (es, supertest) => { - await supertest.put('/api/security/role/kibana_legacy_user') - .send({ - elasticsearch: { - indices: [{ +export const createUsersAndRoles = async (es: any, supertest: 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: [{ + 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: [{ + 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: [{ + 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'] - }] + 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_all_user').send({ + kibana: { + space: { + default: ['all'], + }, + }, + }); + + await supertest.put('/api/security/role/kibana_rbac_default_space_read_user').send({ + kibana: { + space: { + default: ['read'], }, - 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_all_user') - .send({ - kibana: { - space: { - default: ['all'] - } - } - }); - - await supertest.put('/api/security/role/kibana_rbac_default_space_read_user') - .send({ - kibana: { - space: { - default: ['read'] - } - } - }); - - await supertest.put('/api/security/role/kibana_rbac_space_1_all_user') - .send({ - kibana: { - space: { - space_1: ['all'] - } - } - }); - - await supertest.put('/api/security/role/kibana_rbac_space_1_read_user') - .send({ - kibana: { - space: { - space_1: ['read'] - } - } - }); + }, + }); + + await supertest.put('/api/security/role/kibana_rbac_space_1_all_user').send({ + kibana: { + space: { + space_1: ['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, @@ -109,7 +107,7 @@ export const createUsersAndRoles = async (es, supertest) => { roles: [], full_name: 'not a kibana user', email: 'not_a_kibana_user@elastic.co', - } + }, }); await es.shield.putUser({ @@ -119,17 +117,17 @@ export const createUsersAndRoles = async (es, supertest) => { 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"], + 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({ @@ -139,17 +137,17 @@ export const createUsersAndRoles = async (es, supertest) => { 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"], + 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({ @@ -159,17 +157,17 @@ export const createUsersAndRoles = async (es, supertest) => { 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"], + 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({ @@ -179,7 +177,7 @@ export const createUsersAndRoles = async (es, supertest) => { roles: ['kibana_rbac_default_space_all_user'], full_name: 'a kibana default space all user', email: 'a_kibana_rbac_default_space_all_user@elastic.co', - } + }, }); await es.shield.putUser({ @@ -189,7 +187,7 @@ export const createUsersAndRoles = async (es, supertest) => { roles: ['kibana_rbac_default_space_read_user'], full_name: 'a kibana default space read-only user', email: 'a_kibana_rbac_default_space_read_user@elastic.co', - } + }, }); await es.shield.putUser({ @@ -199,7 +197,7 @@ export const createUsersAndRoles = async (es, supertest) => { roles: ['kibana_rbac_space_1_all_user'], full_name: 'a kibana rbac space 1 all user', email: 'a_kibana_rbac_space_1_all_user@elastic.co', - } + }, }); await es.shield.putUser({ @@ -209,6 +207,6 @@ export const createUsersAndRoles = async (es, supertest) => { 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/lib/space_test_utils.js b/x-pack/test/saved_object_api_integration/common/lib/space_test_utils.ts similarity index 75% rename from x-pack/test/saved_object_api_integration/common/lib/space_test_utils.js rename to x-pack/test/saved_object_api_integration/common/lib/space_test_utils.ts index e9aa3a09a78f43..1619d77761c842 100644 --- a/x-pack/test/saved_object_api_integration/common/lib/space_test_utils.js +++ b/x-pack/test/saved_object_api_integration/common/lib/space_test_utils.ts @@ -6,19 +6,19 @@ import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; -export function getUrlPrefix(spaceId) { +export function getUrlPrefix(spaceId: string) { return spaceId && spaceId !== DEFAULT_SPACE_ID ? `/s/${spaceId}` : ``; } -export function getIdPrefix(spaceId) { +export function getIdPrefix(spaceId: string) { return spaceId === DEFAULT_SPACE_ID ? '' : `${spaceId}-`; } -export function getExpectedSpaceIdProperty(spaceId) { +export function getExpectedSpaceIdProperty(spaceId: string) { if (spaceId === DEFAULT_SPACE_ID) { return {}; } return { - spaceId + spaceId, }; } diff --git a/x-pack/test/saved_object_api_integration/common/lib/spaces.js b/x-pack/test/saved_object_api_integration/common/lib/spaces.ts similarity index 98% rename from x-pack/test/saved_object_api_integration/common/lib/spaces.js rename to x-pack/test/saved_object_api_integration/common/lib/spaces.ts index 905b360c999497..a9c552d4ccd789 100644 --- a/x-pack/test/saved_object_api_integration/common/lib/spaces.js +++ b/x-pack/test/saved_object_api_integration/common/lib/spaces.ts @@ -13,5 +13,5 @@ export const SPACES = { }, DEFAULT: { spaceId: 'default', - } + }, }; diff --git a/x-pack/test/saved_object_api_integration/common/lib/types.ts b/x-pack/test/saved_object_api_integration/common/lib/types.ts new file mode 100644 index 00000000000000..fc6d3d8745fb93 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/lib/types.ts @@ -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. + */ + +export type DescribeFn = (text: string, fn: () => void) => void; + +export interface TestDefinitionAuthentication { + username?: string; + password?: string; +} + +export type LoadTestFileFn = (path: string) => string; + +export type GetServiceFn = (service: string) => any; + +export type ReadConfigFileFn = (path: string) => any; + +export interface TestInvoker { + getService: GetServiceFn; + loadTestFile: LoadTestFileFn; + readConfigFile: ReadConfigFileFn; +} diff --git a/x-pack/test/saved_object_api_integration/common/services/es.js b/x-pack/test/saved_object_api_integration/common/services/es.ts similarity index 82% rename from x-pack/test/saved_object_api_integration/common/services/es.js rename to x-pack/test/saved_object_api_integration/common/services/es.ts index c4fa7c504e12cd..f5ef3be4b4bde2 100644 --- a/x-pack/test/saved_object_api_integration/common/services/es.js +++ b/x-pack/test/saved_object_api_integration/common/services/es.ts @@ -8,13 +8,14 @@ import { format as formatUrl } from 'url'; import elasticsearch from 'elasticsearch'; import shieldPlugin from '../../../../server/lib/esjs_shield_plugin'; +import { TestInvoker } from '../lib/types'; -export function EsProvider({ getService }) { +export function EsProvider({ getService }: TestInvoker) { const config = getService('config'); return new elasticsearch.Client({ host: formatUrl(config.get('servers.elasticsearch')), requestTimeout: config.get('timeouts.esRequestTimeout'), - plugins: [shieldPlugin] + plugins: [shieldPlugin], }); } diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/bulk_get.ts b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/bulk_get.ts new file mode 100644 index 00000000000000..ab62907cb897c3 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/bulk_get.ts @@ -0,0 +1,147 @@ +/* + * 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 { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { getIdPrefix, getUrlPrefix } from '../../../common/lib/space_test_utils'; +import { DescribeFn, TestDefinitionAuthentication } from '../../../common/lib/types'; + +interface BulkGetTest { + statusCode: number; + response: (resp: any) => void; +} + +interface BulkGetTests { + default: BulkGetTest; +} + +interface BulkGetTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + otherSpaceId?: string; + tests: BulkGetTests; +} + +export function bulkGetTestSuiteFactory(esArchiver: any, supertest: SuperTest) { + const makeBulkGetTest = (describeFn: DescribeFn) => ( + description: string, + definition: BulkGetTestDefinition + ) => { + const { auth = {}, spaceId, otherSpaceId, tests } = definition; + + const BULK_REQUESTS = [ + { + type: 'visualization', + id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', + }, + { + type: 'dashboard', + id: 'does not exist', + }, + ]; + + const createBulkRequests = (requestSpaceId: string) => + BULK_REQUESTS.map(r => ({ + ...r, + id: `${getIdPrefix(requestSpaceId)}${r.id}`, + })); + + describeFn(description, () => { + before(() => esArchiver.load('saved_objects/spaces')); + after(() => esArchiver.unload('saved_objects/spaces')); + + it(`should return ${tests.default.statusCode}`, async () => { + await supertest + .post(`${getUrlPrefix(spaceId || DEFAULT_SPACE_ID)}/api/saved_objects/_bulk_get`) + .auth(auth.username, auth.password) + .send(createBulkRequests(otherSpaceId || spaceId || DEFAULT_SPACE_ID)) + .expect(tests.default.statusCode) + .then(tests.default.response); + }); + }); + }; + + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + // eslint-disable-next-line max-len + message: `action [indices:data/read/mget] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/mget] is unauthorized for user [${username}]`, + }); + }; + + const expectRbacForbidden = (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: `Unable to bulk_get dashboard,visualization, missing action:saved_objects/dashboard/bulk_get,action:saved_objects/visualization/bulk_get`, + }); + }; + + const createExpectNotFoundResults = (spaceId: string) => (resp: any) => { + expect(resp.body).to.eql({ + saved_objects: [ + { + id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, + type: 'visualization', + error: { + statusCode: 404, + message: 'Not found', + }, + }, + { + id: `${getIdPrefix(spaceId)}does not exist`, + type: 'dashboard', + error: { + statusCode: 404, + message: 'Not found', + }, + }, + ], + }); + }; + + const createExpectResults = (spaceId = DEFAULT_SPACE_ID) => (resp: any) => { + expect(resp.body).to.eql({ + saved_objects: [ + { + id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, + type: 'visualization', + updated_at: '2017-09-21T18:51:23.794Z', + version: resp.body.saved_objects[0].version, + attributes: { + title: 'Count of requests', + description: '', + version: 1, + // cheat for some of the more complex attributes + visState: resp.body.saved_objects[0].attributes.visState, + uiStateJSON: resp.body.saved_objects[0].attributes.uiStateJSON, + kibanaSavedObjectMeta: resp.body.saved_objects[0].attributes.kibanaSavedObjectMeta, + }, + }, + { + id: `${getIdPrefix(spaceId)}does not exist`, + type: 'dashboard', + error: { + statusCode: 404, + message: 'Not found', + }, + }, + ], + }); + }; + + const bulkGetTest = makeBulkGetTest(describe); + bulkGetTest.only = makeBulkGetTest(describe.only); + + return { + bulkGetTest, + createExpectLegacyForbidden, + createExpectNotFoundResults, + createExpectResults, + expectRbacForbidden, + }; +} 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.ts similarity index 56% rename from x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.js rename to x-pack/test/saved_object_api_integration/common/suites/saved_objects/create.ts index 4df092e523382f..38b3592098b459 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.ts @@ -4,21 +4,35 @@ * you may not use this file except in compliance with the Elastic License. */ import expect from 'expect.js'; -import { getUrlPrefix } from '../../lib/space_test_utils'; import { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { DescribeFn, TestDefinitionAuthentication } from '../../../common/lib/types'; +import { getUrlPrefix } from '../../lib/space_test_utils'; -export function createTestSuiteFactory(es, esArchiver, supertest) { +interface CreateTest { + statusCode: number; + response: (resp: any) => void; +} + +interface CreateTests { + spaceAware: CreateTest; + notSpaceAware: CreateTest; +} + +interface CreateTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + tests: CreateTests; +} + +export function createTestSuiteFactory(es: any, esArchiver: any, supertest: SuperTest) { const spaceAwareType = 'visualization'; - const notSpaceAwareType = 'chapo'; - - const makeCreateTest = describeFn => (description, { - auth = { - username: undefined, - password: undefined - }, - spaceId, - tests, - }) => { + const notSpaceAwareType = 'globaltype'; + + const makeCreateTest = (describeFn: DescribeFn) => ( + description: string, + definition: CreateTestDefinition + ) => { + const { auth = {}, spaceId = DEFAULT_SPACE_ID, tests } = definition; describeFn(description, () => { before(() => esArchiver.load('saved_objects/spaces')); after(() => esArchiver.unload('saved_objects/spaces')); @@ -28,8 +42,8 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { .auth(auth.username, auth.password) .send({ attributes: { - title: 'My favorite vis' - } + title: 'My favorite vis', + }, }) .expect(tests.spaceAware.statusCode) .then(tests.spaceAware.response); @@ -42,23 +56,43 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { .send({ attributes: { name: `Can't be contained to a space`, - } + }, }) .expect(tests.notSpaceAware.statusCode) .then(tests.notSpaceAware.response); }); - }); }; 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}$/); + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + 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}]`, + }); + }; + + const createExpectRbacForbidden = (type: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: `Unable to create ${type}, missing action:saved_objects/${type}/create`, + }); + }; + + const createExpectSpaceAwareResults = (spaceId = DEFAULT_SPACE_ID) => async (resp: any) => { + expect(resp.body) + .to.have.property('id') + .match(/^[0-9a-f-]{36}$/); // loose ISO8601 UTC time with milliseconds validation - expect(resp.body).to.have.property('updated_at').match(/^[\d-]{10}T[\d:\.]{12}Z$/); + expect(resp.body) + .to.have.property('updated_at') + .match(/^[\d-]{10}T[\d:\.]{12}Z$/); expect(resp.body).to.eql({ id: resp.body.id, @@ -66,8 +100,8 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { updated_at: resp.body.updated_at, version: 1, attributes: { - title: 'My favorite vis' - } + title: 'My favorite vis', + }, }); const expectedSpacePrefix = spaceId === DEFAULT_SPACE_ID ? '' : `${spaceId}:`; @@ -76,12 +110,10 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { const { _source } = await es.get({ id: `${expectedSpacePrefix}${spaceAwareType}:${resp.body.id}`, type: 'doc', - index: '.kibana' + index: '.kibana', }); - const { - namespace: actualNamespace - } = _source; + const { namespace: actualNamespace } = _source; if (spaceId === DEFAULT_SPACE_ID) { expect(actualNamespace).to.eql(undefined); @@ -90,11 +122,15 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { } }; - const expectNotSpaceAwareResults = () => async (resp) => { - expect(resp.body).to.have.property('id').match(/^[0-9a-f-]{36}$/); + const expectNotSpaceAwareResults = async (resp: any) => { + expect(resp.body) + .to.have.property('id') + .match(/^[0-9a-f-]{36}$/); // loose ISO8601 UTC time with milliseconds validation - expect(resp.body).to.have.property('updated_at').match(/^[\d-]{10}T[\d:\.]{12}Z$/); + expect(resp.body) + .to.have.property('updated_at') + .match(/^[\d-]{10}T[\d:\.]{12}Z$/); expect(resp.body).to.eql({ id: resp.body.id, @@ -103,28 +139,27 @@ export function createTestSuiteFactory(es, esArchiver, supertest) { version: 1, attributes: { name: `Can't be contained to a space`, - } + }, }); // query ES directory to ensure namespace wasn't specified const { _source } = await es.get({ id: `${notSpaceAwareType}:${resp.body.id}`, type: 'doc', - index: '.kibana' + index: '.kibana', }); - const { - namespace: actualNamespace - } = _source; + const { namespace: actualNamespace } = _source; expect(actualNamespace).to.eql(undefined); }; return { createTest, + createExpectLegacyForbidden, createExpectSpaceAwareResults, expectNotSpaceAwareResults, - notSpaceAwareType, - spaceAwareType, + expectNotSpaceAwareRbacForbidden: createExpectRbacForbidden(notSpaceAwareType), + expectSpaceAwareRbacForbidden: createExpectRbacForbidden(spaceAwareType), }; } diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/delete.ts b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/delete.ts new file mode 100644 index 00000000000000..3f54b4238399b7 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/delete.ts @@ -0,0 +1,122 @@ +/* + * 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 { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { DescribeFn, TestDefinitionAuthentication } from '../../../common/lib/types'; +import { getIdPrefix, getUrlPrefix } from '../../lib/space_test_utils'; + +interface DeleteTest { + statusCode: number; + response: (resp: any) => void; +} + +interface DeleteTests { + spaceAware: DeleteTest; + notSpaceAware: DeleteTest; + invalidId: DeleteTest; +} + +interface DeleteTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + tests: DeleteTests; +} + +export function deleteTestSuiteFactory(esArchiver: any, supertest: SuperTest) { + const makeDeleteTest = (describeFn: DescribeFn) => ( + description: string, + definition: DeleteTestDefinition + ) => { + const { auth = {}, spaceId = DEFAULT_SPACE_ID, tests } = definition; + + describeFn(description, () => { + before(() => esArchiver.load('saved_objects/spaces')); + after(() => esArchiver.unload('saved_objects/spaces')); + + it(`should return ${tests.spaceAware.statusCode} when deleting a space-aware doc`, async () => + await supertest + .delete( + `${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/${getIdPrefix( + spaceId + )}be3733a0-9efe-11e7-acb3-3dab96693fab` + ) + .auth(auth.username, auth.password) + .expect(tests.spaceAware.statusCode) + .then(tests.spaceAware.response)); + + it(`should return ${ + tests.notSpaceAware.statusCode + } when deleting a non-space-aware doc`, async () => + await supertest + .delete( + `${getUrlPrefix( + spaceId + )}/api/saved_objects/globaltype/8121a00-8efd-21e7-1cb3-34ab966434445` + ) + .auth(auth.username, auth.password) + .expect(tests.notSpaceAware.statusCode) + .then(tests.notSpaceAware.response)); + + it(`should return ${tests.invalidId.statusCode} when deleting an unknown doc`, async () => + await supertest + .delete( + `${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/${getIdPrefix( + spaceId + )}not-a-real-id` + ) + .auth(auth.username, auth.password) + .expect(tests.invalidId.statusCode) + .then(tests.invalidId.response)); + }); + }; + + const deleteTest = makeDeleteTest(describe); + deleteTest.only = makeDeleteTest(describe.only); + + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + // eslint-disable-next-line max-len + message: `action [indices:data/write/delete] is unauthorized for user [${username}]: [security_exception] action [indices:data/write/delete] is unauthorized for user [${username}]`, + }); + }; + + const expectEmpty = (resp: any) => { + expect(resp.body).to.eql({}); + }; + + const createExpectNotFound = (spaceId: string, type: string, id: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 404, + error: 'Not Found', + message: `Saved object [${type}/${getIdPrefix(spaceId)}${id}] not found`, + }); + }; + + const createExpectUnknownDocNotFound = (spaceId: string = DEFAULT_SPACE_ID) => (resp: any) => { + createExpectNotFound(spaceId, 'dashboard', `not-a-real-id`)(resp); + }; + + const createExpectRbacForbidden = (type: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: `Unable to delete ${type}, missing action:saved_objects/${type}/delete`, + }); + }; + + return { + createExpectLegacyForbidden, + createExpectUnknownDocNotFound, + deleteTest, + expectEmpty, + expectRbacSpaceAwareForbidden: createExpectRbacForbidden('dashboard'), + expectRbacNotSpaceAwareForbidden: createExpectRbacForbidden('globaltype'), + expectRbacInvalidIdForbidden: createExpectRbacForbidden('dashboard'), + }; +} diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/find.ts b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/find.ts new file mode 100644 index 00000000000000..554b5fc4928d45 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/find.ts @@ -0,0 +1,203 @@ +/* + * 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 { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { getIdPrefix, getUrlPrefix } from '../../../common/lib/space_test_utils'; +import { DescribeFn, TestDefinitionAuthentication } from '../../../common/lib/types'; + +interface FindTest { + statusCode: number; + description: string; + response: (resp: any) => void; +} + +interface FindTests { + normal: FindTest; + unknownType: FindTest; + pageBeyondTotal: FindTest; + unknownSearchField: FindTest; + noType: FindTest; +} + +interface FindTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + tests: FindTests; +} + +export function findTestSuiteFactory(esArchiver: any, supertest: SuperTest) { + const makeFindTest = (describeFn: DescribeFn) => ( + description: string, + definition: FindTestDefinition + ) => { + const { auth = {}, spaceId = DEFAULT_SPACE_ID, tests } = definition; + + describeFn(description, () => { + before(() => esArchiver.load('saved_objects/spaces')); + after(() => esArchiver.unload('saved_objects/spaces')); + + it(`should return ${tests.normal.statusCode} with ${tests.normal.description}`, async () => + await supertest + .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=visualization&fields=title`) + .auth(auth.username, auth.password) + .expect(tests.normal.statusCode) + .then(tests.normal.response)); + + describe('unknown type', () => { + it(`should return ${tests.unknownType.statusCode} with ${ + tests.unknownType.description + }`, async () => + await supertest + .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=wigwags`) + .auth(auth.username, auth.password) + .expect(tests.unknownType.statusCode) + .then(tests.unknownType.response)); + }); + + describe('page beyond total', () => { + it(`should return ${tests.pageBeyondTotal.statusCode} with ${ + tests.pageBeyondTotal.description + }`, async () => + await supertest + .get( + `${getUrlPrefix( + spaceId + )}/api/saved_objects/_find?type=visualization&page=100&per_page=100` + ) + .auth(auth.username, auth.password) + .expect(tests.pageBeyondTotal.statusCode) + .then(tests.pageBeyondTotal.response)); + }); + + describe('unknown search field', () => { + it(`should return ${tests.unknownSearchField.statusCode} with ${ + tests.unknownSearchField.description + }`, async () => + await supertest + .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=wigwags&search_fields=a`) + .auth(auth.username, auth.password) + .expect(tests.unknownSearchField.statusCode) + .then(tests.unknownSearchField.response)); + }); + + describe('no type', () => { + it(`should return ${tests.noType.statusCode} with ${tests.noType.description}`, async () => + await supertest + .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find`) + .auth(auth.username, auth.password) + .expect(tests.noType.statusCode) + .then(tests.noType.response)); + }); + }); + }; + + const findTest = makeFindTest(describe); + findTest.only = makeFindTest(describe.only); + + const createExpectEmpty = (page: number, perPage: number, total: number) => (resp: any) => { + expect(resp.body).to.eql({ + page, + per_page: perPage, + total, + saved_objects: [], + }); + }; + + const createExpectRbacForbidden = (type?: string) => (resp: any) => { + const message = type + ? `Unable to find ${type}, missing action:saved_objects/${type}/find` + : `Not authorized to find saved_object`; + + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message, + }); + }; + + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + // eslint-disable-next-line max-len + message: `action [indices:data/read/search] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/search] is unauthorized for user [${username}]`, + }); + }; + + const createExpectResults = (spaceId = DEFAULT_SPACE_ID) => (resp: any) => { + expect(resp.body).to.eql({ + page: 1, + per_page: 20, + total: 5, + saved_objects: [ + { + id: `${getIdPrefix(spaceId)}91200a00-9efd-11e7-acb3-3dab96693fab`, + type: 'index-pattern', + updated_at: '2017-09-21T18:49:16.270Z', + version: 1, + attributes: resp.body.saved_objects[0].attributes, + }, + { + id: '7.0.0-alpha1', + type: 'config', + updated_at: '2017-09-21T18:49:16.302Z', + version: 1, + attributes: resp.body.saved_objects[1].attributes, + }, + { + id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, + type: 'visualization', + updated_at: '2017-09-21T18:51:23.794Z', + version: 1, + attributes: resp.body.saved_objects[2].attributes, + }, + { + id: `${getIdPrefix(spaceId)}be3733a0-9efe-11e7-acb3-3dab96693fab`, + type: 'dashboard', + updated_at: '2017-09-21T18:57:40.826Z', + version: 1, + attributes: resp.body.saved_objects[3].attributes, + }, + { + id: `8121a00-8efd-21e7-1cb3-34ab966434445`, + type: 'globaltype', + updated_at: '2017-09-21T18:59:16.270Z', + version: 1, + attributes: { + name: 'My favorite global object', + }, + }, + ], + }); + }; + + const createExpectVisualizationResults = (spaceId = DEFAULT_SPACE_ID) => (resp: any) => { + expect(resp.body).to.eql({ + page: 1, + per_page: 20, + total: 1, + saved_objects: [ + { + type: 'visualization', + id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, + version: 1, + attributes: { + title: 'Count of requests', + }, + }, + ], + }); + }; + + return { + createExpectEmpty, + createExpectRbacForbidden, + createExpectResults, + createExpectLegacyForbidden, + createExpectVisualizationResults, + findTest, + }; +} diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/get.ts b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/get.ts new file mode 100644 index 00000000000000..7164fdfbc7f164 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/get.ts @@ -0,0 +1,130 @@ +/* + * 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 { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { DescribeFn, TestDefinitionAuthentication } from '../../../common/lib/types'; +import { getIdPrefix, getUrlPrefix } from '../../lib/space_test_utils'; + +interface GetTest { + statusCode: number; + response: (resp: any) => void; +} + +interface GetTests { + exists: GetTest; + doesntExist: GetTest; +} + +interface GetTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + tests: GetTests; +} + +export function getTestSuiteFactory(esArchiver: any, supertest: SuperTest) { + const existsId = 'dd7caf20-9efd-11e7-acb3-3dab96693fab'; + const doesntExistId = 'foobar'; + const makeGetTest = (describeFn: DescribeFn) => ( + description: string, + definition: GetTestDefinition + ) => { + const { auth = {}, spaceId = DEFAULT_SPACE_ID, tests } = definition; + + describeFn(description, () => { + before(() => esArchiver.load('saved_objects/spaces')); + after(() => esArchiver.unload('saved_objects/spaces')); + + it(`should return ${tests.exists.statusCode}`, async () => { + await supertest + .get( + `${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${getIdPrefix( + spaceId + )}${existsId}` + ) + .auth(auth.username, auth.password) + .expect(tests.exists.statusCode) + .then(tests.exists.response); + }); + + describe('document does not exist', () => { + it(`should return ${tests.doesntExist.statusCode}`, async () => { + await supertest + .get( + `${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${getIdPrefix( + spaceId + )}${doesntExistId}` + ) + .auth(auth.username, auth.password) + .expect(tests.doesntExist.statusCode) + .then(tests.doesntExist.response); + }); + }); + }); + }; + + const getTest = makeGetTest(describe); + getTest.only = makeGetTest(describe.only); + + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + // eslint-disable-next-line max-len + message: `action [indices:data/read/get] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/get] is unauthorized for user [${username}]`, + }); + }; + + const createExpectNotFound = (id: string, spaceId = DEFAULT_SPACE_ID) => (resp: any) => { + expect(resp.body).to.eql({ + error: 'Not Found', + message: `Saved object [visualization/${getIdPrefix(spaceId)}${id}] not found`, + statusCode: 404, + }); + }; + + const createExpectDoesntExistNotFound = (spaceId = DEFAULT_SPACE_ID) => { + return createExpectNotFound(doesntExistId, spaceId); + }; + + const createExpectExistsNotFound = (spaceId = DEFAULT_SPACE_ID) => { + return createExpectNotFound(existsId, spaceId); + }; + + const createExpectRbacForbidden = () => (resp: any) => { + expect(resp.body).to.eql({ + error: 'Forbidden', + message: `Unable to get visualization, missing action:saved_objects/visualization/get`, + statusCode: 403, + }); + }; + + const createExpectResults = (spaceId = DEFAULT_SPACE_ID) => (resp: any) => { + expect(resp.body).to.eql({ + id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, + type: 'visualization', + updated_at: '2017-09-21T18:51:23.794Z', + version: resp.body.version, + attributes: { + title: 'Count of requests', + description: '', + version: 1, + // cheat for some of the more complex attributes + visState: resp.body.attributes.visState, + uiStateJSON: resp.body.attributes.uiStateJSON, + kibanaSavedObjectMeta: resp.body.attributes.kibanaSavedObjectMeta, + }, + }); + }; + + return { + createExpectDoesntExistNotFound, + createExpectExistsNotFound, + createExpectLegacyForbidden, + createExpectRbacForbidden, + createExpectResults, + getTest, + }; +} diff --git a/x-pack/test/saved_object_api_integration/common/suites/saved_objects/update.ts b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/update.ts new file mode 100644 index 00000000000000..51b8bc202c9fcd --- /dev/null +++ b/x-pack/test/saved_object_api_integration/common/suites/saved_objects/update.ts @@ -0,0 +1,172 @@ +/* + * 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 { DEFAULT_SPACE_ID } from '../../../../../plugins/spaces/common/constants'; +import { getIdPrefix, getUrlPrefix } from '../../lib/space_test_utils'; +import { DescribeFn, TestDefinitionAuthentication } from '../../lib/types'; + +interface UpdateTest { + statusCode: number; + response: (resp: any) => void; +} + +interface UpdateTests { + spaceAware: UpdateTest; + notSpaceAware: UpdateTest; + doesntExist: UpdateTest; +} + +interface UpdateTestDefinition { + auth?: TestDefinitionAuthentication; + spaceId?: string; + tests: UpdateTests; +} + +export function updateTestSuiteFactory(esArchiver: any, supertest: SuperTest) { + const makeUpdateTest = (describeFn: DescribeFn) => ( + description: string, + definition: UpdateTestDefinition + ) => { + const { auth = {}, spaceId = DEFAULT_SPACE_ID, tests } = definition; + + describeFn(description, () => { + before(() => esArchiver.load('saved_objects/spaces')); + after(() => esArchiver.unload('saved_objects/spaces')); + it(`should return ${tests.spaceAware.statusCode} for a space-aware doc`, async () => { + await supertest + .put( + `${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${getIdPrefix( + spaceId + )}dd7caf20-9efd-11e7-acb3-3dab96693fab` + ) + .auth(auth.username, auth.password) + .send({ + attributes: { + title: 'My second favorite vis', + }, + }) + .expect(tests.spaceAware.statusCode) + .then(tests.spaceAware.response); + }); + + it(`should return ${tests.notSpaceAware.statusCode} for a non space-aware doc`, async () => { + await supertest + .put( + `${getUrlPrefix( + spaceId + )}/api/saved_objects/globaltype/8121a00-8efd-21e7-1cb3-34ab966434445` + ) + .auth(auth.username, auth.password) + .send({ + attributes: { + name: 'My second favorite', + }, + }) + .expect(tests.notSpaceAware.statusCode) + .then(tests.notSpaceAware.response); + }); + + describe('unknown id', () => { + it(`should return ${tests.doesntExist.statusCode}`, async () => { + await supertest + .put(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization/not an id`) + .auth(auth.username, auth.password) + .send({ + attributes: { + title: 'My second favorite vis', + }, + }) + .expect(tests.doesntExist.statusCode) + .then(tests.doesntExist.response); + }); + }); + }); + }; + + const updateTest = makeUpdateTest(describe); + updateTest.only = makeUpdateTest(describe.only); + + const createExpectLegacyForbidden = (username: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + // eslint-disable-next-line max-len + message: `action [indices:data/write/update] is unauthorized for user [${username}]: [security_exception] action [indices:data/write/update] is unauthorized for user [${username}]`, + }); + }; + + const expectSpaceAwareResults = (resp: any) => { + // loose uuid validation ignoring prefix + expect(resp.body) + .to.have.property('id') + .match(/[0-9a-f-]{36}$/); + + // loose ISO8601 UTC time with milliseconds validation + expect(resp.body) + .to.have.property('updated_at') + .match(/^[\d-]{10}T[\d:\.]{12}Z$/); + + expect(resp.body).to.eql({ + id: resp.body.id, + type: 'visualization', + updated_at: resp.body.updated_at, + version: 2, + attributes: { + title: 'My second favorite vis', + }, + }); + }; + + const expectNotSpaceAwareResults = (resp: any) => { + // loose uuid validation + expect(resp.body) + .to.have.property('id') + .match(/^[0-9a-f-]{36}$/); + + // loose ISO8601 UTC time with milliseconds validation + expect(resp.body) + .to.have.property('updated_at') + .match(/^[\d-]{10}T[\d:\.]{12}Z$/); + + expect(resp.body).to.eql({ + id: resp.body.id, + type: 'globaltype', + updated_at: resp.body.updated_at, + version: 2, + attributes: { + name: 'My second favorite', + }, + }); + }; + + const expectNotFound = (resp: any) => { + expect(resp.body).eql({ + statusCode: 404, + error: 'Not Found', + message: 'Saved object [visualization/not an id] not found', + }); + }; + + const createExpectRbacForbidden = (type: string) => (resp: any) => { + expect(resp.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: `Unable to update ${type}, missing action:saved_objects/${type}/update`, + }); + }; + + return { + createExpectLegacyForbidden, + expectDoesntExistRbacForbidden: createExpectRbacForbidden('visualization'), + expectNotSpaceAwareResults, + expectNotSpaceAwareRbacForbidden: createExpectRbacForbidden('globaltype'), + expectNotFound, + expectSpaceAwareResults, + expectSpaceAwareRbacForbidden: createExpectRbacForbidden('visualization'), + updateTest, + }; +} 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.ts similarity index 68% rename from x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.js rename to x-pack/test/saved_object_api_integration/security_and_spaces/apis/index.ts index a0c45c37a3b9ff..8dc2fec5190cd5 100644 --- 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.ts @@ -3,9 +3,11 @@ * 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"; +import { createUsersAndRoles } from '../../common/lib/create_users_and_roles'; +import { TestInvoker } from '../../common/lib/types'; -export default function ({ loadTestFile, getService }) { +// tslint:disable:no-default-export +export default function({ loadTestFile, getService }: TestInvoker) { const es = getService('es'); const supertest = getService('supertest'); diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/bulk_get.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/bulk_get.ts new file mode 100644 index 00000000000000..e984016185900b --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/bulk_get.ts @@ -0,0 +1,194 @@ +/* + * 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 '../../../common/lib/authentication'; +import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { bulkGetTestSuiteFactory } from '../../../common/suites/saved_objects/bulk_get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + const { + bulkGetTest, + createExpectLegacyForbidden, + createExpectResults, + expectRbacForbidden, + } = bulkGetTestSuiteFactory(esArchiver, supertest); + + describe('_bulk_get', () => { + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { + bulkGetTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + bulkGetTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`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: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(userWithAllAtSpace.USERNAME, { + auth: { + username: userWithAllAtSpace.USERNAME, + password: userWithAllAtSpace.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(userWithReadAtSpace.USERNAME, { + auth: { + username: userWithReadAtSpace.USERNAME, + password: userWithReadAtSpace.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + bulkGetTest(userWithAllAtOtherSpace.USERNAME, { + auth: { + username: userWithAllAtOtherSpace.USERNAME, + password: userWithAllAtOtherSpace.PASSWORD, + }, + spaceId, + tests: { + default: { + statusCode: 403, + response: expectRbacForbidden, + }, + }, + }); + }); + }); +} 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.ts similarity index 70% rename from x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/create.js rename to x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/create.ts index 8eb503d56c6647..af05cdaa5f54cf 100644 --- 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.ts @@ -4,59 +4,41 @@ * 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'; +import { TestInvoker } from '../../../common/lib/types'; +import { createTestSuiteFactory } from '../../../common/suites/saved_objects/create'; -export default function ({ getService }) { +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const es = getService('es'); const esArchiver = getService('esArchiver'); const { createTest, + createExpectLegacyForbidden, createExpectSpaceAwareResults, expectNotSpaceAwareResults, - notSpaceAwareType, - spaceAwareType, + expectNotSpaceAwareRbacForbidden, + expectSpaceAwareRbacForbidden, } = 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}]` - }); - }; - - [{ - spaceId: SPACES.DEFAULT.spaceId, - userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, - userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, - userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, - }, { - spaceId: SPACES.DEFAULT.spaceId, - userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, - userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, - userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, - }].forEach(({ - spaceId, - userWithAllAtSpace, - userWithReadAtSpace, - userWithAllAtOtherSpace - }) => { + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { createTest(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, { auth: { username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, @@ -72,7 +54,7 @@ export default function ({ getService }) { statusCode: 403, response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), }, - } + }, }); createTest(AUTHENTICATION.SUPERUSER.USERNAME, { @@ -88,9 +70,9 @@ export default function ({ getService }) { }, notSpaceAware: { statusCode: 200, - response: expectNotSpaceAwareResults(), + response: expectNotSpaceAwareResults, }, - } + }, }); createTest(AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, { @@ -108,7 +90,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, { @@ -120,13 +102,17 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), }, notSpaceAware: { statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), }, - } + }, }); createTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, { @@ -144,7 +130,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, { @@ -156,13 +142,13 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); createTest(AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, { @@ -180,7 +166,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, { @@ -192,13 +178,13 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); createTest(userWithAllAtSpace.USERNAME, { @@ -213,9 +199,9 @@ export default function ({ getService }) { }, notSpaceAware: { statusCode: 200, - response: expectNotSpaceAwareResults(), + response: expectNotSpaceAwareResults, }, - } + }, }); createTest(userWithReadAtSpace.USERNAME, { @@ -226,13 +212,13 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); createTest(userWithAllAtOtherSpace.USERNAME, { @@ -243,15 +229,14 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); }); - }); } diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/delete.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/delete.ts new file mode 100644 index 00000000000000..d5fe0cce520896 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/delete.ts @@ -0,0 +1,291 @@ +/* + * 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 '../../../common/lib/authentication'; +import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { deleteTestSuiteFactory } from '../../../common/suites/saved_objects/delete'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + describe('delete', () => { + const { + createExpectLegacyForbidden, + createExpectUnknownDocNotFound, + deleteTest, + expectEmpty, + expectRbacSpaceAwareForbidden, + expectRbacNotSpaceAwareForbidden, + expectRbacInvalidIdForbidden, + } = deleteTestSuiteFactory(esArchiver, supertest); + + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { + deleteTest(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, { + 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), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + deleteTest(AUTHENTICATION.SUPERUSER.USERNAME, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, { + 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 + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, { + 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: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + + deleteTest(userWithAllAtSpace.USERNAME, { + auth: { + username: userWithAllAtSpace.USERNAME, + password: userWithAllAtSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(userWithReadAtSpace.USERNAME, { + auth: { + username: userWithReadAtSpace.USERNAME, + password: userWithReadAtSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + + deleteTest(userWithAllAtOtherSpace.USERNAME, { + auth: { + username: userWithAllAtOtherSpace.USERNAME, + password: userWithAllAtOtherSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/find.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/find.ts new file mode 100644 index 00000000000000..e9ec47f8ee56f8 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/find.ts @@ -0,0 +1,429 @@ +/* + * 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 '../../../common/lib/authentication'; +import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { findTestSuiteFactory } from '../../../common/suites/saved_objects/find'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + describe('find', () => { + const { + createExpectEmpty, + createExpectRbacForbidden, + createExpectResults, + createExpectLegacyForbidden, + createExpectVisualizationResults, + findTest, + } = findTestSuiteFactory(esArchiver, supertest); + + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.SPACE_1.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { + describe(`${spaceId} space`, () => { + findTest(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + unknownType: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + pageBeyondTotal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + unknownSearchField: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + noType: { + description: `forbidded can't find any types`, + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + findTest(AUTHENTICATION.SUPERUSER.USERNAME, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'forbidden find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'forbidden find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'forbidden find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'forbidden find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(userWithAllAtSpace.USERNAME, { + auth: { + username: userWithAllAtSpace.USERNAME, + password: userWithAllAtSpace.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'forbidden and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'forbidden and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(userWithReadAtSpace.USERNAME, { + auth: { + username: userWithReadAtSpace.USERNAME, + password: userWithReadAtSpace.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(spaceId), + }, + unknownType: { + description: 'forbidden and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'forbidden and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(spaceId), + }, + }, + }); + + findTest(userWithAllAtOtherSpace.USERNAME, { + auth: { + username: userWithAllAtOtherSpace.USERNAME, + password: userWithAllAtOtherSpace.PASSWORD, + }, + spaceId, + tests: { + normal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectRbacForbidden('visualization'), + }, + unknownType: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + pageBeyondTotal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectRbacForbidden('visualization'), + }, + unknownSearchField: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectRbacForbidden('wigwags'), + }, + noType: { + description: `forbidded can't find any types`, + statusCode: 403, + response: createExpectRbacForbidden(), + }, + }, + }); + }); + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/get.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/get.ts new file mode 100644 index 00000000000000..0e6ecaeab96bf4 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/get.ts @@ -0,0 +1,239 @@ +/* + * 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 '../../../common/lib/authentication'; +import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { getTestSuiteFactory } from '../../../common/suites/saved_objects/get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + const { + createExpectDoesntExistNotFound, + createExpectLegacyForbidden, + createExpectRbacForbidden, + createExpectResults, + getTest, + } = getTestSuiteFactory(esArchiver, supertest); + + describe('get', () => { + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.SPACE_1.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { + getTest(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + getTest(AUTHENTICATION.SUPERUSER.USERNAME, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(`${userWithAllAtSpace.USERNAME} user`, { + auth: { + username: userWithAllAtSpace.USERNAME, + password: userWithAllAtSpace.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(`${userWithReadAtSpace.USERNAME} user`, { + auth: { + username: userWithReadAtSpace.USERNAME, + password: userWithReadAtSpace.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(spaceId), + }, + }, + }); + + getTest(`${userWithAllAtOtherSpace.USERNAME} user`, { + auth: { + username: userWithAllAtOtherSpace.USERNAME, + password: userWithAllAtOtherSpace.PASSWORD, + }, + spaceId, + tests: { + exists: { + statusCode: 403, + response: createExpectRbacForbidden(), + }, + doesntExist: { + statusCode: 403, + response: createExpectRbacForbidden(), + }, + }, + }); + }); + }); +} 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 deleted file mode 100644 index 351e71bc38278d..00000000000000 --- a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * 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_only/apis/saved_objects/index.js b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.ts similarity index 79% rename from x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/index.js rename to x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.ts index 4c15c8044436db..b0f3ceb14e8a60 100644 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/index.js +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/index.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { TestInvoker } from '../../../common/lib/types'; - -export default function ({ loadTestFile }) { +// tslint:disable:no-default-export +export default function({ loadTestFile }: TestInvoker) { describe('saved_objects', () => { loadTestFile(require.resolve('./bulk_get')); loadTestFile(require.resolve('./create')); diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/update.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/update.ts new file mode 100644 index 00000000000000..720fef5fb62b37 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/saved_objects/update.ts @@ -0,0 +1,292 @@ +/* + * 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 '../../../common/lib/authentication'; +import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { updateTestSuiteFactory } from '../../../common/suites/saved_objects/update'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + describe('update', () => { + const { + createExpectLegacyForbidden, + expectDoesntExistRbacForbidden, + expectNotSpaceAwareResults, + expectNotSpaceAwareRbacForbidden, + expectNotFound, + expectSpaceAwareRbacForbidden, + expectSpaceAwareResults, + updateTest, + } = updateTestSuiteFactory(esArchiver, supertest); + + [ + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + { + spaceId: SPACES.DEFAULT.spaceId, + userWithAllAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER, + userWithReadAtSpace: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER, + userWithAllAtOtherSpace: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER, + }, + ].forEach(({ spaceId, userWithAllAtSpace, userWithReadAtSpace, userWithAllAtOtherSpace }) => { + updateTest(`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), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + updateTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`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 + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), + }, + }, + }); + + updateTest(`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: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`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: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + + updateTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`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: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + + updateTest(userWithAllAtSpace.USERNAME, { + auth: { + username: userWithAllAtSpace.USERNAME, + password: userWithAllAtSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(userWithReadAtSpace.USERNAME, { + auth: { + username: userWithReadAtSpace.USERNAME, + password: userWithReadAtSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + + updateTest(userWithAllAtOtherSpace.USERNAME, { + auth: { + username: userWithAllAtOtherSpace.USERNAME, + password: userWithAllAtOtherSpace.PASSWORD, + }, + spaceId, + tests: { + spaceAware: { + statusCode: 403, + response: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + }); + }); +} 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.ts similarity index 91% rename from x-pack/test/saved_object_api_integration/security_and_spaces/config.js rename to x-pack/test/saved_object_api_integration/security_and_spaces/config.ts index 5873a050577d7b..81cf9d85671d18 100644 --- 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.ts @@ -6,4 +6,5 @@ import { createTestConfig } from '../common/config'; +// tslint:disable:no-default-export export default createTestConfig('security_and_spaces', { license: 'trial' }); 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.ts similarity index 78% rename from x-pack/test/saved_object_api_integration/security_only/apis/index.js rename to x-pack/test/saved_object_api_integration/security_only/apis/index.ts index 5fbea60eb56291..a4cc59af0b7305 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.ts @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ import { createUsersAndRoles } from '../../common/lib/create_users_and_roles'; +import { TestInvoker } from '../../common/lib/types'; -export default function ({ loadTestFile, getService }) { +// tslint:disable:no-default-export +export default function({ loadTestFile, getService }: TestInvoker) { const es = getService('es'); const supertest = getService('supertest'); diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.js deleted file mode 100644 index fd249749661203..00000000000000 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.js +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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'; - -export default function ({ getService }) { - const supertest = getService('supertestWithoutAuth'); - const esArchiver = getService('esArchiver'); - - const BULK_REQUESTS = [ - { - type: 'visualization', - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - }, - { - type: 'dashboard', - id: 'does not exist', - }, - { - type: 'config', - id: '7.0.0-alpha1', - }, - ]; - - describe('_bulk_get', () => { - const expectResults = resp => { - expect(resp.body).to.eql({ - saved_objects: [ - { - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - type: 'visualization', - updated_at: '2017-09-21T18:51:23.794Z', - version: resp.body.saved_objects[0].version, - attributes: { - title: 'Count of requests', - description: '', - version: 1, - // cheat for some of the more complex attributes - visState: resp.body.saved_objects[0].attributes.visState, - uiStateJSON: resp.body.saved_objects[0].attributes.uiStateJSON, - kibanaSavedObjectMeta: - resp.body.saved_objects[0].attributes.kibanaSavedObjectMeta, - }, - }, - { - id: 'does not exist', - type: 'dashboard', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - { - id: '7.0.0-alpha1', - type: 'config', - updated_at: '2017-09-21T18:49:16.302Z', - version: resp.body.saved_objects[2].version, - attributes: { - buildNum: 8467, - defaultIndex: '91200a00-9efd-11e7-acb3-3dab96693fab', - }, - }, - ], - }); - }; - - const createExpectLegacyForbidden = username => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - //eslint-disable-next-line max-len - message: `action [indices:data/read/mget] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/mget] is unauthorized for user [${username}]` - }); - }; - - const bulkGetTest = (description, { auth, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.default.statusCode}`, async () => { - await supertest - .post(`/api/saved_objects/_bulk_get`) - .auth(auth.username, auth.password) - .send(BULK_REQUESTS) - .expect(tests.default.statusCode) - .then(tests.default.response); - }); - }); - }; - - bulkGetTest(`not a kibana user`, { - auth: { - username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, - password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), - } - } - }); - - bulkGetTest(`superuser`, { - auth: { - username: AUTHENTICATION.SUPERUSER.USERNAME, - password: AUTHENTICATION.SUPERUSER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`kibana legacy user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`kibana legacy dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`kibana dual-privileges user`, { - auth: { - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`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, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`kibana rbac user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - - bulkGetTest(`kibana rbac dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - default: { - statusCode: 200, - response: expectResults, - }, - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.ts b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.ts new file mode 100644 index 00000000000000..07f5455cd8ae2b --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/bulk_get.ts @@ -0,0 +1,186 @@ +/* + * 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 '../../../common/lib/authentication'; +import { TestInvoker } from '../../../common/lib/types'; +import { bulkGetTestSuiteFactory } from '../../../common/suites/saved_objects/bulk_get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + const { bulkGetTest, createExpectLegacyForbidden, createExpectResults } = bulkGetTestSuiteFactory( + esArchiver, + supertest + ); + + describe('_bulk_get', () => { + bulkGetTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + bulkGetTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`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, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 200, + response: createExpectResults(), + }, + }, + }); + + bulkGetTest(`kibana rbac default space all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + }, + }); + + bulkGetTest(`kibana rbac default space read user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + }, + }); + + bulkGetTest(`kibana rbac space 1 all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + }, + }); + + bulkGetTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.PASSWORD, + }, + tests: { + default: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + }, + }); + }); +} 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.ts similarity index 65% rename from x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.js rename to x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/create.ts index c7a0b0e4e71d2a..0390bac48d4d53 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.ts @@ -4,42 +4,26 @@ * 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 { TestInvoker } from '../../../common/lib/types'; import { createTestSuiteFactory } from '../../../common/suites/saved_objects/create'; -export default function ({ getService }) { +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const es = getService('es'); const esArchiver = getService('esArchiver'); const { createTest, + createExpectLegacyForbidden, createExpectSpaceAwareResults, expectNotSpaceAwareResults, - notSpaceAwareType, - spaceAwareType, + expectNotSpaceAwareRbacForbidden, + expectSpaceAwareRbacForbidden, } = 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}]` - }); - }; - createTest(`not a kibana user`, { auth: { username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, @@ -54,7 +38,7 @@ export default function ({ getService }) { statusCode: 403, response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), }, - } + }, }); createTest(`superuser`, { @@ -69,9 +53,9 @@ export default function ({ getService }) { }, notSpaceAware: { statusCode: 200, - response: expectNotSpaceAwareResults(), + response: expectNotSpaceAwareResults, }, - } + }, }); createTest(`kibana legacy user`, { @@ -88,7 +72,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(`kibana legacy dashboard only user`, { @@ -99,13 +83,17 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), }, notSpaceAware: { statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), }, - } + }, }); createTest(`kibana dual-privileges user`, { @@ -122,7 +110,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(`kibana dual-privileges dashboard only user`, { @@ -133,13 +121,13 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); createTest(`kibana rbac user`, { @@ -156,7 +144,7 @@ export default function ({ getService }) { statusCode: 200, response: expectNotSpaceAwareResults, }, - } + }, }); createTest(`kibana rbac dashboard only user`, { @@ -167,13 +155,13 @@ export default function ({ getService }) { tests: { spaceAware: { statusCode: 403, - response: createExpectRbacForbidden(spaceAwareType), + response: expectSpaceAwareRbacForbidden, }, notSpaceAware: { statusCode: 403, - response: createExpectRbacForbidden(notSpaceAwareType), + response: expectNotSpaceAwareRbacForbidden, }, - } + }, }); createTest(`kibana rbac default space all user`, { @@ -184,15 +172,17 @@ export default function ({ getService }) { 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_ALL_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_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_ALL_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), }, - } + }, }); createTest(`kibana rbac default space read user`, { @@ -203,15 +193,17 @@ export default function ({ getService }) { 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_READ_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_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_READ_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), }, - } + }, }); createTest(`kibana rbac space 1 all user`, { @@ -222,15 +214,17 @@ export default function ({ getService }) { 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_ALL_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_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_ALL_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), }, - } + }, }); createTest(`kibana rbac space 1 readonly user`, { @@ -241,15 +235,17 @@ export default function ({ getService }) { 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_READ_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_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_READ_USER.USERNAME), + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), }, - } + }, }); }); } diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.js deleted file mode 100644 index 9656820b566952..00000000000000 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.js +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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'; - -export default function ({ getService }) { - const supertest = getService('supertestWithoutAuth'); - const esArchiver = getService('esArchiver'); - - describe('delete', () => { - - const expectEmpty = (resp) => { - expect(resp.body).to.eql({}); - }; - - const expectNotFound = (resp) => { - expect(resp.body).to.eql({ - statusCode: 404, - error: 'Not Found', - message: 'Saved object [dashboard/not-a-real-id] not found' - }); - }; - - const expectRbacForbidden = resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - message: `Unable to delete dashboard, missing action:saved_objects/dashboard/delete` - }); - }; - - const createExpectLegacyForbidden = (username, action) => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - //eslint-disable-next-line max-len - message: `action [indices:data/${action}] is unauthorized for user [${username}]: [security_exception] action [indices:data/${action}] is unauthorized for user [${username}]` - }); - }; - - const deleteTest = (description, { auth, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.actualId.statusCode} when deleting a doc`, async () => ( - await supertest - .delete(`/api/saved_objects/dashboard/be3733a0-9efe-11e7-acb3-3dab96693fab`) - .auth(auth.username, auth.password) - .expect(tests.actualId.statusCode) - .then(tests.actualId.response) - )); - - it(`should return ${tests.invalidId.statusCode} when deleting an unknown doc`, async () => ( - await supertest - .delete(`/api/saved_objects/dashboard/not-a-real-id`) - .auth(auth.username, auth.password) - .expect(tests.invalidId.statusCode) - .then(tests.invalidId.response) - )); - }); - }; - - deleteTest(`not a kibana user`, { - auth: { - username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, - password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, 'write/delete'), - }, - invalidId: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, 'write/delete'), - } - } - }); - - deleteTest(`superuser`, { - auth: { - username: AUTHENTICATION.SUPERUSER.USERNAME, - password: AUTHENTICATION.SUPERUSER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 200, - response: expectEmpty, - }, - invalidId: { - statusCode: 404, - response: expectNotFound, - } - } - }); - - deleteTest(`kibana legacy user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 200, - response: expectEmpty, - }, - invalidId: { - statusCode: 404, - response: expectNotFound, - } - } - }); - - deleteTest(`kibana legacy dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, 'write/delete'), - }, - invalidId: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, 'write/delete'), - } - } - }); - - deleteTest(`kibana dual-privileges user`, { - auth: { - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 200, - response: expectEmpty, - }, - invalidId: { - statusCode: 404, - response: expectNotFound, - } - } - }); - - deleteTest(`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, - }, - tests: { - actualId: { - statusCode: 403, - response: expectRbacForbidden, - }, - invalidId: { - statusCode: 403, - response: expectRbacForbidden, - } - } - }); - - deleteTest(`kibana rbac user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 200, - response: expectEmpty, - }, - invalidId: { - statusCode: 404, - response: expectNotFound, - } - } - }); - - deleteTest(`kibana rbac dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - actualId: { - statusCode: 403, - response: expectRbacForbidden, - }, - invalidId: { - statusCode: 403, - response: expectRbacForbidden, - } - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.ts b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.ts new file mode 100644 index 00000000000000..3ff5a851c908a8 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/delete.ts @@ -0,0 +1,309 @@ +/* + * 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 '../../../common/lib/authentication'; +import { TestInvoker } from '../../../common/lib/types'; +import { deleteTestSuiteFactory } from '../../../common/suites/saved_objects/delete'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + describe('delete', () => { + const { + createExpectLegacyForbidden, + createExpectUnknownDocNotFound, + deleteTest, + expectEmpty, + expectRbacSpaceAwareForbidden, + expectRbacNotSpaceAwareForbidden, + expectRbacInvalidIdForbidden, + } = deleteTestSuiteFactory(esArchiver, supertest); + + deleteTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + deleteTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + 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 + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), + }, + }, + }); + + deleteTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(`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, + }, + tests: { + spaceAware: { + statusCode: 403, + response: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + + deleteTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(), + }, + }, + }); + + deleteTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: expectRbacSpaceAwareForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectRbacNotSpaceAwareForbidden, + }, + invalidId: { + statusCode: 403, + response: expectRbacInvalidIdForbidden, + }, + }, + }); + + deleteTest(`kibana rbac default space all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + }, + }); + + deleteTest(`kibana rbac default space read user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + }, + }); + + deleteTest(`kibana rbac space 1 all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + }, + }); + + deleteTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + invalidId: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_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.ts similarity index 53% rename from x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.js rename to x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/find.ts index 35d51ed49d61c6..3b1d98a4f4fa3c 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.ts @@ -4,160 +4,24 @@ * 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 { TestInvoker } from '../../../common/lib/types'; +import { findTestSuiteFactory } from '../../../common/suites/saved_objects/find'; -export default function ({ getService }) { +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { const supertest = getService('supertestWithoutAuth'); const esArchiver = getService('esArchiver'); describe('find', () => { - - const expectVisualizationResults = (resp) => { - expect(resp.body).to.eql({ - page: 1, - per_page: 20, - total: 1, - saved_objects: [ - { - type: 'visualization', - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - version: 1, - attributes: { - 'title': 'Count of requests' - } - }, - ] - }); - }; - - const expectResultsWithValidTypes = (resp) => { - expect(resp.body).to.eql({ - page: 1, - per_page: 20, - total: 5, - saved_objects: [ - { - id: '91200a00-9efd-11e7-acb3-3dab96693fab', - type: 'index-pattern', - updated_at: '2017-09-21T18:49:16.270Z', - version: 1, - attributes: resp.body.saved_objects[0].attributes - }, - { - id: '7.0.0-alpha1', - type: 'config', - updated_at: '2017-09-21T18:49:16.302Z', - version: 1, - attributes: resp.body.saved_objects[1].attributes - }, - { - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - type: 'visualization', - updated_at: '2017-09-21T18:51:23.794Z', - version: 1, - attributes: resp.body.saved_objects[2].attributes - }, - { - id: 'be3733a0-9efe-11e7-acb3-3dab96693fab', - type: 'dashboard', - updated_at: '2017-09-21T18:57:40.826Z', - 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' - } - } - ] - }); - }; - - const createExpectEmpty = (page, perPage, total) => (resp) => { - expect(resp.body).to.eql({ - page: page, - per_page: perPage, - total: total, - saved_objects: [] - }); - }; - - const createExpectRbacForbidden = (type) => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - message: `Unable to find ${type}, missing action:saved_objects/${type}/find` - }); - }; - - const createExpectLegacyForbidden = (username) => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - // eslint-disable-next-line max-len - message: `action [indices:data/read/search] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/search] is unauthorized for user [${username}]` - }); - }; - - const findTest = (description, { auth, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.normal.statusCode} with ${tests.normal.description}`, async () => ( - await supertest - .get(`/api/saved_objects/_find?type=visualization&fields=title`) - .auth(auth.username, auth.password) - .expect(tests.normal.statusCode) - .then(tests.normal.response) - )); - - describe('unknown type', () => { - it(`should return ${tests.unknownType.statusCode} with ${tests.unknownType.description}`, async () => ( - await supertest - .get(`/api/saved_objects/_find?type=wigwags`) - .auth(auth.username, auth.password) - .expect(tests.unknownType.statusCode) - .then(tests.unknownType.response) - )); - }); - - describe('page beyond total', () => { - it(`should return ${tests.pageBeyondTotal.statusCode} with ${tests.pageBeyondTotal.description}`, async () => ( - await supertest - .get(`/api/saved_objects/_find?type=visualization&page=100&per_page=100`) - .auth(auth.username, auth.password) - .expect(tests.pageBeyondTotal.statusCode) - .then(tests.pageBeyondTotal.response) - )); - }); - - describe('unknown search field', () => { - it(`should return ${tests.unknownSearchField.statusCode} with ${tests.unknownSearchField.description}`, async () => ( - await supertest - .get(`/api/saved_objects/_find?type=wigwags&search_fields=a`) - .auth(auth.username, auth.password) - .expect(tests.unknownSearchField.statusCode) - .then(tests.unknownSearchField.response) - )); - }); - - describe('no type', () => { - it(`should return ${tests.noType.statusCode} with ${tests.noType.description}`, async () => ( - await supertest - .get(`/api/saved_objects/_find`) - .auth(auth.username, auth.password) - .expect(tests.noType.statusCode) - .then(tests.noType.response) - )); - }); - }); - }; + const { + createExpectEmpty, + createExpectRbacForbidden, + createExpectResults, + createExpectLegacyForbidden, + createExpectVisualizationResults, + findTest, + } = findTestSuiteFactory(esArchiver, supertest); findTest(`not a kibana user`, { auth: { @@ -189,8 +53,8 @@ export default function ({ getService }) { description: `forbidded can't find any types`, statusCode: 403, response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), - } - } + }, + }, }); findTest(`superuser`, { @@ -202,7 +66,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'empty result', @@ -222,7 +86,7 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, }, }); @@ -236,7 +100,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'empty result', @@ -256,7 +120,7 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, }, }); @@ -270,7 +134,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'empty result', @@ -290,9 +154,9 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, - } + }, }); findTest(`kibana dual-privileges user`, { @@ -304,7 +168,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'empty result', @@ -324,7 +188,7 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, }, }); @@ -338,7 +202,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'forbidden find wigwags message', @@ -358,9 +222,9 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, - } + }, }); findTest(`kibana rbac user`, { @@ -372,7 +236,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'empty result', @@ -392,7 +256,7 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), }, }, }); @@ -406,7 +270,7 @@ export default function ({ getService }) { normal: { description: 'only the visualization', statusCode: 200, - response: expectVisualizationResults, + response: createExpectVisualizationResults(), }, unknownType: { description: 'forbidden find wigwags message', @@ -426,9 +290,185 @@ export default function ({ getService }) { noType: { description: 'all objects', statusCode: 200, - response: expectResultsWithValidTypes, + response: createExpectResults(), + }, + }, + }); + + findTest(`kibana rbac default space all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.PASSWORD, + }, + tests: { + normal: { + description: 'only the visualization', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + unknownType: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + noType: { + description: 'all objects', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + }, + }); + + findTest(`kibana rbac default space read user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.PASSWORD, + }, + tests: { + normal: { + description: 'only the visualization', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + unknownType: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + noType: { + description: 'all objects', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + }, + }); + + findTest(`kibana rbac space 1 all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.PASSWORD, + }, + tests: { + normal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + unknownType: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + pageBeyondTotal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + unknownSearchField: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + noType: { + description: `forbidded can't find any types`, + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + }, + }); + + findTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.PASSWORD, + }, + tests: { + normal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + unknownType: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + pageBeyondTotal: { + description: 'forbidden login and find visualization message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), }, - } + unknownSearchField: { + description: 'forbidden login and find wigwags message', + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + noType: { + description: `forbidded can't find any types`, + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + }, }); }); } diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.js deleted file mode 100644 index 8c075aa67b98e1..00000000000000 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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'; - -export default function ({ getService }) { - const supertest = getService('supertestWithoutAuth'); - const esArchiver = getService('esArchiver'); - - describe('get', () => { - - const expectResults = (resp) => { - expect(resp.body).to.eql({ - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - type: 'visualization', - updated_at: '2017-09-21T18:51:23.794Z', - version: resp.body.version, - attributes: { - title: 'Count of requests', - description: '', - version: 1, - // cheat for some of the more complex attributes - visState: resp.body.attributes.visState, - uiStateJSON: resp.body.attributes.uiStateJSON, - kibanaSavedObjectMeta: resp.body.attributes.kibanaSavedObjectMeta - } - }); - }; - - const expectNotFound = (resp) => { - expect(resp.body).to.eql({ - error: 'Not Found', - message: 'Saved object [visualization/foobar] not found', - statusCode: 404, - }); - }; - - const createExpectLegacyForbidden = username => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - // eslint-disable-next-line max-len - message: `action [indices:data/read/get] is unauthorized for user [${username}]: [security_exception] action [indices:data/read/get] is unauthorized for user [${username}]` - }); - }; - - const getTest = (description, { auth, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.exists.statusCode}`, async () => ( - await supertest - .get(`/api/saved_objects/visualization/dd7caf20-9efd-11e7-acb3-3dab96693fab`) - .auth(auth.username, auth.password) - .expect(tests.exists.statusCode) - .then(tests.exists.response) - )); - - describe('document does not exist', () => { - it(`should return ${tests.doesntExist.statusCode}`, async () => ( - await supertest - .get(`/api/saved_objects/visualization/foobar`) - .auth(auth.username, auth.password) - .expect(tests.doesntExist.statusCode) - .then(tests.doesntExist.response) - )); - }); - }); - }; - - getTest(`not a kibana user`, { - auth: { - username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, - password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), - }, - doesntExist: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), - }, - } - }); - - getTest(`superuser`, { - auth: { - username: AUTHENTICATION.SUPERUSER.USERNAME, - password: AUTHENTICATION.SUPERUSER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`kibana legacy user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`kibana legacy dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`kibana dual-privileges user`, { - auth: { - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`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, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`kibana rbac user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - getTest(`kibana rbac dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.ts b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.ts new file mode 100644 index 00000000000000..d6ab9b1aae95d4 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/get.ts @@ -0,0 +1,244 @@ +/* + * 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 '../../../common/lib/authentication'; +import { TestInvoker } from '../../../common/lib/types'; +import { getTestSuiteFactory } from '../../../common/suites/saved_objects/get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + const { + createExpectDoesntExistNotFound, + createExpectLegacyForbidden, + createExpectResults, + getTest, + } = getTestSuiteFactory(esArchiver, supertest); + + describe('get', () => { + getTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + getTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`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, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(), + }, + }, + }); + + getTest(`kibana rbac default space all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + }, + }); + + getTest(`kibana rbac default space read user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + }, + }); + + getTest(`kibana rbac space 1 all user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + }, + }); + + getTest(`kibana rbac space 1 readonly user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.PASSWORD, + }, + tests: { + exists: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/index.ts similarity index 59% rename from x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.js rename to x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/index.ts index c74b03792ba034..1b1ae2c8a3c4de 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.js +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/index.ts @@ -4,9 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { TestInvoker } from '../../../common/lib/types'; -export default function ({ loadTestFile }) { +/* + * 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. + */ +// tslint:disable:no-default-export +export default function({ loadTestFile }: TestInvoker) { describe('saved_objects', () => { loadTestFile(require.resolve('./bulk_get')); loadTestFile(require.resolve('./create')); diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.js b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.js deleted file mode 100644 index d4c5621d061652..00000000000000 --- a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.js +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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'; - -export default function ({ getService }) { - const supertest = getService('supertestWithoutAuth'); - const esArchiver = getService('esArchiver'); - - describe('update', () => { - const expectResults = resp => { - // loose uuid validation - expect(resp.body).to.have.property('id').match(/^[0-9a-f-]{36}$/); - - // loose ISO8601 UTC time with milliseconds validation - expect(resp.body).to.have.property('updated_at').match(/^[\d-]{10}T[\d:\.]{12}Z$/); - - expect(resp.body).to.eql({ - id: resp.body.id, - type: 'visualization', - updated_at: resp.body.updated_at, - version: 2, - attributes: { - title: 'My second favorite vis' - } - }); - }; - - const expectNotFound = resp => { - expect(resp.body).eql({ - statusCode: 404, - error: 'Not Found', - message: 'Saved object [visualization/not an id] not found' - }); - }; - - const expectRbacForbidden = resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - message: `Unable to update visualization, missing action:saved_objects/visualization/update` - }); - }; - - const createExpectLegacyForbidden = (username, action) => resp => { - expect(resp.body).to.eql({ - statusCode: 403, - error: 'Forbidden', - //eslint-disable-next-line max-len - message: `action [indices:data/${action}] is unauthorized for user [${username}]: [security_exception] action [indices:data/${action}] is unauthorized for user [${username}]` - }); - }; - - const updateTest = (description, { auth, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - it(`should return ${tests.exists.statusCode}`, async () => { - await supertest - .put(`/api/saved_objects/visualization/dd7caf20-9efd-11e7-acb3-3dab96693fab`) - .auth(auth.username, auth.password) - .send({ - attributes: { - title: 'My second favorite vis' - } - }) - .expect(tests.exists.statusCode) - .then(tests.exists.response); - }); - - describe('unknown id', () => { - it(`should return ${tests.doesntExist.statusCode}`, async () => { - await supertest - .put(`/api/saved_objects/visualization/not an id`) - .auth(auth.username, auth.password) - .send({ - attributes: { - title: 'My second favorite vis' - } - }) - .expect(tests.doesntExist.statusCode) - .then(tests.doesntExist.response); - }); - }); - }); - }; - - updateTest(`not a kibana user`, { - auth: { - username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, - password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, 'write/update'), - }, - doesntExist: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, 'write/update'), - }, - } - }); - - updateTest(`superuser`, { - auth: { - username: AUTHENTICATION.SUPERUSER.USERNAME, - password: AUTHENTICATION.SUPERUSER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - updateTest(`kibana legacy user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - updateTest(`kibana legacy dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, 'write/update'), - }, - doesntExist: { - statusCode: 403, - response: createExpectLegacyForbidden(AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, 'write/update'), - }, - } - }); - - updateTest(`kibana dual-privileges user`, { - auth: { - username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, - password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - updateTest(`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, - }, - tests: { - exists: { - statusCode: 403, - response: expectRbacForbidden, - }, - doesntExist: { - statusCode: 403, - response: expectRbacForbidden, - }, - } - }); - - updateTest(`kibana rbac user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 200, - response: expectResults, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - updateTest(`kibana rbac dashboard only user`, { - auth: { - username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, - password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, - }, - tests: { - exists: { - statusCode: 403, - response: expectRbacForbidden, - }, - doesntExist: { - statusCode: 403, - response: expectRbacForbidden, - }, - } - }); - - }); -} diff --git a/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.ts b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.ts new file mode 100644 index 00000000000000..88b038f2756068 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/security_only/apis/saved_objects/update.ts @@ -0,0 +1,310 @@ +/* + * 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 '../../../common/lib/authentication'; +import { TestInvoker } from '../../../common/lib/types'; +import { updateTestSuiteFactory } from '../../../common/suites/saved_objects/update'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + + describe('update', () => { + const { + createExpectLegacyForbidden, + expectDoesntExistRbacForbidden, + expectNotSpaceAwareResults, + expectNotSpaceAwareRbacForbidden, + expectNotFound, + expectSpaceAwareRbacForbidden, + expectSpaceAwareResults, + updateTest, + } = updateTestSuiteFactory(esArchiver, supertest); + + updateTest(`not a kibana user`, { + auth: { + username: AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME, + password: AUTHENTICATION.NOT_A_KIBANA_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden(AUTHENTICATION.NOT_A_KIBANA_USER.USERNAME), + }, + }, + }); + + updateTest(`superuser`, { + auth: { + username: AUTHENTICATION.SUPERUSER.USERNAME, + password: AUTHENTICATION.SUPERUSER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`kibana legacy user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`kibana legacy dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.PASSWORD, + }, + 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 + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_LEGACY_DASHBOARD_ONLY_USER.USERNAME + ), + }, + }, + }); + + updateTest(`kibana dual-privileges user`, { + auth: { + username: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.USERNAME, + password: AUTHENTICATION.KIBANA_DUAL_PRIVILEGES_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`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, + }, + tests: { + spaceAware: { + statusCode: 403, + response: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + + updateTest(`kibana rbac user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest(`kibana rbac dashboard only user`, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DASHBOARD_ONLY_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: expectSpaceAwareRbacForbidden, + }, + notSpaceAware: { + statusCode: 403, + response: expectNotSpaceAwareRbacForbidden, + }, + doesntExist: { + statusCode: 403, + response: expectDoesntExistRbacForbidden, + }, + }, + }); + + updateTest(AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_ALL_USER.USERNAME + ), + }, + }, + }); + + updateTest(AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.USERNAME + ), + }, + }, + }); + + updateTest(AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_ALL_USER.USERNAME + ), + }, + }, + }); + + updateTest(AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, { + auth: { + username: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME, + password: AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.PASSWORD, + }, + tests: { + spaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + notSpaceAware: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + doesntExist: { + statusCode: 403, + response: createExpectLegacyForbidden( + AUTHENTICATION.KIBANA_RBAC_SPACE_1_READ_USER.USERNAME + ), + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/security_only/config.js b/x-pack/test/saved_object_api_integration/security_only/config.ts similarity index 83% rename from x-pack/test/saved_object_api_integration/security_only/config.js rename to x-pack/test/saved_object_api_integration/security_only/config.ts index d76161b08d0032..f71cc9207b3cc7 100644 --- a/x-pack/test/saved_object_api_integration/security_only/config.js +++ b/x-pack/test/saved_object_api_integration/security_only/config.ts @@ -6,4 +6,5 @@ import { createTestConfig } from '../common/config'; -export default createTestConfig('security_only', { disabledPlugins: ['spaces'], license: 'trial', }); +// tslint:disable:no-default-export +export default createTestConfig('security_only', { disabledPlugins: ['spaces'], license: 'trial' }); diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/index.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/index.js deleted file mode 100644 index 3c747f65541329..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/index.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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('apis spaces', () => { - loadTestFile(require.resolve('./saved_objects')); - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/index.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/index.ts new file mode 100644 index 00000000000000..a1c07ab90e7628 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { TestInvoker } from '../../common/lib/types'; + +/* + * 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. + */ + +// tslint:disable:no-default-export +export default function({ loadTestFile }: TestInvoker) { + describe('apis spaces', () => { + loadTestFile(require.resolve('./saved_objects')); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.js deleted file mode 100644 index 29a7ebc446f0fc..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.js +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 { SPACES } from '../../../common/lib/spaces'; -import { getIdPrefix, getUrlPrefix } from '../../../common/lib/space_test_utils'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - const BULK_REQUESTS = [ - { - type: 'visualization', - id: 'dd7caf20-9efd-11e7-acb3-3dab96693fab', - }, - { - type: 'dashboard', - id: 'does not exist', - }, - { - type: 'config', - id: '7.0.0-alpha1', - }, - ]; - - const createBulkRequests = (spaceId) => BULK_REQUESTS.map(r => ({ - ...r, - id: `${getIdPrefix(spaceId)}${r.id}` - })); - - describe('_bulk_get', () => { - const expectNotFoundResults = (spaceId) => resp => { - expect(resp.body).to.eql({ - saved_objects: [ - { - id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, - type: 'visualization', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - { - id: `${getIdPrefix(spaceId)}does not exist`, - type: 'dashboard', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - //todo(legrego) fix when config is space aware - { - id: `${getIdPrefix(spaceId)}7.0.0-alpha1`, - type: 'config', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - ], - }); - }; - - const expectResults = (spaceId) => resp => { - expect(resp.body).to.eql({ - saved_objects: [ - { - id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, - type: 'visualization', - updated_at: '2017-09-21T18:51:23.794Z', - version: resp.body.saved_objects[0].version, - attributes: { - title: 'Count of requests', - description: '', - version: 1, - // cheat for some of the more complex attributes - visState: resp.body.saved_objects[0].attributes.visState, - uiStateJSON: resp.body.saved_objects[0].attributes.uiStateJSON, - kibanaSavedObjectMeta: - resp.body.saved_objects[0].attributes.kibanaSavedObjectMeta, - }, - }, - { - id: `${getIdPrefix(spaceId)}does not exist`, - type: 'dashboard', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - //todo(legrego) fix when config is space aware - { - id: `${getIdPrefix(spaceId)}7.0.0-alpha1`, - type: 'config', - error: { - statusCode: 404, - message: 'Not found', - }, - }, - ], - }); - }; - - const bulkGetTest = (description, { spaceId, tests, otherSpaceId = spaceId }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.default.statusCode}`, async () => { - await supertest - .post(`${getUrlPrefix(spaceId)}/api/saved_objects/_bulk_get`) - .send(createBulkRequests(otherSpaceId)) - .expect(tests.default.statusCode) - .then(tests.default.response); - }); - }); - }; - - bulkGetTest(`objects within the current space (space_1)`, { - ...SPACES.SPACE_1, - tests: { - default: { - statusCode: 200, - response: expectResults(SPACES.SPACE_1.spaceId), - }, - } - }); - - bulkGetTest(`objects within another space`, { - ...SPACES.SPACE_1, - otherSpaceId: SPACES.SPACE_2.spaceId, - tests: { - default: { - statusCode: 200, - response: expectNotFoundResults(SPACES.SPACE_2.spaceId) - }, - } - }); - - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.ts new file mode 100644 index 00000000000000..1f270bfd046d3f --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/bulk_get.ts @@ -0,0 +1,43 @@ +/* + * 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 { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { bulkGetTestSuiteFactory } from '../../../common/suites/saved_objects/bulk_get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + const { bulkGetTest, createExpectResults, createExpectNotFoundResults } = bulkGetTestSuiteFactory( + esArchiver, + supertest + ); + + describe('_bulk_get', () => { + bulkGetTest(`objects within the current space (space_1)`, { + ...SPACES.SPACE_1, + tests: { + default: { + statusCode: 200, + response: createExpectResults(SPACES.SPACE_1.spaceId), + }, + }, + }); + + bulkGetTest(`objects within another space`, { + ...SPACES.SPACE_1, + otherSpaceId: SPACES.SPACE_2.spaceId, + tests: { + default: { + statusCode: 200, + response: createExpectNotFoundResults(SPACES.SPACE_2.spaceId), + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.ts similarity index 79% rename from x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.js rename to x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.ts index b8f20dca1531a0..488404e2bb86e1 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.js +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/create.ts @@ -5,9 +5,11 @@ */ import { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; import { createTestSuiteFactory } from '../../../common/suites/saved_objects/create'; -export default function ({ getService }) { +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const es = getService('es'); const esArchiver = getService('esArchiver'); @@ -15,11 +17,10 @@ export default function ({ getService }) { const { createTest, createExpectSpaceAwareResults, - expectNotSpaceAwareResults + expectNotSpaceAwareResults, } = createTestSuiteFactory(es, esArchiver, supertestWithoutAuth); describe('create', () => { - createTest('in the current space (space_1)', { ...SPACES.SPACE_1, tests: { @@ -29,9 +30,9 @@ export default function ({ getService }) { }, notSpaceAware: { statusCode: 200, - response: expectNotSpaceAwareResults(SPACES.SPACE_1.spaceId), - } - } + response: expectNotSpaceAwareResults, + }, + }, }); createTest('in the default space', { @@ -43,9 +44,9 @@ export default function ({ getService }) { }, notSpaceAware: { statusCode: 200, - response: expectNotSpaceAwareResults(SPACES.SPACE_1.spaceId), - } - } + response: expectNotSpaceAwareResults, + }, + }, }); }); } diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.js deleted file mode 100644 index 35b769bc66df73..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 { SPACES } from '../../../common/lib/spaces'; -import { getUrlPrefix, getIdPrefix } from '../../../common/lib/space_test_utils'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('delete', () => { - - const expectEmpty = () => (resp) => { - expect(resp.body).to.eql({}); - }; - - const expectNotFound = (type, id) => (resp) => { - expect(resp.body).to.eql({ - statusCode: 404, - error: 'Not Found', - message: `Saved object [${type}/${id}] not found` - }); - }; - - const deleteTest = (description, { spaceId, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.spaceAware.statusCode} when deleting a space-aware doc`, async () => ( - await supertest - .delete(`${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/${getIdPrefix(spaceId)}be3733a0-9efe-11e7-acb3-3dab96693fab`) - .expect(tests.spaceAware.statusCode) - .then(tests.spaceAware.response()) - )); - - it(`should return ${tests.notSpaceAware.statusCode} when deleting a non-space-aware doc`, async () => ( - await supertest - .delete(`${getUrlPrefix(spaceId)}/api/saved_objects/space/space_2`) - .expect(tests.notSpaceAware.statusCode) - .then(tests.notSpaceAware.response()) - )); - - it(`should return ${tests.inOtherSpace.statusCode} when deleting a doc belonging to another space`, async () => { - const expectedObjectId = `${getIdPrefix('space_2')}be3733a0-9efe-11e7-acb3-3dab96693fab`; - - await supertest - .delete(`${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/${expectedObjectId}`) - .expect(tests.inOtherSpace.statusCode) - .then(tests.inOtherSpace.response('dashboard', expectedObjectId)); - }); - }); - }; - - deleteTest(`in the default space`, { - ...SPACES.DEFAULT, - tests: { - spaceAware: { - statusCode: 200, - response: expectEmpty - }, - notSpaceAware: { - statusCode: 200, - response: expectEmpty - }, - inOtherSpace: { - statusCode: 404, - response: expectNotFound - } - } - }); - - deleteTest(`in the current space (space_1)`, { - ...SPACES.SPACE_1, - tests: { - spaceAware: { - statusCode: 200, - response: expectEmpty - }, - notSpaceAware: { - statusCode: 200, - response: expectEmpty - }, - inOtherSpace: { - statusCode: 404, - response: expectNotFound - } - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.ts new file mode 100644 index 00000000000000..d56124a903dd5e --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/delete.ts @@ -0,0 +1,58 @@ +/* + * 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 { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { deleteTestSuiteFactory } from '../../../common/suites/saved_objects/delete'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('delete', () => { + const { createExpectUnknownDocNotFound, deleteTest, expectEmpty } = deleteTestSuiteFactory( + esArchiver, + supertest + ); + + deleteTest(`in the default space`, { + ...SPACES.DEFAULT, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(SPACES.DEFAULT.spaceId), + }, + }, + }); + + deleteTest(`in the current space (space_1)`, { + ...SPACES.SPACE_1, + tests: { + spaceAware: { + statusCode: 200, + response: expectEmpty, + }, + notSpaceAware: { + statusCode: 200, + response: expectEmpty, + }, + invalidId: { + statusCode: 404, + response: createExpectUnknownDocNotFound(SPACES.SPACE_1.spaceId), + }, + }, + }); + }); +} 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 deleted file mode 100644 index c92c85f3c7832c..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.js +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 { SPACES } from '../../../common/lib/spaces'; -import { getIdPrefix, getUrlPrefix } from '../../../common/lib/space_test_utils'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('find', () => { - - const expectVisualizationResults = (spaceId) => (resp) => { - expect(resp.body).to.eql({ - page: 1, - per_page: 20, - total: 1, - saved_objects: [ - { - type: 'visualization', - id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, - // no space id on the saved object because the field is not requested as part of a find operation - version: 1, - attributes: { - 'title': 'Count of requests' - } - } - ] - }); - }; - - const expectAllResults = (spaceId) => (resp) => { - // TODO(legrego): update once config is space-aware - - const sortById = ({ id: id1 }, { id: id2 }) => id1 < id2 ? -1 : 1; - - resp.body.saved_objects.sort(sortById); - - const expectedSavedObjects = [{ - id: '7.0.0-alpha1', - type: 'config', - updated_at: '2017-09-21T18:49:16.302Z', - version: 1, - }, - { - id: `${getIdPrefix(spaceId)}91200a00-9efd-11e7-acb3-3dab96693fab`, - type: 'index-pattern', - updated_at: '2017-09-21T18:49:16.270Z', - version: 1, - }, - - { - id: `${getIdPrefix(spaceId)}be3733a0-9efe-11e7-acb3-3dab96693fab`, - type: 'dashboard', - updated_at: '2017-09-21T18:57:40.826Z', - version: 1, - }, - { - id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, - 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); - - expectedSavedObjects.forEach((object, index) => { - if (resp.body.saved_objects[index]) { - object.attributes = resp.body.saved_objects[index].attributes; - } - }); - - expect(resp.body).to.eql({ - page: 1, - per_page: 20, - total: expectedSavedObjects.length, - saved_objects: expectedSavedObjects, - }); - }; - - const createExpectEmpty = (page, perPage, total) => (resp) => { - expect(resp.body).to.eql({ - page: page, - per_page: perPage, - total: total, - saved_objects: [] - }); - }; - - const findTest = (description, { spaceId, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - - it(`should return ${tests.normal.statusCode} with ${tests.normal.description}`, async () => ( - await supertest - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=visualization&fields=title`) - .expect(tests.normal.statusCode) - .then(tests.normal.response) - )); - - describe('page beyond total', () => { - it(`should return ${tests.pageBeyondTotal.statusCode} with ${tests.pageBeyondTotal.description}`, async () => ( - await supertest - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=visualization&page=100&per_page=100`) - .expect(tests.pageBeyondTotal.statusCode) - .then(tests.pageBeyondTotal.response) - )); - }); - - describe('unknown search field', () => { - it(`should return ${tests.unknownSearchField.statusCode} with ${tests.unknownSearchField.description}`, async () => ( - await supertest - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find?type=wigwags&search_fields=a`) - .expect(tests.unknownSearchField.statusCode) - .then(tests.unknownSearchField.response) - )); - }); - - describe('no type', () => { - it(`should return ${tests.noType.statusCode} with ${tests.noType.description}`, async () => ( - await supertest - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/_find`) - .expect(tests.noType.statusCode) - .then(tests.noType.response) - )); - }); - }); - }; - - findTest(`objects only within the current space (space_1)`, { - ...SPACES.SPACE_1, - tests: { - normal: { - description: 'only the visualization', - statusCode: 200, - response: expectVisualizationResults(SPACES.SPACE_1.spaceId), - }, - pageBeyondTotal: { - description: 'empty result', - statusCode: 200, - response: createExpectEmpty(100, 100, 1), - }, - unknownSearchField: { - description: 'empty result', - statusCode: 200, - response: createExpectEmpty(1, 20, 0), - }, - noType: { - description: 'all objects', - statusCode: 200, - response: expectAllResults(SPACES.SPACE_1.spaceId), - }, - } - }); - - findTest(`objects only within the current space (default)`, { - ...SPACES.DEFAULT, - tests: { - normal: { - description: 'only the visualization', - statusCode: 200, - response: expectVisualizationResults(SPACES.DEFAULT.spaceId), - }, - pageBeyondTotal: { - description: 'empty result', - statusCode: 200, - response: createExpectEmpty(100, 100, 1), - }, - unknownSearchField: { - description: 'empty result', - statusCode: 200, - response: createExpectEmpty(1, 20, 0), - }, - noType: { - description: 'all objects', - statusCode: 200, - response: expectAllResults(SPACES.DEFAULT.spaceId), - }, - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.ts new file mode 100644 index 00000000000000..83403fdcea08b8 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/find.ts @@ -0,0 +1,86 @@ +/* + * 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 { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { findTestSuiteFactory } from '../../../common/suites/saved_objects/find'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + const { + createExpectEmpty, + createExpectResults, + createExpectVisualizationResults, + findTest, + } = findTestSuiteFactory(esArchiver, supertest); + + describe('find', () => { + findTest(`objects only within the current space (space_1)`, { + ...SPACES.SPACE_1, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(SPACES.SPACE_1.spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(SPACES.SPACE_1.spaceId), + }, + }, + }); + + findTest(`objects only within the current space (default)`, { + ...SPACES.DEFAULT, + tests: { + normal: { + description: 'only the visualization', + statusCode: 200, + response: createExpectVisualizationResults(SPACES.DEFAULT.spaceId), + }, + unknownType: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + pageBeyondTotal: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(100, 100, 1), + }, + unknownSearchField: { + description: 'empty result', + statusCode: 200, + response: createExpectEmpty(1, 20, 0), + }, + noType: { + description: 'all objects', + statusCode: 200, + response: createExpectResults(SPACES.DEFAULT.spaceId), + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.js deleted file mode 100644 index 06b32d795add40..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 { getIdPrefix, getUrlPrefix } from '../../../common/lib/space_test_utils'; -import { SPACES } from '../../../common/lib/spaces'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('get', () => { - - const expectResults = (spaceId) => () => (resp) => { - const expectedBody = { - id: `${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`, - type: 'visualization', - updated_at: '2017-09-21T18:51:23.794Z', - version: resp.body.version, - - attributes: { - title: 'Count of requests', - description: '', - version: 1, - // cheat for some of the more complex attributes - visState: resp.body.attributes.visState, - uiStateJSON: resp.body.attributes.uiStateJSON, - kibanaSavedObjectMeta: resp.body.attributes.kibanaSavedObjectMeta - } - }; - - expect(resp.body).to.eql(expectedBody); - }; - - const expectNotFound = (type, id) => (resp) => { - expect(resp.body).to.eql({ - error: 'Not Found', - message: `Saved object [${type}/${id}] not found`, - statusCode: 404, - }); - }; - - const getTest = (description, { spaceId, tests, otherSpaceId = spaceId }) => { - describe(description, () => { - before(async () => esArchiver.load(`saved_objects/spaces`)); - after(async () => esArchiver.unload(`saved_objects/spaces`)); - - it(`should return ${tests.exists.statusCode}`, async () => { - const objectId = `${getIdPrefix(otherSpaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`; - - return supertest - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${objectId}`) - .expect(tests.exists.statusCode) - .then(tests.exists.response('visualization', objectId)); - }); - }); - }; - - getTest(`can access objects belonging to the current space (space_1)`, { - ...SPACES.SPACE_1, - tests: { - exists: { - statusCode: 200, - response: expectResults(SPACES.SPACE_1.spaceId), - }, - } - }); - - getTest(`cannot access objects belonging to a different space (space_1)`, { - ...SPACES.SPACE_1, - otherSpaceId: SPACES.SPACE_2.spaceId, - tests: { - exists: { - statusCode: 404, - response: expectNotFound - }, - } - }); - - getTest(`can access objects belonging to the current space (default)`, { - ...SPACES.DEFAULT, - tests: { - exists: { - statusCode: 200, - response: expectResults(SPACES.DEFAULT.spaceId), - }, - } - }); - - getTest(`cannot access objects belonging to a different space (default)`, { - ...SPACES.DEFAULT, - otherSpaceId: SPACES.SPACE_1.spaceId, - tests: { - exists: { - statusCode: 404, - response: expectNotFound - }, - } - }); - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.ts new file mode 100644 index 00000000000000..138dc82532a0a7 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/get.ts @@ -0,0 +1,50 @@ +/* + * 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 { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { getTestSuiteFactory } from '../../../common/suites/saved_objects/get'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + const { createExpectDoesntExistNotFound, createExpectResults, getTest } = getTestSuiteFactory( + esArchiver, + supertest + ); + + describe('get', () => { + getTest(`can access objects belonging to the current space (default)`, { + ...SPACES.DEFAULT, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(SPACES.DEFAULT.spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(SPACES.DEFAULT.spaceId), + }, + }, + }); + + getTest(`can access objects belonging to the current space (space_1)`, { + ...SPACES.SPACE_1, + tests: { + exists: { + statusCode: 200, + response: createExpectResults(SPACES.SPACE_1.spaceId), + }, + doesntExist: { + statusCode: 404, + response: createExpectDoesntExistNotFound(SPACES.SPACE_1.spaceId), + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.ts new file mode 100644 index 00000000000000..1b1ae2c8a3c4de --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/index.ts @@ -0,0 +1,25 @@ +/* + * 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 { TestInvoker } from '../../../common/lib/types'; + +/* + * 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. + */ + +// tslint:disable:no-default-export +export default function({ loadTestFile }: TestInvoker) { + describe('saved_objects', () => { + loadTestFile(require.resolve('./bulk_get')); + loadTestFile(require.resolve('./create')); + loadTestFile(require.resolve('./delete')); + loadTestFile(require.resolve('./find')); + loadTestFile(require.resolve('./get')); + loadTestFile(require.resolve('./update')); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.js b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.js deleted file mode 100644 index 1211da2fd208f7..00000000000000 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 { SPACES } from '../../../common/lib/spaces'; -import { getUrlPrefix, getIdPrefix } from '../../../common/lib/space_test_utils'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('update', () => { - const expectSpaceAwareResults = () => resp => { - - // loose ISO8601 UTC time with milliseconds validation - expect(resp.body).to.have.property('updated_at').match(/^[\d-]{10}T[\d:\.]{12}Z$/); - - expect(resp.body).to.eql({ - id: resp.body.id, - type: 'visualization', - updated_at: resp.body.updated_at, - version: 2, - attributes: { - title: 'My second favorite vis' - } - }); - }; - - const expectNonSpaceAwareResults = () => resp => { - - // loose ISO8601 UTC time with milliseconds validation - expect(resp.body).to.have.property('updated_at').match(/^[\d-]{10}T[\d:\.]{12}Z$/); - - expect(resp.body).to.eql({ - id: resp.body.id, - type: 'space', - updated_at: resp.body.updated_at, - version: 2, - attributes: { - name: 'My second favorite space' - } - }); - }; - - const expectNotFound = (type, id) => resp => { - expect(resp.body).eql({ - statusCode: 404, - error: 'Not Found', - message: `Saved object [${type}/${id}] not found` - }); - }; - - const updateTest = (description, { spaceId, tests }) => { - describe(description, () => { - before(() => esArchiver.load('saved_objects/spaces')); - after(() => esArchiver.unload('saved_objects/spaces')); - it(`should return ${tests.spaceAware.statusCode} for a space-aware doc`, async () => { - await supertest - .put(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${getIdPrefix(spaceId)}dd7caf20-9efd-11e7-acb3-3dab96693fab`) - .send({ - attributes: { - title: 'My second favorite vis' - } - }) - .expect(tests.spaceAware.statusCode) - .then(tests.spaceAware.response()); - }); - - it(`should return ${tests.notSpaceAware.statusCode} for a non space-aware doc`, async () => { - await supertest - .put(`${getUrlPrefix(spaceId)}/api/saved_objects/space/space_1`) - .send({ - attributes: { - name: 'My second favorite space' - } - }) - .expect(tests.notSpaceAware.statusCode) - .then(tests.notSpaceAware.response()); - }); - - it(`should return ${tests.inOtherSpace.statusCode} for a doc in another space`, async () => { - const id = `${getIdPrefix('space_2')}dd7caf20-9efd-11e7-acb3-3dab96693fab`; - await supertest - .put(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization/${id}`) - .send({ - attributes: { - title: 'My second favorite vis' - } - }) - .expect(tests.inOtherSpace.statusCode) - .then(tests.inOtherSpace.response(`visualization`, `${id}`)); - }); - - describe('unknown id', () => { - it(`should return ${tests.doesntExist.statusCode}`, async () => { - await supertest - .put(`${getUrlPrefix(spaceId)}/api/saved_objects/visualization/not an id`) - .send({ - attributes: { - title: 'My second favorite vis' - } - }) - .expect(tests.doesntExist.statusCode) - .then(tests.doesntExist.response(`visualization`, `not an id`)); - }); - }); - }); - }; - - updateTest(`in the default space`, { - ...SPACES.DEFAULT, - tests: { - spaceAware: { - statusCode: 200, - response: expectSpaceAwareResults, - }, - notSpaceAware: { - statusCode: 200, - response: expectNonSpaceAwareResults, - }, - inOtherSpace: { - statusCode: 404, - response: expectNotFound, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - updateTest('in the current space (space_1)', { - ...SPACES.SPACE_1, - tests: { - spaceAware: { - statusCode: 200, - response: expectSpaceAwareResults, - }, - notSpaceAware: { - statusCode: 200, - response: expectNonSpaceAwareResults, - }, - inOtherSpace: { - statusCode: 404, - response: expectNotFound, - }, - doesntExist: { - statusCode: 404, - response: expectNotFound, - }, - } - }); - - }); -} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.ts new file mode 100644 index 00000000000000..fe335489f7c8d8 --- /dev/null +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/saved_objects/update.ts @@ -0,0 +1,60 @@ +/* + * 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 { SPACES } from '../../../common/lib/spaces'; +import { TestInvoker } from '../../../common/lib/types'; +import { updateTestSuiteFactory } from '../../../common/suites/saved_objects/update'; + +// tslint:disable:no-default-export +export default function({ getService }: TestInvoker) { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('update', () => { + const { + expectSpaceAwareResults, + expectNotFound, + expectNotSpaceAwareResults, + updateTest, + } = updateTestSuiteFactory(esArchiver, supertest); + + updateTest(`in the default space`, { + ...SPACES.DEFAULT, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + + updateTest('in the current space (space_1)', { + ...SPACES.SPACE_1, + tests: { + spaceAware: { + statusCode: 200, + response: expectSpaceAwareResults, + }, + notSpaceAware: { + statusCode: 200, + response: expectNotSpaceAwareResults, + }, + doesntExist: { + statusCode: 404, + response: expectNotFound, + }, + }, + }); + }); +} diff --git a/x-pack/test/saved_object_api_integration/spaces_only/config.js b/x-pack/test/saved_object_api_integration/spaces_only/config.ts similarity index 89% rename from x-pack/test/saved_object_api_integration/spaces_only/config.js rename to x-pack/test/saved_object_api_integration/spaces_only/config.ts index bff1dcbe7face9..38d65bab1b107b 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/config.js +++ b/x-pack/test/saved_object_api_integration/spaces_only/config.ts @@ -6,4 +6,5 @@ import { createTestConfig } from '../common/config'; -export default createTestConfig('spaces_only', { license: 'basic', securityEnabled: false }); +// tslint:disable:no-default-export +export default createTestConfig('spaces_only', { license: 'basic' }); diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index ad12247a5da848..a5ae5cdd134bf1 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -1,9 +1,9 @@ { - "extends": "../tsconfig.json", - "include": [ - "common/**/*", - "server/**/*", - "plugins/**/*", - "test/**/*" - ] + "extends": "../tsconfig.json", + "include": [ + "common/**/*", + "server/**/*", + "plugins/**/*", + "test/**/*", + ] } \ No newline at end of file diff --git a/x-pack/yarn.lock b/x-pack/yarn.lock index 8ed5b3d8ea4504..61b1986c3ca020 100644 --- a/x-pack/yarn.lock +++ b/x-pack/yarn.lock @@ -136,7 +136,7 @@ version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" -"@types/expect.js@~0.3.29": +"@types/expect.js@^0.3.29": version "0.3.29" resolved "https://registry.yarnpkg.com/@types/expect.js/-/expect.js-0.3.29.tgz#28dd359155b84b8ecb094afc3f4b74c3222dca3b" @@ -158,9 +158,9 @@ dependencies: "@types/node" "*" -"@types/jest@^22.2.3": - version "22.2.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d" +"@types/jest@^23.3.1": + version "23.3.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.1.tgz#a4319aedb071d478e6f407d1c4578ec8156829cf" "@types/loglevel@^1.5.3": version "1.5.3"