mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
# Backport This will backport the following commits from `main` to `8.18`: - [[CLOUD] Add security question in onboarding (#208229)](https://github.com/elastic/kibana/pull/208229) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Xavier Mouligneau","email":"xavier.mouligneau@elastic.co"},"sourceCommit":{"committedDate":"2025-01-31T09:22:22Z","message":"[CLOUD] Add security question in onboarding (#208229)\n\n## Summary\r\n\r\nhttps://github.com/elastic/cloud/issues/133183\r\n\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kateryna Stukan <92258556+galaxxyz@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"ac22f58bc3531b4cc683c982b89804b9a58421f2","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Cloud","release_note:skip","v9.0.0","backport:version","v8.18.0","v9.1.0","v8.19.0"],"title":"[CLOUD] Add security question in onboarding","number":208229,"url":"https://github.com/elastic/kibana/pull/208229","mergeCommit":{"message":"[CLOUD] Add security question in onboarding (#208229)\n\n## Summary\r\n\r\nhttps://github.com/elastic/cloud/issues/133183\r\n\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kateryna Stukan <92258556+galaxxyz@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"ac22f58bc3531b4cc683c982b89804b9a58421f2"}},"sourceBranch":"main","suggestedTargetBranches":["8.18"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/209073","number":209073,"state":"MERGED","mergeCommit":{"sha":"6208d6d92948e5a9b676b32b15de673175d711a8","message":"[9.0] [CLOUD] Add security question in onboarding (#208229) (#209073)\n\n# Backport\n\nThis will backport the following commits from `main` to `9.0`:\n- [[CLOUD] Add security question in onboarding\n(#208229)](https://github.com/elastic/kibana/pull/208229)\n\n<!--- Backport version: 9.4.3 -->\n\n### Questions ?\nPlease refer to the [Backport tool\ndocumentation](https://github.com/sqren/backport)\n\n<!--BACKPORT [{\"author\":{\"name\":\"Xavier\nMouligneau\",\"email\":\"xavier.mouligneau@elastic.co\"},\"sourceCommit\":{\"committedDate\":\"2025-01-31T09:22:22Z\",\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\",\"branchLabelMapping\":{\"^v9.1.0$\":\"main\",\"^v8.19.0$\":\"8.x\",\"^v(\\\\d+).(\\\\d+).\\\\d+$\":\"$1.$2\"}},\"sourcePullRequest\":{\"labels\":[\"Team:Cloud\",\"release_note:skip\",\"v9.0.0\",\"backport:version\",\"v9.1.0\",\"v8.19.0\"],\"title\":\"[CLOUD]\nAdd security question in\nonboarding\",\"number\":208229,\"url\":\"https://github.com/elastic/kibana/pull/208229\",\"mergeCommit\":{\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\"}},\"sourceBranch\":\"main\",\"suggestedTargetBranches\":[\"9.0\",\"8.x\"],\"targetPullRequestStates\":[{\"branch\":\"9.0\",\"label\":\"v9.0.0\",\"branchLabelMappingKey\":\"^v(\\\\d+).(\\\\d+).\\\\d+$\",\"isSourceBranch\":false,\"state\":\"NOT_CREATED\"},{\"branch\":\"main\",\"label\":\"v9.1.0\",\"branchLabelMappingKey\":\"^v9.1.0$\",\"isSourceBranch\":true,\"state\":\"MERGED\",\"url\":\"https://github.com/elastic/kibana/pull/208229\",\"number\":208229,\"mergeCommit\":{\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\"}},{\"branch\":\"8.x\",\"label\":\"v8.19.0\",\"branchLabelMappingKey\":\"^v8.19.0$\",\"isSourceBranch\":false,\"state\":\"NOT_CREATED\"}]}]\nBACKPORT-->\n\nCo-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>"}},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/208229","number":208229,"mergeCommit":{"message":"[CLOUD] Add security question in onboarding (#208229)\n\n## Summary\r\n\r\nhttps://github.com/elastic/cloud/issues/133183\r\n\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Kateryna Stukan <92258556+galaxxyz@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>","sha":"ac22f58bc3531b4cc683c982b89804b9a58421f2"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/209072","number":209072,"state":"MERGED","mergeCommit":{"sha":"a4dcb6202da75691c9a6ab9cdf0a63bdcd969aee","message":"[8.x] [CLOUD] Add security question in onboarding (#208229) (#209072)\n\n# Backport\n\nThis will backport the following commits from `main` to `8.x`:\n- [[CLOUD] Add security question in onboarding\n(#208229)](https://github.com/elastic/kibana/pull/208229)\n\n<!--- Backport version: 9.4.3 -->\n\n### Questions ?\nPlease refer to the [Backport tool\ndocumentation](https://github.com/sqren/backport)\n\n<!--BACKPORT [{\"author\":{\"name\":\"Xavier\nMouligneau\",\"email\":\"xavier.mouligneau@elastic.co\"},\"sourceCommit\":{\"committedDate\":\"2025-01-31T09:22:22Z\",\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\",\"branchLabelMapping\":{\"^v9.1.0$\":\"main\",\"^v8.19.0$\":\"8.x\",\"^v(\\\\d+).(\\\\d+).\\\\d+$\":\"$1.$2\"}},\"sourcePullRequest\":{\"labels\":[\"Team:Cloud\",\"release_note:skip\",\"v9.0.0\",\"backport:version\",\"v9.1.0\",\"v8.19.0\"],\"title\":\"[CLOUD]\nAdd security question in\nonboarding\",\"number\":208229,\"url\":\"https://github.com/elastic/kibana/pull/208229\",\"mergeCommit\":{\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\"}},\"sourceBranch\":\"main\",\"suggestedTargetBranches\":[\"9.0\",\"8.x\"],\"targetPullRequestStates\":[{\"branch\":\"9.0\",\"label\":\"v9.0.0\",\"branchLabelMappingKey\":\"^v(\\\\d+).(\\\\d+).\\\\d+$\",\"isSourceBranch\":false,\"state\":\"NOT_CREATED\"},{\"branch\":\"main\",\"label\":\"v9.1.0\",\"branchLabelMappingKey\":\"^v9.1.0$\",\"isSourceBranch\":true,\"state\":\"MERGED\",\"url\":\"https://github.com/elastic/kibana/pull/208229\",\"number\":208229,\"mergeCommit\":{\"message\":\"[CLOUD]\nAdd security question in onboarding (#208229)\\n\\n##\nSummary\\r\\n\\r\\nhttps://github.com/elastic/cloud/issues/133183\\r\\n\\r\\n\\r\\n\\r\\n###\nChecklist\\r\\n\\r\\n- [x] [Unit or\nfunctional\\r\\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\\r\\nwere\nupdated or added to match the most common\nscenarios\\r\\n\\r\\n---------\\r\\n\\r\\nCo-authored-by: Kateryna Stukan\n<92258556+galaxxyz@users.noreply.github.com>\\r\\nCo-authored-by: Elastic\nMachine\n<elasticmachine@users.noreply.github.com>\",\"sha\":\"ac22f58bc3531b4cc683c982b89804b9a58421f2\"}},{\"branch\":\"8.x\",\"label\":\"v8.19.0\",\"branchLabelMappingKey\":\"^v8.19.0$\",\"isSourceBranch\":false,\"state\":\"NOT_CREATED\"}]}]\nBACKPORT-->\n\nCo-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>"}}]}] BACKPORT--> Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>
This commit is contained in:
parent
55798e1877
commit
feab0224a0
7 changed files with 404 additions and 79 deletions
|
@ -47,6 +47,41 @@ describe('persistTokenCloudData', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('creates a new saved object if none exists and security details are provided', async () => {
|
||||
(mockSavedObjectsClient.get as jest.Mock).mockRejectedValue(
|
||||
SavedObjectsErrorHelpers.createGenericNotFoundError()
|
||||
);
|
||||
await persistTokenCloudData(mockSavedObjectsClient, {
|
||||
logger: mockLogger,
|
||||
solutionType: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockSavedObjectsClient.create).toHaveBeenCalledWith(
|
||||
CLOUD_DATA_SAVED_OBJECT_TYPE,
|
||||
{
|
||||
onboardingData: {
|
||||
solutionType: 'security',
|
||||
token: '',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ id: CLOUD_DATA_SAVED_OBJECT_ID }
|
||||
);
|
||||
});
|
||||
|
||||
it('updates an existing saved object if onboardingToken is provided and different', async () => {
|
||||
(mockSavedObjectsClient.get as jest.Mock).mockResolvedValue({
|
||||
id: CLOUD_DATA_SAVED_OBJECT_ID,
|
||||
|
@ -75,13 +110,67 @@ describe('persistTokenCloudData', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('does nothing if onboardingToken is the same', async () => {
|
||||
it('updates an existing saved object if security details are provided and different', async () => {
|
||||
(mockSavedObjectsClient.get as jest.Mock).mockResolvedValue({
|
||||
id: CLOUD_DATA_SAVED_OBJECT_ID,
|
||||
attributes: {
|
||||
onboardingData: {
|
||||
solutionType: 'security',
|
||||
token: 'test_token',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await persistTokenCloudData(mockSavedObjectsClient, {
|
||||
logger: mockLogger,
|
||||
solutionType: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockSavedObjectsClient.update).toHaveBeenCalledWith(
|
||||
CLOUD_DATA_SAVED_OBJECT_TYPE,
|
||||
CLOUD_DATA_SAVED_OBJECT_ID,
|
||||
{
|
||||
onboardingData: {
|
||||
solutionType: 'security',
|
||||
token: 'test_token',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('does nothing if onboardingToken and security details are the same', async () => {
|
||||
(mockSavedObjectsClient.get as jest.Mock).mockResolvedValue({
|
||||
id: CLOUD_DATA_SAVED_OBJECT_ID,
|
||||
attributes: {
|
||||
onboardingData: {
|
||||
token: 'same_token',
|
||||
solutionType: 'test_solution',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -89,6 +178,13 @@ describe('persistTokenCloudData', () => {
|
|||
logger: mockLogger,
|
||||
onboardingToken: 'same_token',
|
||||
solutionType: 'test_solution',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockSavedObjectsClient.update).not.toHaveBeenCalled();
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isDeepEqual } from 'react-use/lib/util';
|
||||
|
||||
import { Logger, SavedObjectsClientContract, SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { CloudDataAttributes, SolutionType } from '../routes/types';
|
||||
import { CloudDataAttributes, CloudSecurityAnswer, SolutionType } from '../routes/types';
|
||||
import { CLOUD_DATA_SAVED_OBJECT_TYPE } from '../saved_objects';
|
||||
import { CLOUD_DATA_SAVED_OBJECT_ID } from '../routes/constants';
|
||||
|
||||
|
@ -17,11 +19,13 @@ export const persistTokenCloudData = async (
|
|||
returnError,
|
||||
onboardingToken,
|
||||
solutionType,
|
||||
security,
|
||||
}: {
|
||||
logger?: Logger;
|
||||
returnError?: boolean;
|
||||
onboardingToken?: string;
|
||||
solutionType?: string;
|
||||
security?: CloudSecurityAnswer;
|
||||
}
|
||||
): Promise<void> => {
|
||||
let cloudDataSo = null;
|
||||
|
@ -41,23 +45,25 @@ export const persistTokenCloudData = async (
|
|||
}
|
||||
}
|
||||
}
|
||||
const securityAttributes = cloudDataSo?.attributes.onboardingData?.security;
|
||||
|
||||
try {
|
||||
if (onboardingToken && cloudDataSo === null) {
|
||||
if ((onboardingToken || security) && cloudDataSo === null) {
|
||||
await savedObjectsClient.create<CloudDataAttributes>(
|
||||
CLOUD_DATA_SAVED_OBJECT_TYPE,
|
||||
{
|
||||
onboardingData: {
|
||||
solutionType: solutionType as SolutionType,
|
||||
token: onboardingToken,
|
||||
token: onboardingToken ?? '',
|
||||
security,
|
||||
},
|
||||
},
|
||||
{ id: CLOUD_DATA_SAVED_OBJECT_ID }
|
||||
);
|
||||
} else if (
|
||||
onboardingToken &&
|
||||
cloudDataSo?.attributes.onboardingData.token &&
|
||||
cloudDataSo?.attributes.onboardingData.token !== onboardingToken
|
||||
cloudDataSo &&
|
||||
(cloudDataSo?.attributes.onboardingData.token !== onboardingToken ||
|
||||
!isDeepEqual(securityAttributes, security))
|
||||
) {
|
||||
await savedObjectsClient.update<CloudDataAttributes>(
|
||||
CLOUD_DATA_SAVED_OBJECT_TYPE,
|
||||
|
@ -66,7 +72,8 @@ export const persistTokenCloudData = async (
|
|||
onboardingData: {
|
||||
solutionType:
|
||||
(solutionType as SolutionType) ?? cloudDataSo?.attributes.onboardingData.solutionType,
|
||||
token: onboardingToken,
|
||||
token: onboardingToken ?? cloudDataSo?.attributes.onboardingData.token,
|
||||
security: security ?? securityAttributes,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -13,6 +13,7 @@ import type { SolutionId } from '@kbn/core-chrome-browser';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import { parseNextURL } from '@kbn/std';
|
||||
|
||||
import camelcaseKeys from 'camelcase-keys';
|
||||
import type { CloudConfigType } from './config';
|
||||
|
||||
import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context';
|
||||
|
@ -215,6 +216,24 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
{
|
||||
next: schema.maybe(schema.string()),
|
||||
onboarding_token: schema.maybe(schema.string()),
|
||||
security: schema.maybe(
|
||||
schema.object({
|
||||
use_case: schema.oneOf([
|
||||
schema.literal('siem'),
|
||||
schema.literal('cloud'),
|
||||
schema.literal('edr'),
|
||||
schema.literal('other'),
|
||||
]),
|
||||
migration: schema.maybe(
|
||||
schema.object({
|
||||
value: schema.boolean(),
|
||||
type: schema.maybe(
|
||||
schema.oneOf([schema.literal('splunk'), schema.literal('other')])
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
},
|
||||
{ unknowns: 'ignore' }
|
||||
)
|
||||
|
@ -237,9 +256,16 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
// need to get reed of ../../ to make sure we will not be out of space basePath
|
||||
const normalizedRoute = new URL(route, 'https://localhost');
|
||||
|
||||
const queryOnboardingToken = request.url.searchParams.get('onboarding_token');
|
||||
const queryOnboardingToken = request.query?.onboarding_token ?? undefined;
|
||||
const queryOnboardingSecurityRaw = request.query?.security ?? undefined;
|
||||
const queryOnboardingSecurity = queryOnboardingSecurityRaw
|
||||
? camelcaseKeys(queryOnboardingSecurityRaw, {
|
||||
deep: true,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const solutionType = this.config.onboarding?.default_solution;
|
||||
if (queryOnboardingToken) {
|
||||
if (queryOnboardingToken || queryOnboardingSecurity) {
|
||||
core
|
||||
.getStartServices()
|
||||
.then(async ([coreStart]) => {
|
||||
|
@ -251,6 +277,7 @@ export class CloudPlugin implements Plugin<CloudSetup, CloudStart> {
|
|||
logger: this.logger,
|
||||
onboardingToken: queryOnboardingToken,
|
||||
solutionType,
|
||||
security: queryOnboardingSecurity,
|
||||
});
|
||||
})
|
||||
.catch((errorMsg) => this.logger.error(errorMsg));
|
||||
|
|
|
@ -16,5 +16,14 @@ export interface CloudDataAttributes {
|
|||
onboardingData: {
|
||||
solutionType?: SolutionType;
|
||||
token: string;
|
||||
security?: CloudSecurityAnswer;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CloudSecurityAnswer {
|
||||
useCase: 'siem' | 'cloud' | 'edr' | 'other';
|
||||
migration?: {
|
||||
value: boolean;
|
||||
type?: 'splunk' | 'other';
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
const testEndpointsPlugin = resolve(__dirname, '../security_functional/plugins/test_endpoints');
|
||||
|
||||
return {
|
||||
testFiles: [resolve(__dirname, './tests/onboarding_token.ts')],
|
||||
testFiles: [resolve(__dirname, './tests/onboarding.ts')],
|
||||
|
||||
services,
|
||||
pageObjects,
|
||||
|
|
254
x-pack/test/functional_cloud/tests/onboarding.ts
Normal file
254
x-pack/test/functional_cloud/tests/onboarding.ts
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 { parse } from 'url';
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { MAIN_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
|
||||
import type { FtrProviderContext } from '../../security_functional/ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const es = getService('es');
|
||||
const find = getService('find');
|
||||
const browser = getService('browser');
|
||||
const deployment = getService('deployment');
|
||||
const PageObjects = getPageObjects(['common']);
|
||||
const supertest = getService('supertest');
|
||||
|
||||
const deleteSavedObject = async () => {
|
||||
await es.deleteByQuery({
|
||||
index: MAIN_SAVED_OBJECT_INDEX,
|
||||
q: 'type:cloud',
|
||||
wait_for_completion: true,
|
||||
refresh: true,
|
||||
body: {},
|
||||
conflicts: 'proceed',
|
||||
});
|
||||
};
|
||||
|
||||
describe('Onboarding integration', function () {
|
||||
this.tags('includeFirefox');
|
||||
|
||||
before(async () => {
|
||||
await getService('esSupertest')
|
||||
.post('/_security/role_mapping/saml1')
|
||||
.send({ roles: ['superuser'], enabled: true, rules: { field: { 'realm.name': 'saml1' } } })
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await browser.get(deployment.getHostPort() + '/logout');
|
||||
await PageObjects.common.waitUntilUrlIncludes('logged_out');
|
||||
|
||||
await deleteSavedObject();
|
||||
});
|
||||
|
||||
it('Redirect and save token', async () => {
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=vector&next=${encodeURIComponent(
|
||||
'/app/elasticsearch/vector_search'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
// We need to make sure that both path and hash are respected.
|
||||
const currentURL = parse(await browser.getCurrentUrl());
|
||||
expect(currentURL.pathname).to.eql('/app/elasticsearch/vector_search');
|
||||
expect(currentURL.hash).to.eql('#some=hash-value');
|
||||
|
||||
const {
|
||||
body: { onboardingData },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
expect(onboardingData).to.eql({ token: 'vector' });
|
||||
});
|
||||
|
||||
it('Redirect and save security details at creation time', async () => {
|
||||
const securityDetails = '{"use_case":"siem","migration":{"value":true,"type":"splunk"}}';
|
||||
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=security&security=${securityDetails}&next=${encodeURIComponent(
|
||||
'/app/security/get_started'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
// We need to make sure that both path and hash are respected.
|
||||
const currentURL = parse(await browser.getCurrentUrl());
|
||||
expect(currentURL.pathname).to.eql('/app/security/get_started');
|
||||
expect(currentURL.hash).to.eql('#some=hash-value');
|
||||
|
||||
const {
|
||||
body: { onboardingData },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
expect(onboardingData).to.eql({
|
||||
token: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('Redirect and update security details', async () => {
|
||||
const securityDetails = '{"use_case":"siem","migration":{"value":true,"type":"splunk"}}';
|
||||
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=security&security=${securityDetails}&next=${encodeURIComponent(
|
||||
'/app/security/get_started'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
// We need to make sure that both path and hash are respected.
|
||||
const currentURL = parse(await browser.getCurrentUrl());
|
||||
expect(currentURL.pathname).to.eql('/app/security/get_started');
|
||||
expect(currentURL.hash).to.eql('#some=hash-value');
|
||||
|
||||
const {
|
||||
body: { onboardingData },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
|
||||
expect(onboardingData).to.eql({
|
||||
token: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const securityDetailsUpdated =
|
||||
'{"use_case":"cloud","migration":{"value":true,"type":"other"}}';
|
||||
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=security&security=${securityDetailsUpdated}&next=${encodeURIComponent(
|
||||
'/app/security/get_started'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
const {
|
||||
body: { onboardingData: onboardingDataUpdated },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
|
||||
expect(onboardingDataUpdated).to.eql({
|
||||
token: 'security',
|
||||
security: {
|
||||
useCase: 'cloud',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'other',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it(`Redirect and keep initial onboarding token when it's not provided on update`, async () => {
|
||||
const securityDetails = '{"use_case":"siem","migration":{"value":true,"type":"splunk"}}';
|
||||
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=security&security=${securityDetails}&next=${encodeURIComponent(
|
||||
'/app/security/get_started'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
// We need to make sure that both path and hash are respected.
|
||||
const currentURL = parse(await browser.getCurrentUrl());
|
||||
expect(currentURL.pathname).to.eql('/app/security/get_started');
|
||||
expect(currentURL.hash).to.eql('#some=hash-value');
|
||||
|
||||
const {
|
||||
body: { onboardingData },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
|
||||
expect(onboardingData).to.eql({
|
||||
token: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?security=${securityDetails}&next=${encodeURIComponent(
|
||||
'/app/security/get_started'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
const {
|
||||
body: { onboardingData: onboardingDataUpdated },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
|
||||
expect(onboardingDataUpdated).to.eql({
|
||||
token: 'security',
|
||||
security: {
|
||||
useCase: 'siem',
|
||||
migration: {
|
||||
value: true,
|
||||
type: 'splunk',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,68 +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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 { parse } from 'url';
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import type { FtrProviderContext } from '../../security_functional/ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const find = getService('find');
|
||||
const browser = getService('browser');
|
||||
const deployment = getService('deployment');
|
||||
const PageObjects = getPageObjects(['common']);
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('onboarding token', function () {
|
||||
this.tags('includeFirefox');
|
||||
|
||||
before(async () => {
|
||||
await getService('esSupertest')
|
||||
.post('/_security/role_mapping/saml1')
|
||||
.send({ roles: ['superuser'], enabled: true, rules: { field: { 'realm.name': 'saml1' } } })
|
||||
.expect(200);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await browser.get(deployment.getHostPort() + '/logout');
|
||||
await PageObjects.common.waitUntilUrlIncludes('logged_out');
|
||||
});
|
||||
|
||||
it('Redirect and save token', async () => {
|
||||
await browser.get(
|
||||
deployment.getHostPort() +
|
||||
`/app/cloud/onboarding?onboarding_token=vector&next=${encodeURIComponent(
|
||||
'/app/elasticsearch/vector_search'
|
||||
)}#some=hash-value`
|
||||
);
|
||||
await find.byCssSelector('[data-test-subj="userMenuButton"]', 20000);
|
||||
|
||||
// We need to make sure that both path and hash are respected.
|
||||
const currentURL = parse(await browser.getCurrentUrl());
|
||||
expect(currentURL.pathname).to.eql('/app/elasticsearch/vector_search');
|
||||
expect(currentURL.hash).to.eql('#some=hash-value');
|
||||
|
||||
const {
|
||||
body: { onboardingData },
|
||||
} = await supertest
|
||||
.get('/internal/cloud/solution')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.set('x-elastic-internal-origin', 'cloud')
|
||||
.set('elastic-api-version', '1')
|
||||
.expect(200);
|
||||
expect(onboardingData).to.eql({ token: 'vector' });
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue