diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index 83408d2121c56..f581c21901ebd 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -159,6 +159,7 @@ enabled: - x-pack/test/examples/config.ts - x-pack/test/fleet_api_integration/config.ts - x-pack/test/fleet_functional/config.ts + - x-pack/test/ftr_apis/security_and_spaces/config.ts - x-pack/test/functional_basic/config.ts - x-pack/test/functional_cors/config.ts - x-pack/test/functional_embedded/config.ts diff --git a/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/default_space.json b/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/default_space.json new file mode 100644 index 0000000000000..2591ad96d87a3 --- /dev/null +++ b/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/default_space.json @@ -0,0 +1,142 @@ +{ + "id": "tag-1", + "type": "tag", + "attributes": { + "name": "tag-1", + "description": "My first tag!", + "color": "#FF00FF" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "tag-2", + "type": "tag", + "attributes": { + "name": "tag-2", + "description": "Another awesome tag", + "color": "#123456" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "tag-3", + "type": "tag", + "attributes": { + "name": "tag-3", + "description": "Last but not least", + "color": "#000000" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "logstash-*", + "type": "index-pattern", + "attributes": { + "fieldFormatMap": "{\"bytes\":{\"id\":\"bytes\"}}", + "fields": "[{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"agent\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"xss.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:site_name.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"agent.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.og:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"index.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@message.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"links.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:type.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false}]", + "timeFieldName": "@timestamp", + "title": "logstash-*" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "vis-area-1", + "type": "visualization", + "attributes": { + "title": "Visualization 1 (tag-1)", + "description": "AreaChart", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + }, + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Visualization AreaChart\",\"type\":\"area\"}" + }, + "references": [ + { + "type": "tag", + "id": "tag-1", + "name": "tag-1-ref" + } + ], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "vis-area-2", + "type": "visualization", + "attributes": { + "title": "Visualization 2 (tag-2)", + "description": "AreaChart", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + }, + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Visualization AreaChart\",\"type\":\"area\"}" + }, + "references": [ + { + "type": "tag", + "id": "tag-2", + "name": "tag-2-ref" + } + ], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "vis-area-3", + "type": "visualization", + "attributes": { + "title": "Visualization 3 (tag-1 + tag-3)", + "description": "AreaChart", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + }, + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Visualization AreaChart\",\"type\":\"area\"}" + }, + "references": [ + { "type": "tag", + "id": "tag-1", + "name": "tag-1-ref" + }, + { "type": "tag", + "id": "tag-3", + "name": "tag-3-ref" + } + ], + "updated_at": "2021-06-17T18:57:58.076Z" +} + +{ + "id": "vis-area-4", + "type": "visualization", + "attributes": { + "title": "Visualization 4 (tag-2)", + "description": "AreaChart", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}" + }, + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Visualization AreaChart\",\"type\":\"area\"}" + }, + "references": [ + { "type": "tag", + "id": "tag-2", + "name": "tag-2-ref" + } + ], + "updated_at": "2021-06-17T18:57:58.076Z" +} diff --git a/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/space_1.json b/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/space_1.json new file mode 100644 index 0000000000000..2706fcf932108 --- /dev/null +++ b/x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/space_1.json @@ -0,0 +1,11 @@ +{ + "id": "space_1-tag-3", + "type": "tag", + "attributes": { + "name": "tag-3", + "description": "Tag 3 in space 1", + "color": "#117744" + }, + "references": [], + "updated_at": "2021-06-17T18:57:58.076Z" +} diff --git a/x-pack/test/ftr_apis/common/lib/authentication.ts b/x-pack/test/ftr_apis/common/lib/authentication.ts new file mode 100644 index 0000000000000..7f4802ecfb372 --- /dev/null +++ b/x-pack/test/ftr_apis/common/lib/authentication.ts @@ -0,0 +1,243 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const ROLES = { + KIBANA_RBAC_DEFAULT_SPACE_READ_USER: { + name: 'kibana_rbac_default_space_read_user', + privileges: { + kibana: [ + { + base: ['read'], + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_WRITE_USER: { + name: 'kibana_rbac_default_space_write_user', + privileges: { + kibana: [ + { + base: ['all'], + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER: { + name: 'kibana_rbac_default_space_so_management_write_user', + privileges: { + kibana: [ + { + feature: { + savedObjectsManagement: ['all'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_SO_MANAGEMENT_READ_USER: { + name: 'kibana_rbac_default_space_so_management_read_user', + privileges: { + kibana: [ + { + feature: { + savedObjectsManagement: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_SO_TAGGING_READ_USER: { + name: 'kibana_rbac_default_space_so_tagging_read_user', + privileges: { + kibana: [ + { + feature: { + savedObjectsTagging: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_SO_TAGGING_WRITE_USER: { + name: 'kibana_rbac_default_space_so_tagging_write_user', + privileges: { + kibana: [ + { + feature: { + savedObjectsTagging: ['all'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_DASHBOARD_READ_USER: { + name: 'kibana_rbac_default_space_dashboard_read_user', + privileges: { + kibana: [ + { + feature: { + dashboard: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_DASHBOARD_WRITE_USER: { + name: 'kibana_rbac_default_space_dashboard_write_user', + privileges: { + kibana: [ + { + feature: { + dashboard: ['all'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_VISUALIZE_READ_USER: { + name: 'kibana_rbac_default_space_visualize_read_user', + privileges: { + kibana: [ + { + feature: { + visualize: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_VISUALIZE_WRITE_USER: { + name: 'kibana_rbac_default_space_visualize_write_user', + privileges: { + kibana: [ + { + feature: { + visualize: ['all'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER: { + name: 'kibana_rbac_default_space_advanced_settings_read_user', + privileges: { + kibana: [ + { + feature: { + advancedSettings: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, + KIBANA_RBAC_DEFAULT_SPACE_MAPS_READ_USER: { + name: 'kibana_rbac_default_space_maps_read_user', + privileges: { + kibana: [ + { + feature: { + maps: ['read'], + }, + spaces: ['default'], + }, + ], + }, + }, +}; + +export const USERS = { + NOT_A_KIBANA_USER: { + username: 'not_a_kibana_user', + password: 'password', + roles: [], + description: 'user with no access', + }, + SUPERUSER: { + username: 'elastic', + password: 'changeme', + roles: [], + superuser: true, + description: 'superuser', + }, + DEFAULT_SPACE_READ_USER: { + username: 'a_kibana_rbac_default_space_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_READ_USER.name], + description: 'rbac user with read on default space', + }, + DEFAULT_SPACE_WRITE_USER: { + username: 'a_kibana_rbac_default_space_write_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_WRITE_USER.name], + description: 'rbac user with all on default space', + }, + DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER: { + username: 'a_kibana_rbac_default_space_so_management_write_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER.name], + description: 'rbac user with all on SO management on default space', + }, + DEFAULT_SPACE_SO_TAGGING_READ_USER: { + username: 'a_kibana_rbac_default_space_so_tagging_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_SO_TAGGING_READ_USER.name], + }, + DEFAULT_SPACE_SO_TAGGING_READ_SO_MANAGEMENT_READ_USER: { + username: 'a_kibana_rbac_default_space_so_tagging_read_so_management_read_user', + password: 'password', + roles: [ + ROLES.KIBANA_RBAC_DEFAULT_SPACE_SO_TAGGING_READ_USER.name, + ROLES.KIBANA_RBAC_DEFAULT_SPACE_SO_MANAGEMENT_READ_USER.name, + ], + }, + DEFAULT_SPACE_SO_TAGGING_WRITE_USER: { + username: 'a_kibana_rbac_default_space_so_tagging_write_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_SO_TAGGING_WRITE_USER.name], + }, + DEFAULT_SPACE_DASHBOARD_READ_USER: { + username: 'a_kibana_rbac_default_space_dashboard_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_DASHBOARD_READ_USER.name], + }, + DEFAULT_SPACE_VISUALIZE_READ_USER: { + username: 'a_kibana_rbac_default_space_visualize_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_VISUALIZE_READ_USER.name], + }, + DEFAULT_SPACE_DASHBOARD_WRITE_USER: { + username: 'a_kibana_rbac_default_space_dashboard_write_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_DASHBOARD_WRITE_USER.name], + }, + DEFAULT_SPACE_VISUALIZE_WRITE_USER: { + username: 'a_kibana_rbac_default_space_visualize_write_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_VISUALIZE_WRITE_USER.name], + }, + DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER: { + username: 'a_kibana_rbac_default_space_advanced_settings_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER.name], + }, + DEFAULT_SPACE_MAPS_READ_USER: { + username: 'a_kibana_rbac_default_space_maps_read_user', + password: 'password', + roles: [ROLES.KIBANA_RBAC_DEFAULT_SPACE_MAPS_READ_USER.name], + }, +}; diff --git a/x-pack/test/ftr_apis/common/lib/create_users_and_roles.ts b/x-pack/test/ftr_apis/common/lib/create_users_and_roles.ts new file mode 100644 index 0000000000000..2987d561f7762 --- /dev/null +++ b/x-pack/test/ftr_apis/common/lib/create_users_and_roles.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext as CommonFtrProviderContext } from '../../../common/ftr_provider_context'; +import { USERS, ROLES } from './authentication'; +import { User, Role } from './types'; + +export const createUsersAndRoles = async (getService: CommonFtrProviderContext['getService']) => { + const security = getService('security'); + + const createRole = async ({ name, privileges }: Role) => { + return await security.role.create(name, privileges); + }; + + const createUser = async ({ username, password, roles, superuser }: User) => { + // no need to create superuser + if (superuser) { + return; + } + + return await security.user.create(username, { + password, + roles, + full_name: username.replace('_', ' '), + email: `${username}@elastic.co`, + }); + }; + + for (const role of Object.values(ROLES)) { + await createRole(role); + } + + for (const user of Object.values(USERS)) { + await createUser(user); + } +}; diff --git a/x-pack/test/ftr_apis/common/lib/index.ts b/x-pack/test/ftr_apis/common/lib/index.ts new file mode 100644 index 0000000000000..9d23dc2541f8c --- /dev/null +++ b/x-pack/test/ftr_apis/common/lib/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { Role, User, ExpectedResponse } from './types'; +export { ROLES, USERS } from './authentication'; +export { createUsersAndRoles } from './create_users_and_roles'; diff --git a/x-pack/test/ftr_apis/common/lib/types.ts b/x-pack/test/ftr_apis/common/lib/types.ts new file mode 100644 index 0000000000000..76cdeba36d0a9 --- /dev/null +++ b/x-pack/test/ftr_apis/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface User { + username: string; + password: string; + roles: string[]; + superuser?: boolean; + description?: string; +} + +export interface Role { + name: string; + privileges: any; +} + +export interface ExpectedResponse { + httpCode: number; + expectResponse: (body: Record) => void | Promise; +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/bulk_delete.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/bulk_delete.ts new file mode 100644 index 0000000000000..a02e48cbf9b75 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/bulk_delete.ts @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createTestSpaces, deleteTestSpaces, createData, deleteData } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('POST /internal/saved_objects_tagging/tags/_bulk_delete', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({}); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unable to delete tag', + }); + }, + }, + }; + + const expectedResults: Record = { + authorized: [ + USERS.SUPERUSER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + ], + unauthorized: [ + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER, + USERS.NOT_A_KIBANA_USER, + ], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .post(`/internal/saved_objects_tagging/tags/_bulk_delete`) + .send({ + ids: ['default-space-tag-1', 'default-space-tag-2'], + }) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/create.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/create.ts new file mode 100644 index 0000000000000..64b3f42d9d30a --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/create.ts @@ -0,0 +1,106 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createTestSpaces, deleteTestSpaces, createData, deleteData } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('POST /api/saved_objects_tagging/tags/create', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({ + tag: { + id: body.tag.id, + name: 'My new tag', + description: 'I just created that', + color: '#009000', + }, + }); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unable to create tag', + }); + }, + }, + }; + + const expectedResults: Record = { + authorized: [ + USERS.SUPERUSER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + ], + unauthorized: [ + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER, + USERS.DEFAULT_SPACE_MAPS_READ_USER, + USERS.NOT_A_KIBANA_USER, + ], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .post(`/api/saved_objects_tagging/tags/create`) + .send({ + name: 'My new tag', + description: 'I just created that', + color: '#009000', + }) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/delete.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/delete.ts new file mode 100644 index 0000000000000..1c5416d50f2bd --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/delete.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createTestSpaces, deleteTestSpaces, createData, deleteData } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('DELETE /api/saved_objects_tagging/tags/{id}', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({}); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unable to delete tag', + }); + }, + }, + }; + + const expectedResults: Record = { + authorized: [ + USERS.SUPERUSER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + ], + unauthorized: [ + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER, + USERS.DEFAULT_SPACE_MAPS_READ_USER, + USERS.NOT_A_KIBANA_USER, + ], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .delete(`/api/saved_objects_tagging/tags/default-space-tag-1`) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/find.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/find.ts new file mode 100644 index 0000000000000..e9a556a161e09 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/find.ts @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createData, createTestSpaces, deleteData, deleteTestSpaces } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('GET /internal/saved_objects_tagging/tags/_find', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({ + tags: [ + { + id: 'default-space-tag-2', + name: 'tag-2', + description: 'Tag 2 in default space', + color: '#77CC11', + relationCount: 0, + }, + ], + total: 1, + }); + }, + }, + noResults: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({ + tags: [], + total: 0, + }); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + error: 'Forbidden', + message: 'unauthorized', + statusCode: 403, + }); + }, + }, + }; + const expectedResults: Record = { + authorized: [ + USERS.SUPERUSER, + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_MAPS_READ_USER, + ], + noResults: [USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER], + unauthorized: [USERS.NOT_A_KIBANA_USER], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .get(`/internal/saved_objects_tagging/tags/_find`) + .query({ + search: '2', + }) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/get.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/get.ts new file mode 100644 index 0000000000000..db4f507a64645 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/get.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createTestSpaces, deleteTestSpaces, createData, deleteData } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('GET /internal/ftr/kbn_client_so/{type}/{id}', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body.id).to.eql('vis-area-4'); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Forbidden', + }); + }, + }, + }; + + const expectedResults: Record = { + authorized: [USERS.SUPERUSER], + unauthorized: [ + USERS.NOT_A_KIBANA_USER, + USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER, + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_MAPS_READ_USER, + ], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .get(`/internal/ftr/kbn_client_so/visualization/vis-area-4`) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/index.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/index.ts new file mode 100644 index 0000000000000..ca5bf0cb89221 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../services'; +import { createUsersAndRoles } from '../../common/lib'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getService, loadTestFile }: FtrProviderContext) { + describe('FTR API - security and spaces integration', function () { + before(async () => { + await createUsersAndRoles(getService); + }); + + loadTestFile(require.resolve('./get')); + loadTestFile(require.resolve('./create')); + loadTestFile(require.resolve('./update')); + loadTestFile(require.resolve('./delete')); + loadTestFile(require.resolve('./find')); + loadTestFile(require.resolve('./bulk_delete')); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/test_utils.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/test_utils.ts new file mode 100644 index 0000000000000..7ab99302043fa --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/test_utils.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../services'; + +export const createTestSpaces = async ({ getService }: FtrProviderContext) => { + const spaceService = getService('spaces'); + await spaceService.create({ + id: 'space_1', + name: 'Space 1', + description: 'This is the first test space', + }); + await spaceService.create({ + id: 'space_2', + name: 'Space 2', + description: 'This is the second test space', + }); +}; + +export const deleteTestSpaces = async ({ getService }: FtrProviderContext) => { + const spaceService = getService('spaces'); + await spaceService.delete('space_1'); + await spaceService.delete('space_2'); +}; + +export const createData = async ({ getService }: FtrProviderContext) => { + const kibanaServer = getService('kibanaServer'); + await kibanaServer.importExport.load( + 'x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/default_space.json' + ); + await kibanaServer.importExport.load( + 'x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/space_1.json', + { space: 'space_1' } + ); +}; + +export const deleteData = async ({ getService }: FtrProviderContext) => { + const kibanaServer = getService('kibanaServer'); + await kibanaServer.importExport.unload( + 'x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/default_space.json' + ); + await kibanaServer.importExport.unload( + 'x-pack/test/ftr_apis/common/fixtures/es_archiver/base_data/space_1.json', + { space: 'space_1' } + ); +}; diff --git a/x-pack/test/ftr_apis/security_and_spaces/apis/update.ts b/x-pack/test/ftr_apis/security_and_spaces/apis/update.ts new file mode 100644 index 0000000000000..f9aa8d5e20701 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/apis/update.ts @@ -0,0 +1,106 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { USERS, User, ExpectedResponse } from '../../common/lib'; +import { FtrProviderContext } from '../services'; +import { createTestSpaces, deleteTestSpaces, createData, deleteData } from './test_utils'; + +// eslint-disable-next-line import/no-default-export +export default function (ftrContext: FtrProviderContext) { + const supertest = ftrContext.getService('supertestWithoutAuth'); + + describe('POST /api/saved_objects_tagging/tags/{id}', () => { + before(async () => { + await createTestSpaces(ftrContext); + }); + + after(async () => { + await deleteTestSpaces(ftrContext); + }); + + beforeEach(async () => { + await createData(ftrContext); + }); + + afterEach(async () => { + await deleteData(ftrContext); + }); + + const responses: Record = { + authorized: { + httpCode: 200, + expectResponse: ({ body }) => { + expect(body).to.eql({ + tag: { + id: body.tag.id, + name: 'Updated title', + description: 'I just updated that', + color: '#009000', + }, + }); + }, + }, + unauthorized: { + httpCode: 403, + expectResponse: ({ body }) => { + expect(body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unable to update tag', + }); + }, + }, + }; + + const expectedResults: Record = { + authorized: [ + USERS.SUPERUSER, + USERS.DEFAULT_SPACE_SO_MANAGEMENT_WRITE_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_WRITE_USER, + ], + unauthorized: [ + USERS.DEFAULT_SPACE_READ_USER, + USERS.DEFAULT_SPACE_SO_TAGGING_READ_USER, + USERS.DEFAULT_SPACE_DASHBOARD_READ_USER, + USERS.DEFAULT_SPACE_VISUALIZE_READ_USER, + USERS.DEFAULT_SPACE_ADVANCED_SETTINGS_READ_USER, + USERS.DEFAULT_SPACE_MAPS_READ_USER, + USERS.NOT_A_KIBANA_USER, + ], + }; + + const createUserTest = ( + { username, password, description }: User, + { httpCode, expectResponse }: ExpectedResponse + ) => { + it(`returns expected ${httpCode} response for ${description ?? username}`, async () => { + await supertest + .post(`/api/saved_objects_tagging/tags/default-space-tag-1`) + .send({ + name: 'Updated title', + description: 'I just updated that', + color: '#009000', + }) + .auth(username, password) + .expect(httpCode) + .then(expectResponse); + }); + }; + + const createTestSuite = () => { + Object.entries(expectedResults).forEach(([responseId, users]) => { + const response: ExpectedResponse = responses[responseId]; + users.forEach((user) => { + createUserTest(user, response); + }); + }); + }; + + createTestSuite(); + }); +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/config.ts b/x-pack/test/ftr_apis/security_and_spaces/config.ts new file mode 100644 index 0000000000000..8cfc662bb0b96 --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/config.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; +import { services } from './services'; + +// eslint-disable-next-line import/no-default-export +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const apiIntegrationConfig = await readConfigFile( + require.resolve('../../api_integration/config.ts') + ); + + return { + testFiles: [require.resolve('./apis')], + servers: apiIntegrationConfig.get('servers'), + services, + junit: { + reportName: 'X-Pack FTR API Integration Tests - Security and Spaces', + }, + esTestCluster: { + ...apiIntegrationConfig.get('esTestCluster'), + license: 'trial', + }, + kbnTestServer: { + ...apiIntegrationConfig.get('kbnTestServer'), + serverArgs: [ + ...apiIntegrationConfig.get('kbnTestServer.serverArgs'), + '--server.xsrf.disableProtection=true', + `--xpack.fleet.registryUrl=http://localhost:12345`, // setting to invalid registry url to prevent installing preconfigured packages + ], + }, + }; +} diff --git a/x-pack/test/ftr_apis/security_and_spaces/services.ts b/x-pack/test/ftr_apis/security_and_spaces/services.ts new file mode 100644 index 0000000000000..cb1db3f8469ee --- /dev/null +++ b/x-pack/test/ftr_apis/security_and_spaces/services.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GenericFtrProviderContext } from '@kbn/test'; +import { services as apiIntegrationServices } from '../../api_integration/services'; + +export const services = { + ...apiIntegrationServices, +}; + +export type FtrProviderContext = GenericFtrProviderContext;