diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9a1762436e2ae..4622c3feeb31e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -599,6 +599,7 @@ src/platform/packages/shared/kbn-telemetry-config @elastic/kibana-core src/platform/packages/shared/kbn-test @elastic/kibana-operations @elastic/appex-qa src/platform/packages/shared/kbn-test-es-server @elastic/kibana-operations @elastic/appex-qa src/platform/packages/shared/kbn-test-jest-helpers @elastic/kibana-operations @elastic/appex-qa +src/platform/packages/shared/kbn-test-saml-auth @elastic/appex-qa src/platform/packages/shared/kbn-test-subj-selector @elastic/kibana-operations @elastic/appex-qa src/platform/packages/shared/kbn-timerange @elastic/obs-onboarding-team src/platform/packages/shared/kbn-tooling-log @elastic/kibana-operations diff --git a/package.json b/package.json index 61c6e3bd6a690..e78a79434ecb1 100644 --- a/package.json +++ b/package.json @@ -1687,6 +1687,7 @@ "@kbn/test-es-server": "link:src/platform/packages/shared/kbn-test-es-server", "@kbn/test-eui-helpers": "link:src/platform/packages/private/kbn-test-eui-helpers", "@kbn/test-jest-helpers": "link:src/platform/packages/shared/kbn-test-jest-helpers", + "@kbn/test-saml-auth": "link:src/platform/packages/shared/kbn-test-saml-auth", "@kbn/test-subj-selector": "link:src/platform/packages/shared/kbn-test-subj-selector", "@kbn/test-suites-security-solution-apis": "link:x-pack/solutions/security/test/security_solution_api_integration", "@kbn/test-suites-src": "link:src/platform/test", diff --git a/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts b/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts index bffd269153cc0..ad91bfb137f23 100644 --- a/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts +++ b/packages/kbn-repo-source-classifier/src/repo_source_classifier.ts @@ -165,6 +165,7 @@ export class RepoSourceClassifier { if ( pkgId === '@kbn/test' || pkgId === '@kbn/test-es-server' || + pkgId === '@kbn/test-saml-auth' || pkgId === '@kbn/test-subj-selector' ) { return 'common package'; diff --git a/src/platform/packages/shared/kbn-ftr-common-functional-services/moon.yml b/src/platform/packages/shared/kbn-ftr-common-functional-services/moon.yml index ddde3e26a60a9..907b1906b7abf 100644 --- a/src/platform/packages/shared/kbn-ftr-common-functional-services/moon.yml +++ b/src/platform/packages/shared/kbn-ftr-common-functional-services/moon.yml @@ -21,6 +21,7 @@ dependsOn: - '@kbn/tooling-log' - '@kbn/es-archiver' - '@kbn/test' + - '@kbn/test-saml-auth' - '@kbn/expect' - '@kbn/search-types' - '@kbn/core-http-common' diff --git a/src/platform/packages/shared/kbn-ftr-common-functional-services/services/saml_auth/serverless/auth_provider.ts b/src/platform/packages/shared/kbn-ftr-common-functional-services/services/saml_auth/serverless/auth_provider.ts index 1648760cd45f1..eccbc192f185d 100644 --- a/src/platform/packages/shared/kbn-ftr-common-functional-services/services/saml_auth/serverless/auth_provider.ts +++ b/src/platform/packages/shared/kbn-ftr-common-functional-services/services/saml_auth/serverless/auth_provider.ts @@ -13,7 +13,7 @@ import { SERVERLESS_ROLES_ROOT_PATH } from '@kbn/es'; import { type Config } from '@kbn/test'; import { isServerlessProjectType, readRolesDescriptorsFromResource } from '@kbn/es/src/utils'; import { resolve } from 'path'; -import type { Role } from '@kbn/test/src/auth/types'; +import type { Role } from '@kbn/test-saml-auth'; import { getServerlessInternalRequestHeaders, COMMON_REQUEST_HEADERS, diff --git a/src/platform/packages/shared/kbn-ftr-common-functional-services/tsconfig.json b/src/platform/packages/shared/kbn-ftr-common-functional-services/tsconfig.json index b2728ac8245e1..ebea3deaf0c1d 100644 --- a/src/platform/packages/shared/kbn-ftr-common-functional-services/tsconfig.json +++ b/src/platform/packages/shared/kbn-ftr-common-functional-services/tsconfig.json @@ -16,6 +16,7 @@ "@kbn/tooling-log", "@kbn/es-archiver", "@kbn/test", + "@kbn/test-saml-auth", "@kbn/expect", "@kbn/search-types", "@kbn/core-http-common", diff --git a/src/platform/packages/shared/kbn-scout/moon.yml b/src/platform/packages/shared/kbn-scout/moon.yml index 3a6fc8ea85f3e..a0ddc0854fb62 100644 --- a/src/platform/packages/shared/kbn-scout/moon.yml +++ b/src/platform/packages/shared/kbn-scout/moon.yml @@ -28,6 +28,7 @@ dependsOn: - '@kbn/kbn-client' - '@kbn/test-es-server' - '@kbn/test' + - '@kbn/test-saml-auth' - '@kbn/es-archiver' - '@kbn/dev-utils' - '@kbn/mock-idp-utils' diff --git a/src/platform/packages/shared/kbn-scout/src/common/constants.ts b/src/platform/packages/shared/kbn-scout/src/common/constants.ts index 92f394a655309..bf9085888a53b 100644 --- a/src/platform/packages/shared/kbn-scout/src/common/constants.ts +++ b/src/platform/packages/shared/kbn-scout/src/common/constants.ts @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import type { Role } from '@kbn/test/src/auth/types'; +import type { Role } from '@kbn/test-saml-auth'; export const PROJECT_DEFAULT_ROLES = new Map([ ['es', 'developer'], diff --git a/src/platform/packages/shared/kbn-scout/src/common/services/index.ts b/src/platform/packages/shared/kbn-scout/src/common/services/index.ts index f46743eb17d1d..5cf8c409a1f4f 100644 --- a/src/platform/packages/shared/kbn-scout/src/common/services/index.ts +++ b/src/platform/packages/shared/kbn-scout/src/common/services/index.ts @@ -14,7 +14,7 @@ export { createKbnUrl } from './kibana_url'; export { createSamlSessionManager } from './saml_auth'; export type { KibanaUrl } from './kibana_url'; -export type { SamlSessionManager } from '@kbn/test'; +export type { SamlSessionManager } from '@kbn/test-saml-auth'; export { ScoutLogger } from './logger'; export type { KbnClient } from '@kbn/kbn-client'; export type { Client as EsClient } from '@elastic/elasticsearch'; diff --git a/src/platform/packages/shared/kbn-scout/src/common/services/roles.ts b/src/platform/packages/shared/kbn-scout/src/common/services/roles.ts index 2aba012b7d315..1eb32c2c199ad 100644 --- a/src/platform/packages/shared/kbn-scout/src/common/services/roles.ts +++ b/src/platform/packages/shared/kbn-scout/src/common/services/roles.ts @@ -8,7 +8,7 @@ */ import type { ServerlessProjectType } from '@kbn/es'; -import type { Role } from '@kbn/test/src/auth/types'; +import type { Role } from '@kbn/test-saml-auth'; import { PROJECT_DEFAULT_ROLES } from '../constants'; /** diff --git a/src/platform/packages/shared/kbn-scout/src/common/services/saml_auth.ts b/src/platform/packages/shared/kbn-scout/src/common/services/saml_auth.ts index 208b35a44e250..3340fcdfb7e6d 100644 --- a/src/platform/packages/shared/kbn-scout/src/common/services/saml_auth.ts +++ b/src/platform/packages/shared/kbn-scout/src/common/services/saml_auth.ts @@ -15,8 +15,8 @@ import { readRolesDescriptorsFromResource, } from '@kbn/es'; import { REPO_ROOT } from '@kbn/repo-info'; -import type { HostOptions } from '@kbn/test'; -import { SamlSessionManager } from '@kbn/test'; +import type { HostOptions } from '@kbn/test-saml-auth'; +import { SamlSessionManager } from '@kbn/test-saml-auth'; import type { ScoutTestConfig } from '../../types'; import type { Protocol } from '../../playwright/types'; import type { ScoutLogger } from './logger'; diff --git a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/core_fixtures.ts b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/core_fixtures.ts index f1d9a85562f7f..db3a1b1f6eda0 100644 --- a/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/core_fixtures.ts +++ b/src/platform/packages/shared/kbn-scout/src/playwright/fixtures/scope/worker/core_fixtures.ts @@ -9,7 +9,7 @@ import { test as base } from '@playwright/test'; import type { KbnClient } from '@kbn/kbn-client'; -import type { SamlSessionManager } from '@kbn/test'; +import type { SamlSessionManager } from '@kbn/test-saml-auth'; import type { Client } from '@elastic/elasticsearch'; import type { KibanaUrl, @@ -32,7 +32,7 @@ import type { ScoutTestConfig } from '.'; // re-export to import types from '@kbn-scout' export type { KbnClient } from '@kbn/kbn-client'; -export type { SamlSessionManager } from '@kbn/test'; +export type { SamlSessionManager } from '@kbn/test-saml-auth'; export type { Client as EsClient } from '@elastic/elasticsearch'; export type { KibanaUrl } from '../../../../common/services/kibana_url'; export type { ScoutTestConfig } from '../../../../types'; diff --git a/src/platform/packages/shared/kbn-scout/tsconfig.json b/src/platform/packages/shared/kbn-scout/tsconfig.json index f5a1a7d28b800..7abf5ae8ff35e 100644 --- a/src/platform/packages/shared/kbn-scout/tsconfig.json +++ b/src/platform/packages/shared/kbn-scout/tsconfig.json @@ -18,6 +18,7 @@ "@kbn/kbn-client", "@kbn/test-es-server", "@kbn/test", + "@kbn/test-saml-auth", "@kbn/es-archiver", "@kbn/dev-utils", "@kbn/mock-idp-utils", diff --git a/src/platform/packages/shared/kbn-test/src/auth/index.ts b/src/platform/packages/shared/kbn-test-saml-auth/index.ts similarity index 88% rename from src/platform/packages/shared/kbn-test/src/auth/index.ts rename to src/platform/packages/shared/kbn-test-saml-auth/index.ts index b16ddc6951944..8bc70f74c2112 100644 --- a/src/platform/packages/shared/kbn-test/src/auth/index.ts +++ b/src/platform/packages/shared/kbn-test-saml-auth/index.ts @@ -12,4 +12,6 @@ export { type GetCookieOptions, type HostOptions, type SamlSessionManagerOptions, -} from './session_manager'; +} from './src/session_manager'; + +export type { Role } from './src/types'; diff --git a/src/platform/packages/shared/kbn-test-saml-auth/jest.config.js b/src/platform/packages/shared/kbn-test-saml-auth/jest.config.js new file mode 100644 index 0000000000000..62c5c0d313021 --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/jest.config.js @@ -0,0 +1,14 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/src/platform/packages/shared/kbn-test-saml-auth'], +}; diff --git a/src/platform/packages/shared/kbn-test-saml-auth/kibana.jsonc b/src/platform/packages/shared/kbn-test-saml-auth/kibana.jsonc new file mode 100644 index 0000000000000..70a7a8b4c61e7 --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/kibana.jsonc @@ -0,0 +1,11 @@ +{ + "type": "shared-common", + "id": "@kbn/test-saml-auth", + "owner": [ + "@elastic/kibana-operations", + "@elastic/appex-qa" + ], + "group": "platform", + "visibility": "shared", + "devOnly": true +} diff --git a/src/platform/packages/shared/kbn-test-saml-auth/moon.yml b/src/platform/packages/shared/kbn-test-saml-auth/moon.yml new file mode 100644 index 0000000000000..2f57e0bdef37c --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/moon.yml @@ -0,0 +1,58 @@ +# This file is generated by the @kbn/moon package. Any manual edits will be erased! +# To extend this, write your extensions/overrides to 'moon.extend.yml' +# then regenerate this file with: 'node scripts/regenerate_moon_projects.js --update --filter @kbn/test-saml-auth' + +$schema: https://moonrepo.dev/schemas/project.json +id: '@kbn/test-saml-auth' +layer: unknown +owners: + defaultOwner: '@elastic/kibana-operations' +toolchains: + default: node +language: typescript +project: + title: '@kbn/test-saml-auth' + description: Moon project for @kbn/test-saml-auth + channel: '' + owner: '@elastic/kibana-operations' + sourceRoot: src/platform/packages/shared/kbn-test-saml-auth +dependsOn: + - '@kbn/es' + - '@kbn/mock-idp-utils' + - '@kbn/tooling-log' + - '@kbn/repo-info' +tags: + - shared-common + - package + - dev + - group-platform + - shared + - jest-unit-tests +fileGroups: + src: + - '**/*.ts' + - '**/*.js' + - '!target/**/*' +tasks: + jest: + command: node + args: + - '--no-experimental-require-module' + - $workspaceRoot/scripts/jest + - '--config' + - $projectRoot/jest.config.js + options: + runFromWorkspaceRoot: true + inputs: + - '@group(src)' + jestCI: + command: node + args: + - '--no-experimental-require-module' + - $workspaceRoot/scripts/jest + - '--config' + - $projectRoot/jest.config.js + options: + runFromWorkspaceRoot: true + inputs: + - '@group(src)' diff --git a/src/platform/packages/shared/kbn-test-saml-auth/package.json b/src/platform/packages/shared/kbn-test-saml-auth/package.json new file mode 100644 index 0000000000000..15e1ed1b827f1 --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/test-saml-auth", + "author": "Operations", + "version": "1.0.0", + "private": true, + "license": "Elastic License 2.0 OR AGPL-3.0-only OR SSPL-1.0" +} diff --git a/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.test.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.test.ts new file mode 100644 index 0000000000000..8a6775d9a72bf --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.test.ts @@ -0,0 +1,71 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import axios from 'axios'; +import { ToolingLog } from '@kbn/tooling-log'; +import { fetchKibanaVersionHeaderString } from './fetch_kibana_version'; + +jest.mock('axios'); +const mockedAxios = axios as jest.Mocked; + +describe('fetchKibanaVersionHeaderString', () => { + const log = new ToolingLog(); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + test('returns version.number and appends -SNAPSHOT when build_snapshot is true', async () => { + mockedAxios.request.mockResolvedValue({ + data: { + version: { number: '9.0.0', build_snapshot: true }, + }, + }); + + const v = await fetchKibanaVersionHeaderString( + 'https://localhost:5601', + 'elastic', + 'changeme', + log + ); + + expect(v).toBe('9.0.0-SNAPSHOT'); + expect(mockedAxios.request).toHaveBeenCalledTimes(1); + expect(mockedAxios.request).toHaveBeenCalledWith( + expect.objectContaining({ + method: 'GET', + auth: { username: 'elastic', password: 'changeme' }, + validateStatus: expect.any(Function), + }) + ); + const callUrl = mockedAxios.request.mock.calls[0][0].url as string; + expect(callUrl).toContain('/api/status'); + expect(callUrl).toContain('v8format=true'); + }); + + test('throws when version is missing from response body', async () => { + mockedAxios.request.mockResolvedValue({ data: {} }); + + await expect( + fetchKibanaVersionHeaderString('http://localhost:5601', 'u', 'p', log) + ).rejects.toThrow(/Unable to get version from Kibana/); + + expect(mockedAxios.request).toHaveBeenCalledTimes(1); + }); + + test('propagates axios errors after a single attempt', async () => { + mockedAxios.request.mockRejectedValue(new Error('network down')); + + await expect( + fetchKibanaVersionHeaderString('http://localhost:5601', 'u', 'p', log) + ).rejects.toThrow('network down'); + + expect(mockedAxios.request).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.ts new file mode 100644 index 0000000000000..8898826da419a --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/src/fetch_kibana_version.ts @@ -0,0 +1,64 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import https from 'https'; +import axios from 'axios'; +import type { ToolingLog } from '@kbn/tooling-log'; + +interface KibanaStatusResponse { + version?: { + number: string; + build_snapshot: boolean; + }; +} + +/** + * Fetches Kibana version string in the same shape as @kbn/kbn-client KbnClientVersion.get() + * (for use as the `kbn-version` header on SAML requests). Single GET to `/api/status`; no retries. + */ +export async function fetchKibanaVersionHeaderString( + kbnBaseUrl: string, + username: string, + password: string, + log: ToolingLog +): Promise { + const base = kbnBaseUrl.endsWith('/') ? kbnBaseUrl : `${kbnBaseUrl}/`; + const url = new URL('api/status', base); + url.searchParams.set('v8format', 'true'); + + const isHttps = url.protocol === 'https:'; + const httpsAgent = isHttps + ? new https.Agent({ + rejectUnauthorized: false, + }) + : undefined; + + log.debug(`Fetching Kibana version from ${url.origin}/api/status`); + + const response = await axios.request({ + method: 'GET', + url: url.toString(), + auth: { username, password }, + headers: { + 'kbn-xsrf': 'kbn-client', + 'x-elastic-internal-origin': 'kbn-client', + }, + httpsAgent, + validateStatus: (status: number) => status === 200 || status === 503, + }); + + const data = response.data; + if (!data?.version) { + throw new Error( + `Unable to get version from Kibana, invalid response from server: ${JSON.stringify(data)}` + ); + } + + return data.version.number + (data.version.build_snapshot ? '-SNAPSHOT' : ''); +} diff --git a/src/platform/packages/shared/kbn-test/src/auth/helper.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/helper.ts similarity index 100% rename from src/platform/packages/shared/kbn-test/src/auth/helper.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/helper.ts diff --git a/src/platform/packages/shared/kbn-test/src/auth/saml_auth.test.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/saml_auth.test.ts similarity index 100% rename from src/platform/packages/shared/kbn-test/src/auth/saml_auth.test.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/saml_auth.test.ts diff --git a/src/platform/packages/shared/kbn-test/src/auth/saml_auth.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/saml_auth.ts similarity index 100% rename from src/platform/packages/shared/kbn-test/src/auth/saml_auth.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/saml_auth.ts diff --git a/src/platform/packages/shared/kbn-test/src/auth/session_manager.test.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.test.ts similarity index 96% rename from src/platform/packages/shared/kbn-test/src/auth/session_manager.test.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.test.ts index 5ca6634b5f4ea..4c9d5f902dea5 100644 --- a/src/platform/packages/shared/kbn-test/src/auth/session_manager.test.ts +++ b/src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.test.ts @@ -10,9 +10,18 @@ import { ToolingLog } from '@kbn/tooling-log'; import crypto from 'crypto'; import { Cookie } from 'tough-cookie'; +import { fetchKibanaVersionHeaderString } from './fetch_kibana_version'; import { Session } from './saml_auth'; import type { SupportedRoles } from './session_manager'; import { SamlSessionManager } from './session_manager'; + +jest.mock('./fetch_kibana_version', () => ({ + fetchKibanaVersionHeaderString: jest.fn(), +})); + +const mockedFetchKibanaVersionHeaderString = fetchKibanaVersionHeaderString as jest.MockedFunction< + typeof fetchKibanaVersionHeaderString +>; import * as samlAuth from './saml_auth'; import * as helper from './helper'; import type { Role, User, UserProfile } from './types'; @@ -36,13 +45,6 @@ const readCloudUsersFromFileMock = jest.spyOn(helper, 'readCloudUsersFromFile'); const getTestToken = () => 'kbn_cookie_' + crypto.randomBytes(16).toString('hex'); -jest.mock('@kbn/kbn-client', () => { - return { - KbnClient: jest.fn(), - }; -}); -const get = jest.fn(); - describe('SamlSessionManager', () => { let createCloudSAMLSessionMock: jest.SpyInstance; beforeEach(() => { @@ -52,10 +54,6 @@ describe('SamlSessionManager', () => { describe('for local session', () => { beforeEach(() => { jest.resetAllMocks(); - jest - .requireMock('@kbn/kbn-client') - .KbnClient.mockImplementation(() => ({ version: { get } })); - get.mockImplementation(() => Promise.resolve('8.12.0')); createLocalSAMLSessionMock.mockResolvedValue(new Session(cookieInstance, testEmail)); }); @@ -236,10 +234,6 @@ describe('SamlSessionManager', () => { describe('handles errors', () => { beforeEach(() => { jest.resetAllMocks(); - jest - .requireMock('@kbn/kbn-client') - .KbnClient.mockImplementation(() => ({ version: { get } })); - get.mockImplementationOnce(() => Promise.resolve('8.12.0')); readCloudUsersFromFileMock.mockReturnValue(cloudUsers); delete process.env.TEST_CLOUD_HOST_NAME; // Ensure variable is unset @@ -262,11 +256,8 @@ describe('SamlSessionManager', () => { beforeEach(() => { jest.resetAllMocks(); - jest - .requireMock('@kbn/kbn-client') - .KbnClient.mockImplementation(() => ({ version: { get } })); - get.mockImplementationOnce(() => Promise.resolve('8.12.0')); + mockedFetchKibanaVersionHeaderString.mockResolvedValue('8.12.0'); createCloudSAMLSessionMock.mockResolvedValue(new Session(cloudCookieInstance, cloudEmail)); readCloudUsersFromFileMock.mockReturnValue(cloudUsers); delete process.env.TEST_CLOUD_HOST_NAME; diff --git a/src/platform/packages/shared/kbn-test/src/auth/session_manager.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.ts similarity index 91% rename from src/platform/packages/shared/kbn-test/src/auth/session_manager.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.ts index b916a0b6c2f4c..cbb24efc44b02 100644 --- a/src/platform/packages/shared/kbn-test/src/auth/session_manager.ts +++ b/src/platform/packages/shared/kbn-test-saml-auth/src/session_manager.ts @@ -9,7 +9,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import Url from 'url'; -import { KbnClient } from '@kbn/kbn-client'; +import { fetchKibanaVersionHeaderString } from './fetch_kibana_version'; import { isValidHostname, readCloudUsersFromFile } from './helper'; import type { Session } from './saml_auth'; import { createCloudSAMLSession, createLocalSAMLSession, getSecurityProfile } from './saml_auth'; @@ -48,7 +48,9 @@ export interface GetCookieOptions { export class SamlSessionManager { private readonly isCloud: boolean; private readonly kbnHost: string; - private readonly kbnClient: KbnClient; + private readonly kbnUsername: string; + private readonly kbnPassword: string; + private kbnVersionResolved?: string; private readonly log: ToolingLog; private readonly roleToUserMap: Map; private readonly sessionCache: Map; @@ -64,18 +66,13 @@ export class SamlSessionManager { port: options.hostOptions.port, }; this.kbnHost = Url.format(hostOptionsWithoutAuth); + this.kbnUsername = options.hostOptions.username; + this.kbnPassword = options.hostOptions.password; this.isCloud = options.isCloud; this.cloudHostName = options.cloudHostName || process.env.TEST_CLOUD_HOST_NAME; if (this.isCloud) { this.validateCloudHostName(); } - this.kbnClient = new KbnClient({ - log: this.log, - url: Url.format({ - ...hostOptionsWithoutAuth, - auth: `${options.hostOptions.username}:${options.hostOptions.password}`, - }), - }); this.cloudUsersFilePath = options.cloudUsersFilePath; this.sessionCache = new Map(); this.roleToUserMap = new Map(); @@ -83,6 +80,20 @@ export class SamlSessionManager { this.validateCloudSetting(); } + private async getKibanaVersionForCloudSaml(): Promise { + if (this.kbnVersionResolved !== undefined) { + return this.kbnVersionResolved; + } + const version = await fetchKibanaVersionHeaderString( + this.kbnHost, + this.kbnUsername, + this.kbnPassword, + this.log + ); + this.kbnVersionResolved = version; + return version; + } + private validateCloudHostName() { if (!this.cloudHostName) { throw new Error( @@ -162,7 +173,7 @@ Set env variable 'TEST_CLOUD=1' to run FTR against your Cloud deployment` if (this.isCloud) { this.log.debug(`Creating new cloud SAML session for role '${role}'`); - const kbnVersion = await this.kbnClient.version.get(); + const kbnVersion = await this.getKibanaVersionForCloudSaml(); const { email, password } = this.getCloudUserByRole(role); session = await createCloudSAMLSession({ hostname: this.cloudHostName!, diff --git a/src/platform/packages/shared/kbn-test/src/auth/types.ts b/src/platform/packages/shared/kbn-test-saml-auth/src/types.ts similarity index 100% rename from src/platform/packages/shared/kbn-test/src/auth/types.ts rename to src/platform/packages/shared/kbn-test-saml-auth/src/types.ts diff --git a/src/platform/packages/shared/kbn-test-saml-auth/tsconfig.json b/src/platform/packages/shared/kbn-test-saml-auth/tsconfig.json new file mode 100644 index 0000000000000..d1bf1171fbff2 --- /dev/null +++ b/src/platform/packages/shared/kbn-test-saml-auth/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "@kbn/tsconfig-base/tsconfig.json", + "compilerOptions": { + "outDir": "target/types", + "stripInternal": true, + "types": ["jest", "node"] + }, + "include": ["**/*.ts", "**/*.js"], + "exclude": ["target/**/*"], + "kbn_references": [ + "@kbn/es", + "@kbn/mock-idp-utils", + "@kbn/tooling-log", + "@kbn/repo-info" + ] +} diff --git a/src/platform/packages/shared/kbn-test/index.ts b/src/platform/packages/shared/kbn-test/index.ts index c86ee63d4d3ad..0c044c50dfc7f 100644 --- a/src/platform/packages/shared/kbn-test/index.ts +++ b/src/platform/packages/shared/kbn-test/index.ts @@ -30,7 +30,8 @@ export { type SamlSessionManagerOptions, type HostOptions, type GetCookieOptions, -} from './src/auth'; + type Role, +} from '@kbn/test-saml-auth'; export type { CreateTestEsClusterOptions, diff --git a/src/platform/packages/shared/kbn-test/moon.yml b/src/platform/packages/shared/kbn-test/moon.yml index 55c111cb58dfa..49563cf2a263f 100644 --- a/src/platform/packages/shared/kbn-test/moon.yml +++ b/src/platform/packages/shared/kbn-test/moon.yml @@ -33,7 +33,7 @@ dependsOn: - '@kbn/stdio-dev-helpers' - '@kbn/babel-register' - '@kbn/repo-packages' - - '@kbn/mock-idp-utils' + - '@kbn/test-saml-auth' - '@kbn/code-owners' - '@kbn/scout-reporting' - '@kbn/scout-info' diff --git a/src/platform/packages/shared/kbn-test/tsconfig.json b/src/platform/packages/shared/kbn-test/tsconfig.json index 1c99a1fd7c6a0..545aace25b4a9 100644 --- a/src/platform/packages/shared/kbn-test/tsconfig.json +++ b/src/platform/packages/shared/kbn-test/tsconfig.json @@ -24,7 +24,7 @@ "@kbn/stdio-dev-helpers", "@kbn/babel-register", "@kbn/repo-packages", - "@kbn/mock-idp-utils", + "@kbn/test-saml-auth", "@kbn/code-owners", "@kbn/scout-reporting", "@kbn/scout-info", diff --git a/tsconfig.base.json b/tsconfig.base.json index adc7a844c9895..3e484598df27a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -2192,6 +2192,8 @@ "@kbn/test-feature-usage-plugin/*": ["x-pack/platform/test/licensing_plugin/plugins/test_feature_usage/*"], "@kbn/test-jest-helpers": ["src/platform/packages/shared/kbn-test-jest-helpers"], "@kbn/test-jest-helpers/*": ["src/platform/packages/shared/kbn-test-jest-helpers/*"], + "@kbn/test-saml-auth": ["src/platform/packages/shared/kbn-test-saml-auth"], + "@kbn/test-saml-auth/*": ["src/platform/packages/shared/kbn-test-saml-auth/*"], "@kbn/test-subj-selector": ["src/platform/packages/shared/kbn-test-subj-selector"], "@kbn/test-subj-selector/*": ["src/platform/packages/shared/kbn-test-subj-selector/*"], "@kbn/test-suites-security-solution-apis": ["x-pack/solutions/security/test/security_solution_api_integration"], diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/support/saml_auth.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/support/saml_auth.ts index 307260eefc2e1..7784d5d3b78b0 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/support/saml_auth.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/support/saml_auth.ts @@ -10,8 +10,8 @@ import type { Role } from '@kbn/security-plugin-types-common'; import { ToolingLog } from '@kbn/tooling-log'; import type { SecurityRoleName } from '@kbn/security-solution-plugin/common/test'; -import type { HostOptions } from '@kbn/test'; -import { SamlSessionManager } from '@kbn/test'; +import type { HostOptions } from '@kbn/test-saml-auth'; +import { SamlSessionManager } from '@kbn/test-saml-auth'; import { REPO_ROOT } from '@kbn/repo-info'; import { resolve } from 'path'; import axios from 'axios'; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tsconfig.json b/x-pack/solutions/security/test/security_solution_cypress/cypress/tsconfig.json index acff7b847e65d..c28a224057b02 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tsconfig.json +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tsconfig.json @@ -38,6 +38,7 @@ "@kbn/elastic-assistant-common", "@kbn/cloud-security-posture-common", "@kbn/security-plugin-types-common", - "@kbn/securitysolution-utils" + "@kbn/securitysolution-utils", + "@kbn/test-saml-auth" ] } diff --git a/yarn.lock b/yarn.lock index f8b3af92bbdaa..aaccb737fc2e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8498,6 +8498,10 @@ version "0.0.0" uid "" +"@kbn/test-saml-auth@link:src/platform/packages/shared/kbn-test-saml-auth": + version "0.0.0" + uid "" + "@kbn/test-subj-selector@link:src/platform/packages/shared/kbn-test-subj-selector": version "0.0.0" uid ""