mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Enable custom roles and spaces in serverless projects (#195584)
Closes #194933 Closes #192282 ## Summary This PR updates the serverless project yml files to - enable custom roles for Elasticsearch and Security projects - enable multiple spaces (max 100) for all serverless project types ### Tests Additionally, this PR adjust the serverless test suites. Originally, testing of roles and spaces endpoints was achieved from the feature flag test config. Now that these features are enabled by default, the tests have been migrated to the standard serverless test configs. Affected tests: - x-pack/test_serverless/api_integration/test_suites/common/management/spaces.ts - x-pack/test_serverless/api_integration/test_suites/common/platform_security/authorization.ts - x-pack/test_serverless/functional/test_suites/common/platform_security/navigation/management_nav_cards.ts - x-pack/test_serverless/functional/test_suites/common/platform_security/roles.ts - x-pack/test_serverless/functional/test_suites/common/spaces/spaces_management.ts - x-pack/test_serverless/functional/test_suites/common/spaces/spaces_selection.ts - Feature flag configs/indices - Project specific configs/indices - Base serverless config --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Dzmitry Lemechko <dzmitry.lemechko@elastic.co>
This commit is contained in:
parent
3ff6aadacd
commit
c73bfd2480
38 changed files with 2884 additions and 1629 deletions
|
@ -207,3 +207,6 @@ xpack.ml.compatibleModuleType: 'observability'
|
|||
|
||||
# Disable the embedded Dev Console
|
||||
console.ui.embeddedEnabled: false
|
||||
|
||||
# Disable role management (custom roles)
|
||||
xpack.security.roleManagementEnabled: false
|
||||
|
|
|
@ -155,7 +155,7 @@ server.versioned.versionResolution: newest
|
|||
server.versioned.strictClientVersionCheck: false
|
||||
|
||||
# Enforce single "default" space and disable feature visibility controls
|
||||
xpack.spaces.maxSpaces: 1
|
||||
xpack.spaces.maxSpaces: 100
|
||||
xpack.spaces.allowFeatureVisibility: false
|
||||
xpack.spaces.allowSolutionVisibility: false
|
||||
|
||||
|
|
|
@ -40993,6 +40993,697 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/security/role": {
|
||||
"get": {
|
||||
"operationId": "%2Fapi%2Fsecurity%2Frole#0",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The version of the API to use",
|
||||
"in": "header",
|
||||
"name": "elastic-api-version",
|
||||
"schema": {
|
||||
"default": "2023-10-31",
|
||||
"enum": [
|
||||
"2023-10-31"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "replaceDeprecatedPrivileges",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {},
|
||||
"summary": "Get all roles",
|
||||
"tags": [
|
||||
"roles"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/security/role/{name}": {
|
||||
"delete": {
|
||||
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The version of the API to use",
|
||||
"in": "header",
|
||||
"name": "elastic-api-version",
|
||||
"schema": {
|
||||
"default": "2023-10-31",
|
||||
"enum": [
|
||||
"2023-10-31"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A required header to protect against CSRF attacks",
|
||||
"in": "header",
|
||||
"name": "kbn-xsrf",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"example": "true",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "name",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {},
|
||||
"summary": "Delete a role",
|
||||
"tags": [
|
||||
"roles"
|
||||
]
|
||||
},
|
||||
"get": {
|
||||
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The version of the API to use",
|
||||
"in": "header",
|
||||
"name": "elastic-api-version",
|
||||
"schema": {
|
||||
"default": "2023-10-31",
|
||||
"enum": [
|
||||
"2023-10-31"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "name",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "replaceDeprecatedPrivileges",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {},
|
||||
"summary": "Get a role",
|
||||
"tags": [
|
||||
"roles"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The version of the API to use",
|
||||
"in": "header",
|
||||
"name": "elastic-api-version",
|
||||
"schema": {
|
||||
"default": "2023-10-31",
|
||||
"enum": [
|
||||
"2023-10-31"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A required header to protect against CSRF attacks",
|
||||
"in": "header",
|
||||
"name": "kbn-xsrf",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"example": "true",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "path",
|
||||
"name": "name",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"maxLength": 1024,
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "createOnly",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json; Elastic-Api-Version=2023-10-31": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"description": {
|
||||
"maxLength": 2048,
|
||||
"type": "string"
|
||||
},
|
||||
"elasticsearch": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"cluster": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"indices": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_restricted_indices": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"field_security": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"names": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"names",
|
||||
"privileges"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"remote_cluster": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"clusters": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"privileges",
|
||||
"clusters"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"remote_indices": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_restricted_indices": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"clusters": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"field_security": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"names": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"clusters",
|
||||
"names",
|
||||
"privileges"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"run_as": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"kibana": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"base": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"nullable": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"feature": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"spaces": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {
|
||||
"enum": [
|
||||
"*"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"maxItems": 1,
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
],
|
||||
"default": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"base"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"metadata": {
|
||||
"additionalProperties": {},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"elasticsearch"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {},
|
||||
"summary": "Create or update a role",
|
||||
"tags": [
|
||||
"roles"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/security/roles": {
|
||||
"post": {
|
||||
"operationId": "%2Fapi%2Fsecurity%2Froles#0",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "The version of the API to use",
|
||||
"in": "header",
|
||||
"name": "elastic-api-version",
|
||||
"schema": {
|
||||
"default": "2023-10-31",
|
||||
"enum": [
|
||||
"2023-10-31"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "A required header to protect against CSRF attacks",
|
||||
"in": "header",
|
||||
"name": "kbn-xsrf",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"example": "true",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json; Elastic-Api-Version=2023-10-31": {
|
||||
"schema": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"roles": {
|
||||
"additionalProperties": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"description": {
|
||||
"maxLength": 2048,
|
||||
"type": "string"
|
||||
},
|
||||
"elasticsearch": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"cluster": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"indices": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_restricted_indices": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"field_security": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"names": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"names",
|
||||
"privileges"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"remote_cluster": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"clusters": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"privileges",
|
||||
"clusters"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"remote_indices": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_restricted_indices": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"clusters": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"field_security": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"names": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"privileges": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"clusters",
|
||||
"names",
|
||||
"privileges"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"run_as": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"kibana": {
|
||||
"items": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"base": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"nullable": true,
|
||||
"oneOf": [
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"feature": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"spaces": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {
|
||||
"enum": [
|
||||
"*"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"maxItems": 1,
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
],
|
||||
"default": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"base"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"metadata": {
|
||||
"additionalProperties": {},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"elasticsearch"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"roles"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {},
|
||||
"summary": "Create or update roles",
|
||||
"tags": [
|
||||
"roles"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/spaces/space": {
|
||||
"get": {
|
||||
"operationId": "%2Fapi%2Fspaces%2Fspace#0",
|
||||
|
@ -41493,6 +42184,9 @@
|
|||
{
|
||||
"name": "Message Signing Service"
|
||||
},
|
||||
{
|
||||
"name": "roles"
|
||||
},
|
||||
{
|
||||
"name": "spaces"
|
||||
},
|
||||
|
|
|
@ -36556,6 +36556,456 @@ paths:
|
|||
tags:
|
||||
- Security AI Assistant API
|
||||
- Prompts API
|
||||
/api/security/role:
|
||||
get:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- in: query
|
||||
name: replaceDeprecatedPrivileges
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses: {}
|
||||
summary: Get all roles
|
||||
tags:
|
||||
- roles
|
||||
/api/security/role/{name}:
|
||||
delete:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
minLength: 1
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Delete a role
|
||||
tags:
|
||||
- roles
|
||||
get:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
minLength: 1
|
||||
type: string
|
||||
- in: query
|
||||
name: replaceDeprecatedPrivileges
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses: {}
|
||||
summary: Get a role
|
||||
tags:
|
||||
- roles
|
||||
put:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
type: string
|
||||
- in: query
|
||||
name: createOnly
|
||||
required: false
|
||||
schema:
|
||||
default: false
|
||||
type: boolean
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
maxLength: 2048
|
||||
type: string
|
||||
elasticsearch:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
cluster:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
remote_cluster:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- privileges
|
||||
- clusters
|
||||
type: array
|
||||
remote_indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- clusters
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
run_as:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kibana:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
base:
|
||||
anyOf:
|
||||
- items: {}
|
||||
type: array
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: object
|
||||
- type: string
|
||||
nullable: true
|
||||
oneOf:
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
feature:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
spaces:
|
||||
anyOf:
|
||||
- items:
|
||||
enum:
|
||||
- '*'
|
||||
type: string
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
default:
|
||||
- '*'
|
||||
required:
|
||||
- base
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties: {}
|
||||
type: object
|
||||
required:
|
||||
- elasticsearch
|
||||
responses: {}
|
||||
summary: Create or update a role
|
||||
tags:
|
||||
- roles
|
||||
/api/security/roles:
|
||||
post:
|
||||
operationId: '%2Fapi%2Fsecurity%2Froles#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
roles:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
maxLength: 2048
|
||||
type: string
|
||||
elasticsearch:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
cluster:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
remote_cluster:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- privileges
|
||||
- clusters
|
||||
type: array
|
||||
remote_indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- clusters
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
run_as:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kibana:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
base:
|
||||
anyOf:
|
||||
- items: {}
|
||||
type: array
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: object
|
||||
- type: string
|
||||
nullable: true
|
||||
oneOf:
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
feature:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
spaces:
|
||||
anyOf:
|
||||
- items:
|
||||
enum:
|
||||
- '*'
|
||||
type: string
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
default:
|
||||
- '*'
|
||||
required:
|
||||
- base
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties: {}
|
||||
type: object
|
||||
required:
|
||||
- elasticsearch
|
||||
type: object
|
||||
required:
|
||||
- roles
|
||||
responses: {}
|
||||
summary: Create or update roles
|
||||
tags:
|
||||
- roles
|
||||
/api/spaces/space:
|
||||
get:
|
||||
operationId: '%2Fapi%2Fspaces%2Fspace#0'
|
||||
|
@ -51504,6 +51954,7 @@ tags:
|
|||
- name: Message Signing Service
|
||||
- description: Machine learning
|
||||
name: ml
|
||||
- name: roles
|
||||
- description: >
|
||||
Export sets of saved objects that you want to import into {kib}, resolve
|
||||
import errors, and rotate an encryption key for encrypted saved objects
|
||||
|
|
|
@ -36556,6 +36556,456 @@ paths:
|
|||
tags:
|
||||
- Security AI Assistant API
|
||||
- Prompts API
|
||||
/api/security/role:
|
||||
get:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- in: query
|
||||
name: replaceDeprecatedPrivileges
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses: {}
|
||||
summary: Get all roles
|
||||
tags:
|
||||
- roles
|
||||
/api/security/role/{name}:
|
||||
delete:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#1'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
minLength: 1
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Delete a role
|
||||
tags:
|
||||
- roles
|
||||
get:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
minLength: 1
|
||||
type: string
|
||||
- in: query
|
||||
name: replaceDeprecatedPrivileges
|
||||
required: false
|
||||
schema:
|
||||
type: boolean
|
||||
responses: {}
|
||||
summary: Get a role
|
||||
tags:
|
||||
- roles
|
||||
put:
|
||||
operationId: '%2Fapi%2Fsecurity%2Frole%2F%7Bname%7D#2'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
- in: path
|
||||
name: name
|
||||
required: true
|
||||
schema:
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
type: string
|
||||
- in: query
|
||||
name: createOnly
|
||||
required: false
|
||||
schema:
|
||||
default: false
|
||||
type: boolean
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
maxLength: 2048
|
||||
type: string
|
||||
elasticsearch:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
cluster:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
remote_cluster:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- privileges
|
||||
- clusters
|
||||
type: array
|
||||
remote_indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- clusters
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
run_as:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kibana:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
base:
|
||||
anyOf:
|
||||
- items: {}
|
||||
type: array
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: object
|
||||
- type: string
|
||||
nullable: true
|
||||
oneOf:
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
feature:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
spaces:
|
||||
anyOf:
|
||||
- items:
|
||||
enum:
|
||||
- '*'
|
||||
type: string
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
default:
|
||||
- '*'
|
||||
required:
|
||||
- base
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties: {}
|
||||
type: object
|
||||
required:
|
||||
- elasticsearch
|
||||
responses: {}
|
||||
summary: Create or update a role
|
||||
tags:
|
||||
- roles
|
||||
/api/security/roles:
|
||||
post:
|
||||
operationId: '%2Fapi%2Fsecurity%2Froles#0'
|
||||
parameters:
|
||||
- description: The version of the API to use
|
||||
in: header
|
||||
name: elastic-api-version
|
||||
schema:
|
||||
default: '2023-10-31'
|
||||
enum:
|
||||
- '2023-10-31'
|
||||
type: string
|
||||
- description: A required header to protect against CSRF attacks
|
||||
in: header
|
||||
name: kbn-xsrf
|
||||
required: true
|
||||
schema:
|
||||
example: 'true'
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
roles:
|
||||
additionalProperties:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
description:
|
||||
maxLength: 2048
|
||||
type: string
|
||||
elasticsearch:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
cluster:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
remote_cluster:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
required:
|
||||
- privileges
|
||||
- clusters
|
||||
type: array
|
||||
remote_indices:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
allow_restricted_indices:
|
||||
type: boolean
|
||||
clusters:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
field_security:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
names:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
privileges:
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
query:
|
||||
type: string
|
||||
required:
|
||||
- clusters
|
||||
- names
|
||||
- privileges
|
||||
type: array
|
||||
run_as:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
kibana:
|
||||
items:
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
base:
|
||||
anyOf:
|
||||
- items: {}
|
||||
type: array
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: object
|
||||
- type: string
|
||||
nullable: true
|
||||
oneOf:
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
feature:
|
||||
additionalProperties:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
spaces:
|
||||
anyOf:
|
||||
- items:
|
||||
enum:
|
||||
- '*'
|
||||
type: string
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
type: array
|
||||
- items:
|
||||
type: string
|
||||
type: array
|
||||
default:
|
||||
- '*'
|
||||
required:
|
||||
- base
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties: {}
|
||||
type: object
|
||||
required:
|
||||
- elasticsearch
|
||||
type: object
|
||||
required:
|
||||
- roles
|
||||
responses: {}
|
||||
summary: Create or update roles
|
||||
tags:
|
||||
- roles
|
||||
/api/spaces/space:
|
||||
get:
|
||||
operationId: '%2Fapi%2Fspaces%2Fspace#0'
|
||||
|
@ -51504,6 +51954,7 @@ tags:
|
|||
- name: Message Signing Service
|
||||
- description: Machine learning
|
||||
name: ml
|
||||
- name: roles
|
||||
- description: >
|
||||
Export sets of saved objects that you want to import into {kib}, resolve
|
||||
import errors, and rotate an encryption key for encrypted saved objects
|
||||
|
|
|
@ -247,7 +247,7 @@ describe('config schema', () => {
|
|||
},
|
||||
"loginAssistanceMessage": "",
|
||||
"public": Object {},
|
||||
"roleManagementEnabled": false,
|
||||
"roleManagementEnabled": true,
|
||||
"secureCookies": false,
|
||||
"session": Object {
|
||||
"cleanupInterval": "PT1H",
|
||||
|
|
|
@ -303,8 +303,9 @@ export const ConfigSchema = schema.object({
|
|||
),
|
||||
}),
|
||||
|
||||
// config/serverless.oblt.yml contains an override to false for OBLT projects
|
||||
roleManagementEnabled: offeringBasedSchema({
|
||||
serverless: schema.boolean({ defaultValue: false }),
|
||||
serverless: schema.boolean({ defaultValue: true }),
|
||||
}),
|
||||
|
||||
// Setting only allowed in the Serverless offering
|
||||
|
|
|
@ -125,7 +125,7 @@ export class ServerlessPlugin
|
|||
getNavigationCards: (roleManagementEnabled, extendCardNavDefinitions) => {
|
||||
if (!roleManagementEnabled) return extendCardNavDefinitions;
|
||||
|
||||
const manageOrgMembersNavCard = generateManageOrgMembersNavCard(cloud.organizationUrl);
|
||||
const manageOrgMembersNavCard = generateManageOrgMembersNavCard(cloud.usersAndRolesUrl);
|
||||
if (extendCardNavDefinitions) {
|
||||
extendCardNavDefinitions[manageOrgMembersNavCardName] = manageOrgMembersNavCard;
|
||||
return extendCardNavDefinitions;
|
||||
|
|
|
@ -113,10 +113,6 @@ export function createServerlessTestConfig<T extends DeploymentAgnosticCommonSer
|
|||
...svlSharedConfig.get('kbnTestServer.serverArgs'),
|
||||
...kbnServerArgsFromController[options.serverlessProject],
|
||||
`--serverless=${options.serverlessProject}`,
|
||||
// custom native roles are enabled only for search and security projects
|
||||
...(options.serverlessProject !== 'oblt'
|
||||
? ['--xpack.security.roleManagementEnabled=true']
|
||||
: []),
|
||||
],
|
||||
},
|
||||
testFiles: options.testFiles,
|
||||
|
|
|
@ -36,10 +36,6 @@ export function createTestConfig(options: CreateTestConfigOptions) {
|
|||
serverArgs: [
|
||||
...svlSharedConfig.get('kbnTestServer.serverArgs'),
|
||||
`--serverless=${options.serverlessProject}`,
|
||||
// custom native roles are enabled only for search and security projects
|
||||
...(options.serverlessProject !== 'oblt'
|
||||
? ['--xpack.security.roleManagementEnabled=true']
|
||||
: []),
|
||||
...(options.kbnServerArgs || []),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,410 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import { asyncForEach } from '@kbn/std';
|
||||
import { SupertestWithRoleScopeType } from '@kbn/test-suites-xpack/api_integration/deployment_agnostic/services';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
// Notes:
|
||||
// This suite is currently only called from the feature flags test configs, e.g.
|
||||
// x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
|
||||
// Configuration toggle:
|
||||
// kbnServerArgs: ['--xpack.spaces.maxSpaces=100'],
|
||||
//
|
||||
// Initial test coverage limited to CRUD operations and ensuring disabling features/toggling feature visibility is not possible.
|
||||
// Full coverage of x-pack/test/api_integration/apis/spaces & x-pack/test/spaces_api_integration
|
||||
// should be converted into a deployment agnostic suite when spaces are
|
||||
// permanently enabled in serverless.
|
||||
//
|
||||
// The route access tests for the spaces APIs in ./spaces.ts should also get updated at that time.
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const svlCommonApi = getService('svlCommonApi');
|
||||
const roleScopedSupertest = getService('roleScopedSupertest');
|
||||
const samlAuth = getService('samlAuth');
|
||||
|
||||
// CRUD operations to become public APIs: https://github.com/elastic/kibana/issues/192153
|
||||
let supertestAdminWithApiKey: SupertestWithRoleScopeType;
|
||||
let supertestAdminWithCookieCredentials: SupertestWithRoleScopeType;
|
||||
|
||||
async function createSpace(id: string) {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id,
|
||||
name: id,
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
}
|
||||
|
||||
async function deleteSpace(id: string) {
|
||||
await supertestAdminWithApiKey.delete(`/api/spaces/space/${id}`).expect(204);
|
||||
}
|
||||
|
||||
describe('spaces', function () {
|
||||
before(async () => {
|
||||
supertestAdminWithApiKey = await roleScopedSupertest.getSupertestWithRoleScope('admin', {
|
||||
withCommonHeaders: true,
|
||||
});
|
||||
supertestAdminWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope(
|
||||
'admin',
|
||||
{
|
||||
useCookieHeader: true,
|
||||
withInternalHeaders: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
after(async () => {
|
||||
// delete any lingering spaces
|
||||
const { body } = await supertestAdminWithApiKey.get('/api/spaces/space').send().expect(200);
|
||||
|
||||
const toDelete = (body as Array<{ id: string }>).filter((f) => f.id !== 'default');
|
||||
|
||||
await asyncForEach(toDelete, async (space) => {
|
||||
await deleteSpace(space.id);
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey.destroy();
|
||||
});
|
||||
|
||||
describe('Create (POST /api/spaces/space)', () => {
|
||||
it('should allow us to create a space', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id: 'custom_space_1',
|
||||
name: 'custom_space_1',
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('should not allow us to create a space with disabled features', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id: 'custom_space_2',
|
||||
name: 'custom_space_2',
|
||||
disabledFeatures: ['discover'],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Read (GET /api/spaces/space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('space_to_get_1');
|
||||
await createSpace('space_to_get_2');
|
||||
await createSpace('space_to_get_3');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('space_to_get_1');
|
||||
await deleteSpace('space_to_get_2');
|
||||
await deleteSpace('space_to_get_3');
|
||||
});
|
||||
|
||||
it('should allow us to get a space', async () => {
|
||||
await supertestAdminWithApiKey.get('/api/spaces/space/space_to_get_1').send().expect(200, {
|
||||
id: 'space_to_get_1',
|
||||
name: 'space_to_get_1',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow us to get all spaces', async () => {
|
||||
const { body } = await supertestAdminWithApiKey.get('/api/spaces/space').send().expect(200);
|
||||
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
_reserved: true,
|
||||
color: '#00bfb3',
|
||||
description: 'This is your default space!',
|
||||
disabledFeatures: [],
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
},
|
||||
{ id: 'space_to_get_1', name: 'space_to_get_1', disabledFeatures: [] },
|
||||
{ id: 'space_to_get_2', name: 'space_to_get_2', disabledFeatures: [] },
|
||||
{ id: 'space_to_get_3', name: 'space_to_get_3', disabledFeatures: [] },
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update (PUT /api/spaces/space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('space_to_update');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('space_to_update');
|
||||
});
|
||||
|
||||
it('should allow us to update a space', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/spaces/space/space_to_update')
|
||||
.send({
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
await supertestAdminWithApiKey.get('/api/spaces/space/space_to_update').send().expect(200, {
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow us to update a space with disabled features', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/spaces/space/space_to_update')
|
||||
.send({
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: ['discover'],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete (DELETE /api/spaces/space)', () => {
|
||||
it('should allow us to delete a space', async () => {
|
||||
await createSpace('space_to_delete');
|
||||
|
||||
await supertestAdminWithApiKey.delete(`/api/spaces/space/space_to_delete`).expect(204);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get active space (GET /internal/spaces/_active_space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('foo-space');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('foo-space');
|
||||
});
|
||||
|
||||
it('returns the default space', async () => {
|
||||
const response = await supertestAdminWithCookieCredentials
|
||||
.get('/internal/spaces/_active_space')
|
||||
.expect(200);
|
||||
|
||||
const { id, name, _reserved } = response.body;
|
||||
expect({ id, name, _reserved }).toEqual({
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
_reserved: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the default space when explicitly referenced', async () => {
|
||||
const response = await supertestAdminWithCookieCredentials
|
||||
.get('/s/default/internal/spaces/_active_space')
|
||||
.expect(200);
|
||||
|
||||
const { id, name, _reserved } = response.body;
|
||||
expect({ id, name, _reserved }).toEqual({
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
_reserved: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the foo space', async () => {
|
||||
await supertestAdminWithCookieCredentials
|
||||
.get('/s/foo-space/internal/spaces/_active_space')
|
||||
.expect(200, {
|
||||
id: 'foo-space',
|
||||
name: 'foo-space',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('returns 404 when the space is not found', async () => {
|
||||
await supertestAdminWithCookieCredentials
|
||||
.get('/s/not-found-space/internal/spaces/_active_space')
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: 'Saved object [space/not-found-space] not found',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// These tests just test access to API endpoints, in this case
|
||||
// when accessed without internal headers they will return 400
|
||||
// They will be included in deployment agnostic testing once spaces
|
||||
// are enabled in production.
|
||||
describe(`Access`, () => {
|
||||
describe(`internal`, () => {
|
||||
it('#getActiveSpace requires internal header', async () => {
|
||||
let body: any;
|
||||
let status: number;
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.get('/internal/spaces/_active_space')
|
||||
.set(samlAuth.getCommonRequestHeader()));
|
||||
// expect a rejection because we're not using the internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: expect.stringContaining(
|
||||
'method [get] exists but is not available with the current configuration'
|
||||
),
|
||||
});
|
||||
expect(status).toBe(400);
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.get('/internal/spaces/_active_space')
|
||||
.set(samlAuth.getInternalRequestHeader()));
|
||||
// expect success because we're using the internal header
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: 'default',
|
||||
})
|
||||
);
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
|
||||
it('#copyToSpace requires internal header', async () => {
|
||||
let body: any;
|
||||
let status: number;
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey.post(
|
||||
'/api/spaces/_copy_saved_objects'
|
||||
));
|
||||
// expect a rejection because we're not using the internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: expect.stringContaining(
|
||||
'method [post] exists but is not available with the current configuration'
|
||||
),
|
||||
});
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.post('/api/spaces/_copy_saved_objects')
|
||||
.set(samlAuth.getInternalRequestHeader()));
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(400, status, body);
|
||||
|
||||
// expect 400 for missing body
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: '[request body]: expected a plain object value, but found [null] instead.',
|
||||
});
|
||||
});
|
||||
|
||||
it('#resolveCopyToSpaceErrors requires internal header', async () => {
|
||||
let body: any;
|
||||
let status: number;
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey.post(
|
||||
'/api/spaces/_resolve_copy_saved_objects_errors'
|
||||
));
|
||||
// expect a rejection because we're not using the internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: expect.stringContaining(
|
||||
'method [post] exists but is not available with the current configuration'
|
||||
),
|
||||
});
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.post('/api/spaces/_resolve_copy_saved_objects_errors')
|
||||
.set(samlAuth.getInternalRequestHeader()));
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(400, status, body);
|
||||
|
||||
// expect 400 for missing body
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: '[request body]: expected a plain object value, but found [null] instead.',
|
||||
});
|
||||
});
|
||||
|
||||
it('#updateObjectsSpaces requires internal header', async () => {
|
||||
let body: any;
|
||||
let status: number;
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey.post(
|
||||
'/api/spaces/_update_objects_spaces'
|
||||
));
|
||||
// expect a rejection because we're not using the internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: expect.stringContaining(
|
||||
'method [post] exists but is not available with the current configuration'
|
||||
),
|
||||
});
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.post('/api/spaces/_update_objects_spaces')
|
||||
.set(samlAuth.getInternalRequestHeader()));
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(400, status, body);
|
||||
|
||||
// expect 400 for missing body
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: '[request body]: expected a plain object value, but found [null] instead.',
|
||||
});
|
||||
});
|
||||
|
||||
it('#getShareableReferences requires internal header', async () => {
|
||||
let body: any;
|
||||
let status: number;
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey.post(
|
||||
'/api/spaces/_get_shareable_references'
|
||||
));
|
||||
// expect a rejection because we're not using the internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: expect.stringContaining(
|
||||
'method [post] exists but is not available with the current configuration'
|
||||
),
|
||||
});
|
||||
|
||||
({ body, status } = await supertestAdminWithApiKey
|
||||
.post('/api/spaces/_get_shareable_references')
|
||||
.set(samlAuth.getInternalRequestHeader())
|
||||
.send({
|
||||
objects: [{ type: 'a', id: 'a' }],
|
||||
}));
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(200, status, body);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`disabled`, () => {
|
||||
it('#disableLegacyUrlAliases', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey.post(
|
||||
'/api/spaces/_disable_legacy_url_aliases'
|
||||
);
|
||||
// without a request body we would normally a 400 bad request if the endpoint was registered
|
||||
svlCommonApi.assertApiNotFound(body, status);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import expect from 'expect';
|
||||
import { SupertestWithRoleScopeType } from '@kbn/test-suites-xpack/api_integration/deployment_agnostic/services';
|
||||
import { asyncForEach } from '@kbn/std';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
@ -16,6 +17,21 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
let supertestAdminWithApiKey: SupertestWithRoleScopeType;
|
||||
let supertestAdminWithCookieCredentials: SupertestWithRoleScopeType;
|
||||
|
||||
async function createSpace(id: string) {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id,
|
||||
name: id,
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
}
|
||||
|
||||
async function deleteSpace(id: string) {
|
||||
await supertestAdminWithApiKey.delete(`/api/spaces/space/${id}`).expect(204);
|
||||
}
|
||||
|
||||
describe('spaces', function () {
|
||||
before(async () => {
|
||||
// admin is the only predefined role that will work for all 3 solutions
|
||||
|
@ -34,76 +50,212 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
await supertestAdminWithApiKey.destroy();
|
||||
});
|
||||
|
||||
describe('route access', () => {
|
||||
describe('public (CRUD)', () => {
|
||||
// Skipped due to change in QA environment for role management and spaces
|
||||
// TODO: revisit once the change is rolled out to all environments
|
||||
it.skip('#create', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey.post('/api/spaces/space').send({
|
||||
id: 'custom',
|
||||
name: 'Custom',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
// The create and update test cases are unique to serverless because
|
||||
// setting feature visibility is not possible in serverless
|
||||
describe('CRUD', () => {
|
||||
after(async () => {
|
||||
// delete any lingering spaces
|
||||
const { body } = await supertestAdminWithApiKey.get('/api/spaces/space').send().expect(200);
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(400, status, body);
|
||||
const toDelete = (body as Array<{ id: string }>).filter((f) => f.id !== 'default');
|
||||
|
||||
// Should fail due to maximum spaces limit, not because of lacking internal header
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message:
|
||||
'Unable to create Space, this exceeds the maximum number of spaces set by the xpack.spaces.maxSpaces setting',
|
||||
});
|
||||
});
|
||||
|
||||
it('#get', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey.get('/api/spaces/space/default');
|
||||
// expect success because we're using the internal header
|
||||
expect(body).toEqual(expect.objectContaining({ id: 'default' }));
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
|
||||
it('#getAll', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey.get('/api/spaces/space');
|
||||
// expect success because we're using the internal header
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: 'default',
|
||||
}),
|
||||
])
|
||||
);
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
|
||||
it('#update', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey
|
||||
.put('/api/spaces/space/default')
|
||||
.send({
|
||||
id: 'default',
|
||||
name: 'UPDATED!',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(200, status, body);
|
||||
});
|
||||
|
||||
it('#delete', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey.delete(
|
||||
'/api/spaces/space/default'
|
||||
);
|
||||
|
||||
svlCommonApi.assertResponseStatusCode(400, status, body);
|
||||
|
||||
// 400 with specific reason - cannot delete the default space
|
||||
expect(body).toEqual({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: 'The default space cannot be deleted because it is reserved.',
|
||||
});
|
||||
await asyncForEach(toDelete, async (space) => {
|
||||
await deleteSpace(space.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Create (POST /api/spaces/space)', () => {
|
||||
it('should allow us to create a space', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id: 'custom_space_1',
|
||||
name: 'custom_space_1',
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
it('should not allow us to create a space with disabled features', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.post('/api/spaces/space')
|
||||
.send({
|
||||
id: 'custom_space_2',
|
||||
name: 'custom_space_2',
|
||||
disabledFeatures: ['discover'],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Read (GET /api/spaces/space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('space_to_get_1');
|
||||
await createSpace('space_to_get_2');
|
||||
await createSpace('space_to_get_3');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('space_to_get_1');
|
||||
await deleteSpace('space_to_get_2');
|
||||
await deleteSpace('space_to_get_3');
|
||||
});
|
||||
|
||||
it('should allow us to get a space', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.get('/api/spaces/space/space_to_get_1')
|
||||
.send()
|
||||
.expect(200, {
|
||||
id: 'space_to_get_1',
|
||||
name: 'space_to_get_1',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow us to get all spaces', async () => {
|
||||
const { body } = await supertestAdminWithApiKey
|
||||
.get('/api/spaces/space')
|
||||
.send()
|
||||
.expect(200);
|
||||
|
||||
expect(body).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
_reserved: true,
|
||||
color: '#00bfb3',
|
||||
description: 'This is your default space!',
|
||||
disabledFeatures: [],
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
},
|
||||
{ id: 'space_to_get_1', name: 'space_to_get_1', disabledFeatures: [] },
|
||||
{ id: 'space_to_get_2', name: 'space_to_get_2', disabledFeatures: [] },
|
||||
{ id: 'space_to_get_3', name: 'space_to_get_3', disabledFeatures: [] },
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update (PUT /api/spaces/space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('space_to_update');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('space_to_update');
|
||||
});
|
||||
|
||||
it('should allow us to update a space', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/spaces/space/space_to_update')
|
||||
.send({
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: [],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.get('/api/spaces/space/space_to_update')
|
||||
.send()
|
||||
.expect(200, {
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow us to update a space with disabled features', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/spaces/space/space_to_update')
|
||||
.send({
|
||||
id: 'space_to_update',
|
||||
name: 'some new name',
|
||||
initials: 'SN',
|
||||
disabledFeatures: ['discover'],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete (DELETE /api/spaces/space)', () => {
|
||||
it('should allow us to delete a space', async () => {
|
||||
await createSpace('space_to_delete');
|
||||
|
||||
await supertestAdminWithApiKey.delete(`/api/spaces/space/space_to_delete`).expect(204);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get active space (GET /internal/spaces/_active_space)', () => {
|
||||
before(async () => {
|
||||
await createSpace('foo-space');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteSpace('foo-space');
|
||||
});
|
||||
|
||||
it('returns the default space', async () => {
|
||||
const response = await supertestAdminWithCookieCredentials
|
||||
.get('/internal/spaces/_active_space')
|
||||
.set(samlAuth.getInternalRequestHeader())
|
||||
.expect(200);
|
||||
|
||||
const { id, name, _reserved } = response.body;
|
||||
expect({ id, name, _reserved }).toEqual({
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
_reserved: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the default space when explicitly referenced', async () => {
|
||||
const response = await supertestAdminWithCookieCredentials
|
||||
.get('/s/default/internal/spaces/_active_space')
|
||||
.set(samlAuth.getInternalRequestHeader())
|
||||
.expect(200);
|
||||
|
||||
const { id, name, _reserved } = response.body;
|
||||
expect({ id, name, _reserved }).toEqual({
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
_reserved: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the foo space', async () => {
|
||||
await supertestAdminWithCookieCredentials
|
||||
.get('/s/foo-space/internal/spaces/_active_space')
|
||||
.set(samlAuth.getInternalRequestHeader())
|
||||
.expect(200, {
|
||||
id: 'foo-space',
|
||||
name: 'foo-space',
|
||||
disabledFeatures: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('returns 404 when the space is not found', async () => {
|
||||
await supertestAdminWithCookieCredentials
|
||||
.get('/s/not-found-space/internal/spaces/_active_space')
|
||||
.set(samlAuth.getInternalRequestHeader())
|
||||
.expect(404, {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: 'Saved object [space/not-found-space] not found',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('route access', () => {
|
||||
// The 'internal route access' tests check that the internal header
|
||||
// is needed for these specific endpoints.
|
||||
// When accessed without internal headers they will return 400.
|
||||
// They could be moved to deployment agnostic testing if there is
|
||||
// a way to specify which tests to run when stateful vs serverles,
|
||||
// as internal vs disabled is different in serverless.
|
||||
describe('internal', () => {
|
||||
it('#getActiveSpace requires internal header', async () => {
|
||||
let body: any;
|
||||
|
@ -251,6 +403,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
|
||||
// Disabled in serverless, but public in stateful
|
||||
describe('disabled', () => {
|
||||
it('#disableLegacyUrlAliases', async () => {
|
||||
const { body, status } = await supertestAdminWithApiKey
|
||||
|
@ -262,26 +415,5 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Re-enable test-suite once users can create and update spaces in the Serverless offering.
|
||||
// it('rejects request to update a space with disabledFeatures', async () => {
|
||||
// const { body, status } = await supertest
|
||||
// .put('/api/spaces/space/default')
|
||||
// .set(svlCommonApi.getInternalRequestHeader())
|
||||
// .send({
|
||||
// id: 'custom',
|
||||
// name: 'Custom',
|
||||
// disabledFeatures: ['some-feature'],
|
||||
// });
|
||||
//
|
||||
// // in a non-serverless environment this would succeed with a 200
|
||||
// expect(body).toEqual({
|
||||
// statusCode: 400,
|
||||
// error: 'Bad Request',
|
||||
// message:
|
||||
// 'Unable to update Space, the disabledFeatures array must be empty when xpack.spaces.allowFeatureVisibility setting is disabled',
|
||||
// });
|
||||
// expect(status).toBe(400);
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,951 +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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import type { Role } from '@kbn/security-plugin-types-common';
|
||||
import { SupertestWithRoleScopeType } from '@kbn/test-suites-xpack/api_integration/deployment_agnostic/services';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
// Notes:
|
||||
// Test coverage comes from stateful test suite: x-pack/test/api_integration/apis/security/roles.ts
|
||||
// It has been modified to work for serverless by removing invalid options (run_as, allow_restricted_indices, etc).
|
||||
//
|
||||
// Note: this suite is currently only called from the feature flags test configs, e.g.
|
||||
// x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
|
||||
//
|
||||
// This suite should be converted into a deployment agnostic suite when the native roles
|
||||
// feature flags are enabled permanently in serverless. Additionally, the route access tests
|
||||
// for the roles APIs in authorization.ts should also get updated at that time.
|
||||
// kbnServerArgs: ['--xpack.security.roleManagementEnabled=true'],
|
||||
// esServerArgs: ['xpack.security.authc.native_roles.enabled=true'],
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const platformSecurityUtils = getService('platformSecurityUtils');
|
||||
const roleScopedSupertest = getService('roleScopedSupertest');
|
||||
const svlCommonApi = getService('svlCommonApi');
|
||||
let supertestAdminWithApiKey: SupertestWithRoleScopeType;
|
||||
let supertestAdminWithCookieCredentials: SupertestWithRoleScopeType;
|
||||
const es = getService('es');
|
||||
|
||||
describe('security', function () {
|
||||
describe('Roles', () => {
|
||||
before(async () => {
|
||||
supertestAdminWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope(
|
||||
'admin',
|
||||
{
|
||||
useCookieHeader: true,
|
||||
withInternalHeaders: true,
|
||||
}
|
||||
);
|
||||
supertestAdminWithApiKey = await roleScopedSupertest.getSupertestWithRoleScope('admin', {
|
||||
withCommonHeaders: true,
|
||||
});
|
||||
});
|
||||
after(async () => {
|
||||
await platformSecurityUtils.clearAllRoles();
|
||||
});
|
||||
|
||||
describe('Create Role', () => {
|
||||
it('should allow us to create an empty role', async () => {
|
||||
await supertestAdminWithApiKey.put('/api/security/role/empty_role').send({}).expect(204);
|
||||
});
|
||||
|
||||
it('should create a role with kibana and elasticsearch privileges', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_with_privileges')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['read'],
|
||||
},
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
discover: ['all'],
|
||||
ml: ['all'],
|
||||
},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(204);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_with_privileges' });
|
||||
expect(role).toEqual({
|
||||
role_with_privileges: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['feature_dashboard.read', 'feature_discover.all', 'feature_ml.all'],
|
||||
resources: ['space:marketing', 'space:sales'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it(`should create a role with kibana and FLS/DLS elasticsearch privileges`, async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_with_privileges_dls_fls')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*'],
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
.expect(204);
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not create a role with 'run as' privileges`, async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_with_privileges')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
run_as: ['admin'],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['read'],
|
||||
},
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
discover: ['all'],
|
||||
ml: ['all'],
|
||||
},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not create a role with remote cluster privileges`, async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_with_privileges')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
remote_cluster: [
|
||||
{
|
||||
clusters: ['remote_cluster1'],
|
||||
privileges: ['monitor_enrich'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['read'],
|
||||
},
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
discover: ['all'],
|
||||
ml: ['all'],
|
||||
},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not create a role with remote index privileges`, async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_with_privileges')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
remote_indices: [
|
||||
{
|
||||
clusters: ['remote_cluster1'],
|
||||
names: ['remote_index1', 'remote_index2'],
|
||||
privileges: ['all'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['read'],
|
||||
},
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
discover: ['all'],
|
||||
ml: ['all'],
|
||||
},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
describe('with the createOnly option enabled', () => {
|
||||
it('should fail when role already exists', async () => {
|
||||
await es.security.putRole({
|
||||
name: 'test_role',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/test_role?createOnly=true')
|
||||
.send({})
|
||||
.expect(409);
|
||||
});
|
||||
|
||||
it('should succeed when role does not exist', async () => {
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/new_role?createOnly=true')
|
||||
.send({})
|
||||
.expect(204);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Read Role', () => {
|
||||
it('should get roles', async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_get',
|
||||
body: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['feature_dashboard.read', 'feature_discover.all', 'feature_ml.all'],
|
||||
resources: ['space:marketing', 'space:sales'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey.get('/api/security/role/role_to_get').expect(200, {
|
||||
name: 'role_to_get',
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
transient_metadata: { enabled: true },
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
run_as: [],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['read'],
|
||||
feature: {},
|
||||
spaces: ['*'],
|
||||
},
|
||||
{
|
||||
base: [],
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
discover: ['all'],
|
||||
ml: ['all'],
|
||||
},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
|
||||
_transform_error: [],
|
||||
_unrecognized_applications: ['apm'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should get roles by space id', async () => {
|
||||
await es.security.putRole({
|
||||
name: 'space_role_not_to_get',
|
||||
body: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['feature_dashboard.read', 'feature_discover.all', 'feature_ml.all'],
|
||||
resources: ['space:marketing', 'space:sales'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await es.security.putRole({
|
||||
name: 'space_role_to_get',
|
||||
body: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['feature_dashboard.read', 'feature_discover.all', 'feature_ml.all'],
|
||||
resources: ['space:engineering', 'space:sales'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithCookieCredentials
|
||||
.get('/internal/security/roles/engineering')
|
||||
.expect(200)
|
||||
.expect((res: { body: Role[] }) => {
|
||||
const roles = res.body;
|
||||
|
||||
const success = roles.every((role) => {
|
||||
return (
|
||||
role.name !== 'space_role_not_to_get' &&
|
||||
role.kibana.some((privilege) => {
|
||||
return (
|
||||
privilege.spaces.includes('*') || privilege.spaces.includes('engineering')
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
const expectedRole = roles.find((role) => role.name === 'space_role_to_get');
|
||||
|
||||
expect(success).toBe(true);
|
||||
expect(expectedRole).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update Role', () => {
|
||||
it('should update a role with elasticsearch, kibana and other applications privileges', async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_update',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_to_update')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
dev_tools: ['all'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(204);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_to_update' });
|
||||
expect(role).toEqual({
|
||||
role_to_update: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['feature_dashboard.read', 'feature_dev_tools.all'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['space_all'],
|
||||
resources: ['space:marketing', 'space:sales'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it(`should update a role adding DLS and FLS privileges`, async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_update_with_dls_fls',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_to_update_with_dls_fls')
|
||||
.send({
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
field_security: {
|
||||
grant: ['*'],
|
||||
except: ['geo.*'],
|
||||
},
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read'],
|
||||
query: `{ "match": { "geo.src": "CN" } }`,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
.expect(204);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_to_update_with_dls_fls' });
|
||||
|
||||
expect(role.role_to_update_with_dls_fls.cluster).toEqual(['manage']);
|
||||
expect(role.role_to_update_with_dls_fls.indices[0].names).toEqual(['logstash-*']);
|
||||
expect(role.role_to_update_with_dls_fls.indices[0].query).toEqual(
|
||||
`{ "match": { "geo.src": "CN" } }`
|
||||
);
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not update a role with 'run as' privileges`, async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_update',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_to_update')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
run_as: ['admin'],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
dev_tools: ['all'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_to_update' });
|
||||
expect(role).toEqual({
|
||||
role_to_update: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not update a role with remote cluster privileges`, async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_update',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_to_update')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
remote_cluster: [
|
||||
{
|
||||
clusters: ['remote_cluster1'],
|
||||
privileges: ['monitor_enrich'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
dev_tools: ['all'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_to_update' });
|
||||
expect(role).toEqual({
|
||||
role_to_update: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// serverless only (stateful will allow)
|
||||
it(`should not update a role with remote index privileges`, async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_update',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await supertestAdminWithApiKey
|
||||
.put('/api/security/role/role_to_update')
|
||||
.send({
|
||||
metadata: {
|
||||
foo: 'test-metadata',
|
||||
},
|
||||
elasticsearch: {
|
||||
cluster: ['manage'],
|
||||
indices: [
|
||||
{
|
||||
names: ['logstash-*'],
|
||||
privileges: ['read', 'view_index_metadata'],
|
||||
},
|
||||
],
|
||||
remote_indices: [
|
||||
{
|
||||
clusters: ['remote_cluster1'],
|
||||
names: ['remote_index1', 'remote_index2'],
|
||||
privileges: ['all'],
|
||||
},
|
||||
],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
feature: {
|
||||
dashboard: ['read'],
|
||||
dev_tools: ['all'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
const role = await es.security.getRole({ name: 'role_to_update' });
|
||||
expect(role).toEqual({
|
||||
role_to_update: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
allow_restricted_indices: false,
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete Role', () => {
|
||||
it('should delete an existing role', async () => {
|
||||
await es.security.putRole({
|
||||
name: 'role_to_delete',
|
||||
body: {
|
||||
cluster: ['monitor'],
|
||||
indices: [
|
||||
{
|
||||
names: ['beats-*'],
|
||||
privileges: ['write'],
|
||||
},
|
||||
],
|
||||
applications: [
|
||||
{
|
||||
application: 'kibana-.kibana',
|
||||
privileges: ['read'],
|
||||
resources: ['*'],
|
||||
},
|
||||
{
|
||||
application: 'apm',
|
||||
privileges: ['apm-privilege'],
|
||||
resources: ['*'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
bar: 'old-metadata',
|
||||
},
|
||||
},
|
||||
});
|
||||
await supertestAdminWithApiKey.delete('/api/security/role/role_to_delete').expect(204);
|
||||
|
||||
const deletedRole = await es.security.getRole(
|
||||
{ name: 'role_to_delete' },
|
||||
{ ignore: [404] }
|
||||
);
|
||||
expect(deletedRole).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Access', () => {
|
||||
describe('public', () => {
|
||||
it('reset session page', async () => {
|
||||
const { status } = await supertestAdminWithCookieCredentials.get(
|
||||
'/internal/security/reset_session_page.js'
|
||||
);
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
});
|
||||
describe('Disabled', () => {
|
||||
it('get shared saved object permissions', async () => {
|
||||
const { body, status } = await supertestAdminWithCookieCredentials.get(
|
||||
'/internal/security/_share_saved_object_permissions'
|
||||
);
|
||||
svlCommonApi.assertApiNotFound(body, status);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -22,13 +22,12 @@ export default createTestConfig({
|
|||
// add feature flags
|
||||
kbnServerArgs: [
|
||||
'--xpack.infra.enabled=true',
|
||||
'--xpack.security.roleManagementEnabled=true', // enables custom roles
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
'--xpack.security.roleManagementEnabled=true', // needed to check composite feautures in /observability/platform_security/authorization.ts
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/observability/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.dfa.enabled=false', 'xpack.security.authc.native_roles.enabled=true'],
|
||||
esServerArgs: ['xpack.ml.dfa.enabled=false'],
|
||||
});
|
||||
|
|
|
@ -12,7 +12,5 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./custom_threshold_rule'));
|
||||
loadTestFile(require.resolve('./infra'));
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts'));
|
||||
loadTestFile(require.resolve('../common/management/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ export default createTestConfig({
|
|||
suiteTags: { exclude: ['skipSvlSearch'] },
|
||||
// add feature flags
|
||||
kbnServerArgs: [
|
||||
'--xpack.security.roleManagementEnabled=true', // enables custom roles
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
`--xpack.searchIndices.enabled=true`, // global empty state FF
|
||||
],
|
||||
// load tests in the index file
|
||||
|
@ -28,5 +26,5 @@ export default createTestConfig({
|
|||
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/esproject/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.security.authc.native_roles.enabled=true'],
|
||||
esServerArgs: [],
|
||||
});
|
||||
|
|
|
@ -10,8 +10,5 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Serverless search API - feature flags', function () {
|
||||
loadTestFile(require.resolve('./search_indices'));
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts'));
|
||||
loadTestFile(require.resolve('../common/management/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,5 +14,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./cases/find_cases'));
|
||||
loadTestFile(require.resolve('./cases/post_case'));
|
||||
loadTestFile(require.resolve('./serverless_search'));
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,14 +18,11 @@ export default createTestConfig({
|
|||
},
|
||||
suiteTags: { exclude: ['skipSvlSec'] },
|
||||
// add feature flags
|
||||
kbnServerArgs: [
|
||||
'--xpack.security.roleManagementEnabled=true', // enables custom roles
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
],
|
||||
kbnServerArgs: [],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/security/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.nlp.enabled=true', 'xpack.security.authc.native_roles.enabled=true'],
|
||||
esServerArgs: ['xpack.ml.nlp.enabled=true'],
|
||||
});
|
||||
|
|
|
@ -8,9 +8,5 @@
|
|||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Serverless security API - feature flags', function () {
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles_routes_feature_flag.ts'));
|
||||
loadTestFile(require.resolve('../common/management/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
describe('Serverless security API - feature flags', function () {});
|
||||
}
|
||||
|
|
|
@ -13,5 +13,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
|
||||
loadTestFile(require.resolve('./cases'));
|
||||
loadTestFile(require.resolve('./cloud_security_posture'));
|
||||
loadTestFile(require.resolve('./platform_security'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,10 +41,6 @@ export function createTestConfig(options: CreateTestConfigOptions) {
|
|||
`--xpack.trigger_actions_ui.enableExperimental=${JSON.stringify([
|
||||
'isUsingRuleCreateFlyout',
|
||||
])}`,
|
||||
// custom native roles are enabled only for search and security projects
|
||||
...(options.serverlessProject !== 'oblt'
|
||||
? ['--xpack.security.roleManagementEnabled=true']
|
||||
: []),
|
||||
...(options.kbnServerArgs ?? []),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -13,6 +13,8 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
|
||||
loadTestFile(require.resolve('./api_keys'));
|
||||
loadTestFile(require.resolve('./navigation/avatar_menu'));
|
||||
loadTestFile(require.resolve('./navigation/management_nav_cards'));
|
||||
loadTestFile(require.resolve('./user_profiles/user_profiles'));
|
||||
loadTestFile(require.resolve('./roles.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -46,16 +46,17 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
expect(url).to.contain('/management/security/api_keys');
|
||||
});
|
||||
|
||||
it('displays the roles management card, and will navigate to the Roles UI', async () => {
|
||||
await pageObjects.svlManagementPage.assertRoleManagementCardExists();
|
||||
await pageObjects.svlManagementPage.clickRoleManagementCard();
|
||||
|
||||
const url = await browser.getCurrentUrl();
|
||||
expect(url).to.contain('/management/security/roles');
|
||||
});
|
||||
|
||||
describe('Organization members', function () {
|
||||
describe('custom roles', function () {
|
||||
this.tags('skipSvlOblt'); // Observability will not support custom roles
|
||||
|
||||
it('displays the roles management card, and will navigate to the Roles UI', async () => {
|
||||
await pageObjects.svlManagementPage.assertRoleManagementCardExists();
|
||||
await pageObjects.svlManagementPage.clickRoleManagementCard();
|
||||
|
||||
const url = await browser.getCurrentUrl();
|
||||
expect(url).to.contain('/management/security/roles');
|
||||
});
|
||||
|
||||
it('displays the Organization members management card, and will navigate to the cloud organization URL', async () => {
|
||||
await pageObjects.svlManagementPage.assertOrgMembersManagementCardExists();
|
||||
await pageObjects.svlManagementPage.clickOrgMembersManagementCard();
|
||||
|
|
|
@ -19,6 +19,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
const platformSecurityUtils = getService('platformSecurityUtils');
|
||||
|
||||
describe('Roles', function () {
|
||||
// custom roles are not enabled for observability projects
|
||||
this.tags(['skipSvlOblt']);
|
||||
|
||||
describe('as Viewer', () => {
|
||||
before(async () => {
|
||||
await pageObjects.svlCommonPage.loginAsViewer();
|
||||
|
|
|
@ -11,6 +11,7 @@ export default ({ loadTestFile }: FtrProviderContext) => {
|
|||
describe('Spaces', function () {
|
||||
this.tags(['esGate']);
|
||||
|
||||
loadTestFile(require.resolve('./spaces_management.ts'));
|
||||
loadTestFile(require.resolve('./spaces_selection.ts'));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -15,51 +15,9 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
|
|||
export default function ({ getPageObject, getService }: FtrProviderContext) {
|
||||
const svlCommon = getPageObject('common');
|
||||
const svlCommonPage = getPageObject('svlCommonPage');
|
||||
const svlCommonNavigation = getService('svlCommonNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('spaces', function () {
|
||||
describe('selection', function () {
|
||||
describe('as Viewer', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.loginAsViewer();
|
||||
});
|
||||
|
||||
it('displays the space selection menu in header', async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
|
||||
await testSubjects.existOrFail('spacesNavSelector');
|
||||
});
|
||||
|
||||
it(`does not display the manage button in the space selection menu`, async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.click('spacesNavSelector');
|
||||
await testSubjects.missingOrFail('manageSpaces');
|
||||
});
|
||||
});
|
||||
|
||||
describe('as Admin', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.loginAsAdmin();
|
||||
});
|
||||
|
||||
it('displays the space selection menu in header', async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.existOrFail('spacesNavSelector');
|
||||
});
|
||||
|
||||
it(`displays the manage button in the space selection menu`, async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.click('spacesNavSelector');
|
||||
await testSubjects.existOrFail('manageSpaces');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('management', function () {
|
||||
describe('as Viewer', function () {
|
||||
before(async () => {
|
|
@ -12,18 +12,46 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
|
|||
const svlCommonNavigation = getService('svlCommonNavigation');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
// Skipped due to change in QA environment for role management and spaces
|
||||
// TODO: revisit once the change is rolled out to all environments
|
||||
describe.skip('space selection', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.loginAsViewer();
|
||||
});
|
||||
describe('spaces', function () {
|
||||
describe('selection', function () {
|
||||
describe('as Viewer', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.loginAsViewer();
|
||||
});
|
||||
|
||||
it('does not have the space selection menu in header', async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
it('displays the space selection menu in header', async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
|
||||
await testSubjects.missingOrFail('spacesNavSelector');
|
||||
await testSubjects.existOrFail('spacesNavSelector');
|
||||
});
|
||||
|
||||
it(`does not display the manage button in the space selection menu`, async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.click('spacesNavSelector');
|
||||
await testSubjects.missingOrFail('manageSpaces');
|
||||
});
|
||||
});
|
||||
|
||||
describe('as Admin', function () {
|
||||
before(async () => {
|
||||
await svlCommonPage.loginAsAdmin();
|
||||
});
|
||||
|
||||
it('displays the space selection menu in header', async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.existOrFail('spacesNavSelector');
|
||||
});
|
||||
|
||||
it(`displays the manage button in the space selection menu`, async () => {
|
||||
await svlCommonNavigation.navigateToKibanaHome();
|
||||
await svlCommonPage.assertProjectHeaderExists();
|
||||
await testSubjects.click('spacesNavSelector');
|
||||
await testSubjects.existOrFail('manageSpaces');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -22,10 +22,6 @@ export default createTestConfig({
|
|||
'--xpack.infra.enabled=true',
|
||||
'--xpack.infra.featureFlags.customThresholdAlertsEnabled=true',
|
||||
'--xpack.security.roleManagementEnabled=true',
|
||||
`--xpack.cloud.serverless.project_id='fakeprojectid'`,
|
||||
`--xpack.cloud.base_url='https://cloud.elastic.co'`,
|
||||
`--xpack.cloud.organization_url='/account/members'`,
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
|
|
@ -12,8 +12,5 @@ export default function ({ loadTestFile }: FtrProviderContext) {
|
|||
// add tests that require feature flags, defined in config.feature_flags.ts
|
||||
loadTestFile(require.resolve('./role_management'));
|
||||
loadTestFile(require.resolve('./infra'));
|
||||
loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles.ts'));
|
||||
loadTestFile(require.resolve('../common/spaces/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,19 +20,13 @@ export default createTestConfig({
|
|||
// add feature flags
|
||||
kbnServerArgs: [
|
||||
`--xpack.cloud.id=ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg==`,
|
||||
`--xpack.cloud.serverless.project_id=fakeprojectid`,
|
||||
`--xpack.cloud.base_url=https://fake-cloud.elastic.co`,
|
||||
`--xpack.cloud.projects_url=/projects/`,
|
||||
`--xpack.cloud.organization_url=/account/members`,
|
||||
`--xpack.security.roleManagementEnabled=true`,
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/esproject/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.security.authc.native_roles.enabled=true'],
|
||||
esServerArgs: [],
|
||||
apps: {
|
||||
serverlessElasticsearch: {
|
||||
pathname: '/app/elasticsearch/getting_started',
|
||||
|
|
|
@ -20,16 +20,8 @@ export default createTestConfig({
|
|||
esServerArgs: [],
|
||||
kbnServerArgs: [
|
||||
`--xpack.cloud.id=ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg==`,
|
||||
`--xpack.cloud.serverless.project_id=fakeprojectid`,
|
||||
`--xpack.cloud.serverless.project_name=ES3_FTR_TESTS`,
|
||||
`--xpack.cloud.base_url=https://fake-cloud.elastic.co`,
|
||||
`--xpack.cloud.profile_url=/user/settings/`,
|
||||
`--xpack.cloud.billing_url=/billing/overview/`,
|
||||
`--xpack.cloud.deployments_url=/deployments`,
|
||||
`--xpack.cloud.deployment_url=/projects/elasticsearch/fakeprojectid`,
|
||||
`--xpack.cloud.users_and_roles_url=/account/members/`,
|
||||
`--xpack.cloud.projects_url=/projects/`,
|
||||
`--xpack.cloud.organization_url=/account/`,
|
||||
],
|
||||
apps: {
|
||||
serverlessElasticsearch: {
|
||||
|
|
|
@ -10,9 +10,5 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('serverless search UI - feature flags', function () {
|
||||
// add tests that require feature flags, defined in config.feature_flags.ts
|
||||
|
||||
loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles.ts'));
|
||||
loadTestFile(require.resolve('../common/spaces/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,16 +18,11 @@ export default createTestConfig({
|
|||
},
|
||||
suiteTags: { exclude: ['skipSvlSec'] },
|
||||
// add feature flags
|
||||
kbnServerArgs: [
|
||||
`--xpack.security.roleManagementEnabled=true`,
|
||||
`--xpack.cloud.base_url='https://cloud.elastic.co'`,
|
||||
`--xpack.cloud.organization_url='/account/members'`,
|
||||
`--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities
|
||||
],
|
||||
kbnServerArgs: [],
|
||||
// load tests in the index file
|
||||
testFiles: [require.resolve('./index.feature_flags.ts')],
|
||||
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/security/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.nlp.enabled=true', 'xpack.security.authc.native_roles.enabled=true'],
|
||||
esServerArgs: ['xpack.ml.nlp.enabled=true'],
|
||||
});
|
||||
|
|
|
@ -10,8 +10,5 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('serverless security UI - feature flags', function () {
|
||||
// add tests that require feature flags, defined in config.feature_flags.ts
|
||||
loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts'));
|
||||
loadTestFile(require.resolve('../common/platform_security/roles.ts'));
|
||||
loadTestFile(require.resolve('../common/spaces/multiple_spaces_enabled.ts'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -151,7 +151,6 @@ export default async () => {
|
|||
// This ensures that we register the Security SAML API endpoints.
|
||||
// In the real world the SAML config is injected by control plane.
|
||||
`--plugin-path=${samlIdPPlugin}`,
|
||||
'--xpack.cloud.id=ftr_fake_cloud_id',
|
||||
// Ensure that SAML is used as the default authentication method whenever a user navigates to Kibana. In other
|
||||
// words, Kibana should attempt to authenticate the user using the provider with the lowest order if the Login
|
||||
// Selector is disabled (which is how Serverless Kibana is configured). By declaring `cloud-basic` with a higher
|
||||
|
@ -167,6 +166,16 @@ export default async () => {
|
|||
// configure security reponse header report-to settings to mimic MKI configuration
|
||||
`--csp.report_to=${JSON.stringify(['violations-endpoint'])}`,
|
||||
`--permissionsPolicy.report_to=${JSON.stringify(['violations-endpoint'])}`,
|
||||
// normally below is injected by control plane
|
||||
'--xpack.cloud.id=ftr_fake_cloud_id',
|
||||
`--xpack.cloud.serverless.project_id=fakeprojectid`,
|
||||
`--xpack.cloud.base_url=https://fake-cloud.elastic.co`,
|
||||
`--xpack.cloud.projects_url=/projects/`,
|
||||
`--xpack.cloud.profile_url=/user/settings/`,
|
||||
`--xpack.cloud.billing_url=/billing/overview/`,
|
||||
`--xpack.cloud.deployments_url=/deployments`,
|
||||
`--xpack.cloud.organization_url=/account/`,
|
||||
`--xpack.cloud.users_and_roles_url=/account/members/`,
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -97,8 +97,8 @@
|
|||
"@kbn/test-suites-src",
|
||||
"@kbn/console-plugin",
|
||||
"@kbn/cloud-security-posture-common",
|
||||
"@kbn/security-plugin-types-common",
|
||||
"@kbn/core-saved-objects-import-export-server-internal",
|
||||
"@kbn/security-plugin-types-common",
|
||||
"@kbn/ai-assistant-common",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue