From 92686f3452380fe2c6d4ede76b98fb01eb4ca0ff Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 09:08:24 +0000 Subject: [PATCH 01/32] Add Mock IDP login page and role switcher --- .../core-http-resources-server/src/types.ts | 7 +- packages/kbn-es/src/utils/docker.ts | 4 +- .../kbn-mock-idp-plugin/common/constants.ts | 23 ++- packages/kbn-mock-idp-plugin/common/index.ts | 8 +- packages/kbn-mock-idp-plugin/common/utils.ts | 6 +- packages/kbn-mock-idp-plugin/kibana.jsonc | 6 +- packages/kbn-mock-idp-plugin/public/index.ts | 9 ++ .../kbn-mock-idp-plugin/public/login_page.tsx | 137 ++++++++++++++++ .../kbn-mock-idp-plugin/public/plugin.tsx | 70 ++++++++ .../public/reload_page_toast.tsx | 55 +++++++ .../public/role_switcher.tsx | 150 ++++++++++++++++++ packages/kbn-mock-idp-plugin/server/index.ts | 1 + packages/kbn-mock-idp-plugin/server/plugin.ts | 111 ++++--------- 13 files changed, 496 insertions(+), 91 deletions(-) create mode 100644 packages/kbn-mock-idp-plugin/public/index.ts create mode 100644 packages/kbn-mock-idp-plugin/public/login_page.tsx create mode 100644 packages/kbn-mock-idp-plugin/public/plugin.tsx create mode 100644 packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx create mode 100644 packages/kbn-mock-idp-plugin/public/role_switcher.tsx diff --git a/packages/core/http/core-http-resources-server/src/types.ts b/packages/core/http/core-http-resources-server/src/types.ts index b7b9b4387da0c..f0c1a81ed3d4d 100644 --- a/packages/core/http/core-http-resources-server/src/types.ts +++ b/packages/core/http/core-http-resources-server/src/types.ts @@ -47,7 +47,12 @@ export type HttpResourcesResponseOptions = HttpResponseOptions; export interface HttpResourcesServiceToolkit { /** To respond with HTML page bootstrapping Kibana application. */ renderCoreApp: (options?: HttpResourcesRenderOptions) => Promise; - /** To respond with HTML page bootstrapping Kibana application without retrieving user-specific information. */ + /** + * To respond with HTML page bootstrapping Kibana application without retrieving user-specific information. + * **Note:** + * - Your client-side JavaScript bundle will only be loaded on an anonymous page if `plugin.enabledOnAnonymousPages` is enabled in your plugin's `kibana.jsonc` manifest file. + * - You will also need to register the route serving your anonymous app with the `coreSetup.http.anonymousPaths` service in your plugin's client-side `setup` method. + * */ renderAnonymousCoreApp: (options?: HttpResourcesRenderOptions) => Promise; /** To respond with a custom HTML page. */ renderHtml: (options: HttpResourcesResponseOptions) => IKibanaResponse; diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index 73e5e1fc77288..31c00beb7a71f 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -508,11 +508,11 @@ export function resolveEsArgs( ); esArgs.set( `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.name`, - MOCK_IDP_ATTRIBUTE_EMAIL + MOCK_IDP_ATTRIBUTE_NAME ); esArgs.set( `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.mail`, - MOCK_IDP_ATTRIBUTE_NAME + MOCK_IDP_ATTRIBUTE_EMAIL ); } diff --git a/packages/kbn-mock-idp-plugin/common/constants.ts b/packages/kbn-mock-idp-plugin/common/constants.ts index 6fb5475587574..b6dd15c43795b 100644 --- a/packages/kbn-mock-idp-plugin/common/constants.ts +++ b/packages/kbn-mock-idp-plugin/common/constants.ts @@ -6,15 +6,11 @@ * Side Public License, v 1. */ -import { resolve } from 'path'; - -export const MOCK_IDP_PLUGIN_PATH = resolve(__dirname, '..'); -export const MOCK_IDP_METADATA_PATH = resolve(MOCK_IDP_PLUGIN_PATH, 'metadata.xml'); - export const MOCK_IDP_LOGIN_PATH = '/mock_idp/login'; export const MOCK_IDP_LOGOUT_PATH = '/mock_idp/logout'; export const MOCK_IDP_REALM_NAME = 'mock-idp'; +export const MOCK_IDP_REALM_TYPE = 'saml'; export const MOCK_IDP_ENTITY_ID = 'urn:mock-idp'; // Must match `entityID` in `metadata.xml` export const MOCK_IDP_ROLE_MAPPING_NAME = 'mock-idp-mapping'; @@ -22,3 +18,20 @@ export const MOCK_IDP_ATTRIBUTE_PRINCIPAL = 'http://saml.elastic-cloud.com/attri export const MOCK_IDP_ATTRIBUTE_ROLES = 'http://saml.elastic-cloud.com/attributes/roles'; export const MOCK_IDP_ATTRIBUTE_EMAIL = 'http://saml.elastic-cloud.com/attributes/email'; export const MOCK_IDP_ATTRIBUTE_NAME = 'http://saml.elastic-cloud.com/attributes/name'; + +/** List of roles from `packages/kbn-es/src/serverless_resources/roles.yml` */ +export const MOCK_IDP_ROLE_NAMES = [ + 'viewer', + 'editor', + 't1_analyst', + 't2_analyst', + 't3_analyst', + 'threat_intelligence_analyst', + 'rule_author', + 'soc_manager', + 'detections_admin', + 'platform_engineer', + 'endpoint_operations_analyst', + 'endpoint_policy_manager', + 'system_indices_superuser', +]; diff --git a/packages/kbn-mock-idp-plugin/common/index.ts b/packages/kbn-mock-idp-plugin/common/index.ts index aaaffc15f10f8..4e257b3c70b6c 100644 --- a/packages/kbn-mock-idp-plugin/common/index.ts +++ b/packages/kbn-mock-idp-plugin/common/index.ts @@ -5,20 +5,24 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ +import { resolve } from 'path'; + +export const MOCK_IDP_PLUGIN_PATH = resolve(__dirname, '..'); export { - MOCK_IDP_PLUGIN_PATH, - MOCK_IDP_METADATA_PATH, MOCK_IDP_LOGIN_PATH, MOCK_IDP_LOGOUT_PATH, MOCK_IDP_REALM_NAME, + MOCK_IDP_REALM_TYPE, MOCK_IDP_ENTITY_ID, MOCK_IDP_ROLE_MAPPING_NAME, MOCK_IDP_ATTRIBUTE_PRINCIPAL, MOCK_IDP_ATTRIBUTE_ROLES, MOCK_IDP_ATTRIBUTE_EMAIL, MOCK_IDP_ATTRIBUTE_NAME, + MOCK_IDP_ROLE_NAMES, } from './constants'; + export { createMockIdpMetadata, createSAMLResponse, diff --git a/packages/kbn-mock-idp-plugin/common/utils.ts b/packages/kbn-mock-idp-plugin/common/utils.ts index 5d55fbc565685..8289394c1fd9b 100644 --- a/packages/kbn-mock-idp-plugin/common/utils.ts +++ b/packages/kbn-mock-idp-plugin/common/utils.ts @@ -97,7 +97,7 @@ export async function createSAMLResponse(options: { /** ID from SAML authentication request */ authnRequestId?: string; username: string; - fullname?: string; + full_name?: string; email?: string; roles: string[]; }) { @@ -139,9 +139,9 @@ export async function createSAMLResponse(options: { : '' } ${ - options.fullname + options.full_name ? ` - ${options.fullname} + ${options.full_name} ` : '' } diff --git a/packages/kbn-mock-idp-plugin/kibana.jsonc b/packages/kbn-mock-idp-plugin/kibana.jsonc index 929d7b9b990db..e486c534348a2 100644 --- a/packages/kbn-mock-idp-plugin/kibana.jsonc +++ b/packages/kbn-mock-idp-plugin/kibana.jsonc @@ -6,6 +6,10 @@ "plugin": { "id": "mockIdpPlugin", "server": true, - "browser": false + "browser": true, + "enabledOnAnonymousPages": true, + "requiredBundles": [ + "kibanaReact" + ] } } \ No newline at end of file diff --git a/packages/kbn-mock-idp-plugin/public/index.ts b/packages/kbn-mock-idp-plugin/public/index.ts new file mode 100644 index 0000000000000..db807851d4564 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/public/index.ts @@ -0,0 +1,9 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +export { plugin } from './plugin'; diff --git a/packages/kbn-mock-idp-plugin/public/login_page.tsx b/packages/kbn-mock-idp-plugin/public/login_page.tsx new file mode 100644 index 0000000000000..80e20bd776625 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/public/login_page.tsx @@ -0,0 +1,137 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import { + EuiButton, + EuiPageTemplate, + EuiEmptyPrompt, + EuiComboBox, + EuiInlineEditTitle, + EuiFormRow, + EuiSpacer, + EuiComboBoxOptionOption, + EuiButtonEmpty, +} from '@elastic/eui'; +import React, { ChangeEvent } from 'react'; +import { FormikProvider, useFormik, Field, Form } from 'formik'; + +import { useAuthenticator } from './role_switcher'; +import { MOCK_IDP_ROLE_NAMES } from '../common/constants'; + +export function LoginPage() { + const [, switchCurrentUser] = useAuthenticator(true); + const formik = useFormik({ + initialValues: { + full_name: 'Test User', + role: MOCK_IDP_ROLE_NAMES[0], + }, + async onSubmit(values) { + await switchCurrentUser({ + username: sanitizeUsername(values.full_name), + full_name: values.full_name, + email: sanitizeEmail(values.full_name), + roles: [values.role], + }); + }, + }); + + return ( + + + +
+ + ) => { + formik.setFieldValue('full_name', event.target.value); + }} + onCancel={(previousValue: string) => { + formik.setFieldValue('full_name', previousValue); + }} + isReadOnly={formik.isSubmitting} + editModeProps={{ + formRowProps: { + error: formik.errors.full_name, + }, + }} + validate={(value: string) => { + if (value.trim().length === 0) { + return 'Name cannot be empty'; + } + }} + isInvalid={!!formik.errors.full_name} + placeholder="Enter your name" + css={{ width: 350 }} + /> + + + + ({ label: role }))} + selectedOptions={ + formik.values.role ? [{ label: formik.values.role }] : undefined + } + onCreateOption={(value: string) => { + formik.setFieldValue('role', value); + }} + onChange={(selectedOptions: EuiComboBoxOptionOption[]) => { + formik.setFieldValue( + 'role', + selectedOptions.length === 0 ? '' : selectedOptions[0].label + ); + }} + validate={(value: string) => { + if (value.trim().length === 0) { + return 'Role cannot be empty'; + } + }} + isInvalid={!!formik.errors.role} + isClearable={false} + fullWidth + /> + + + } + actions={[ + + Log in + , + + More login options + , + ]} + /> + +
+
+
+ ); +} + +const sanitizeUsername = (username: string) => + username.replace(/[^a-zA-Z0-9_]/g, '_').toLowerCase(); +const sanitizeEmail = (email: string) => `${sanitizeUsername(email)}@elastic.co`; diff --git a/packages/kbn-mock-idp-plugin/public/plugin.tsx b/packages/kbn-mock-idp-plugin/public/plugin.tsx new file mode 100644 index 0000000000000..b8719d83a7894 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/public/plugin.tsx @@ -0,0 +1,70 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import type { PluginInitializer, Plugin } from '@kbn/core-plugins-browser'; +import { AppNavLinkStatus } from '@kbn/core-application-browser'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; +import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { I18nProvider } from '@kbn/i18n-react'; +import { MOCK_IDP_LOGIN_PATH } from '../common/constants'; +import { RoleSwitcher } from './role_switcher'; + +export const plugin: PluginInitializer = (): Plugin => ({ + setup(coreSetup) { + // Register Mock IDP login page + coreSetup.http.anonymousPaths.register(MOCK_IDP_LOGIN_PATH); + coreSetup.application.register({ + id: 'mock_idp', + title: 'Mock IDP', + chromeless: true, + appRoute: MOCK_IDP_LOGIN_PATH, + navLinkStatus: AppNavLinkStatus.hidden, + mount: async (params) => { + const [[coreStart], { LoginPage }] = await Promise.all([ + coreSetup.getStartServices(), + import('./login_page'), + ]); + + ReactDOM.render( + + + + + + + , + params.element + ); + + return () => ReactDOM.unmountComponentAtNode(params.element); + }, + }); + }, + start(coreStart) { + // Register role switcher dropdown menu in the top right navigation of the Kibana UI + coreStart.chrome.navControls.registerRight({ + order: 4000 + 1, // Make sure it comes after the user menu + mount: (element: HTMLElement) => { + ReactDOM.render( + + + + + + + , + element + ); + return () => ReactDOM.unmountComponentAtNode(element); + }, + }); + }, + stop() {}, +}); diff --git a/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx new file mode 100644 index 0000000000000..d045f69bee0ca --- /dev/null +++ b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx @@ -0,0 +1,55 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { i18n } from '@kbn/i18n'; +import { toMountPoint } from '@kbn/react-kibana-mount'; +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import type { ToastInput } from '@kbn/core-notifications-browser'; +import type { I18nStart } from '@kbn/core-i18n-browser'; +import type { ThemeServiceStart } from '@kbn/core-theme-browser'; +import type { AuthenticatedUser } from '@kbn/security-plugin/common'; + +export const DATA_TEST_SUBJ_PAGE_RELOAD_BUTTON = 'pageReloadButton'; + +/** + * Utility function for returning a {@link ToastInput} for displaying a prompt for reloading the page. + * @param theme The {@link ThemeServiceStart} contract. + * @param i18nStart The {@link I18nStart} contract. + * @returns A toast. + */ +export const createReloadPageToast = (options: { + user: Pick; + theme: ThemeServiceStart; + i18n: I18nStart; +}): ToastInput => { + return { + title: i18n.translate('management.settings.form.requiresPageReloadToastDescription', { + defaultMessage: `Your role has been set to '${options.user.roles.join(`', '`)}'.`, + }), + text: toMountPoint( + + + window.location.reload()} + data-test-subj={DATA_TEST_SUBJ_PAGE_RELOAD_BUTTON} + > + {i18n.translate('management.settings.form.requiresPageReloadToastButtonLabel', { + defaultMessage: 'Reload page', + })} + + + , + { i18n: options.i18n, theme: options.theme } + ), + color: 'success', + toastLifeTimeMs: 0x7fffffff, // Do not auto-hide toast since page is in an unknown state + }; +}; diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx new file mode 100644 index 0000000000000..d8b0d1ffcf496 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -0,0 +1,150 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import React, { FunctionComponent, useEffect, useState } from 'react'; +import { EuiButton, EuiPopover, EuiContextMenu } from '@elastic/eui'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { CoreStart } from '@kbn/core-lifecycle-browser'; +import useAsyncFn from 'react-use/lib/useAsyncFn'; +import type { AuthenticatedUser } from '@kbn/security-plugin/common'; +import { MOCK_IDP_REALM_NAME, MOCK_IDP_REALM_TYPE, MOCK_IDP_ROLE_NAMES } from '../common/constants'; +import { createReloadPageToast } from './reload_page_toast'; +import type { CreateSAMLResponseParams } from '../server'; + +const useCurrentUser = () => { + const { services } = useKibana(); + return useAsyncFn(() => services.http.get('/internal/security/me')); +}; + +export const useAuthenticator = (reloadPage = false) => { + const { services } = useKibana(); + + return useAsyncFn(async (params: CreateSAMLResponseParams) => { + // Create SAML Response using Mock IDP + const response = await services.http.post>('/mock_idp/saml_response', { + body: JSON.stringify(params), + }); + + // Authenticate user with SAML response + if (reloadPage) { + const form = createForm('/api/security/saml/callback', response); + form.submit(); + await new Promise(() => {}); // Never resolve + } else { + await services.http.post('/api/security/saml/callback', { + body: JSON.stringify(response), + asResponse: true, + rawResponse: true, + }); + } + + return params; + }); +}; + +export const RoleSwitcher: FunctionComponent = () => { + const [isOpen, setIsOpen] = useState(false); + const { services } = useKibana(); + const [currentUserState, getCurrentUser] = useCurrentUser(); + const [authenticateUserState, authenticateUser] = useAuthenticator(); + + useEffect(() => { + getCurrentUser(); + }, [getCurrentUser, authenticateUserState.value]); + + useEffect(() => { + if (authenticateUserState.value) { + services.notifications.toasts.add( + createReloadPageToast({ + user: authenticateUserState.value, + theme: services.theme, + i18n: services.i18n, + }) + ); + } + }, [authenticateUserState.value]); // eslint-disable-line react-hooks/exhaustive-deps + + if (!currentUserState.value || !isAuthenticatedWithMockIDP(currentUserState.value)) { + return null; + } + + const [currentRole] = currentUserState.value.roles; + + return ( + setIsOpen((toggle) => !toggle)} + isLoading={currentUserState.loading || authenticateUserState.loading} + > + {currentRole} + + } + panelPaddingSize="none" + anchorPosition="downRight" + repositionOnScroll + repositionToCrossAxis={false} + isOpen={isOpen} + closePopover={() => setIsOpen(false)} + > + ({ + name: role, + icon: currentUserState.value!.roles.includes(role) ? 'check' : 'empty', + onClick: () => { + authenticateUser({ + username: currentUserState.value!.username, + full_name: currentUserState.value!.full_name, + email: currentUserState.value!.email, + roles: [role], + }); + setIsOpen(false); + }, + })), + }, + ]} + /> + + ); +}; + +function isAuthenticatedWithMockIDP(user: AuthenticatedUser) { + return ( + user.authentication_provider.type === MOCK_IDP_REALM_TYPE && + user.authentication_provider.name === MOCK_IDP_REALM_NAME + ); +} + +const createForm = (url: string, fields: Record) => { + const form = document.createElement('form'); + form.setAttribute('method', 'post'); + form.setAttribute('action', url); + + for (const key in fields) { + if (!fields.hasOwnProperty(key)) { + continue; + } + const input = document.createElement('input'); + input.setAttribute('type', 'hidden'); + input.setAttribute('name', key); + input.setAttribute('value', fields[key]); + form.appendChild(input); + } + + return document.body.appendChild(form); +}; diff --git a/packages/kbn-mock-idp-plugin/server/index.ts b/packages/kbn-mock-idp-plugin/server/index.ts index db807851d4564..81f6713e675fe 100644 --- a/packages/kbn-mock-idp-plugin/server/index.ts +++ b/packages/kbn-mock-idp-plugin/server/index.ts @@ -6,4 +6,5 @@ * Side Public License, v 1. */ +export type { CreateSAMLResponseParams } from './plugin'; export { plugin } from './plugin'; diff --git a/packages/kbn-mock-idp-plugin/server/plugin.ts b/packages/kbn-mock-idp-plugin/server/plugin.ts index 20c115d80cf2c..dab1f1488d3ac 100644 --- a/packages/kbn-mock-idp-plugin/server/plugin.ts +++ b/packages/kbn-mock-idp-plugin/server/plugin.ts @@ -8,99 +8,56 @@ import type { PluginInitializer, Plugin } from '@kbn/core-plugins-server'; import { schema } from '@kbn/config-schema'; +import type { TypeOf } from '@kbn/config-schema'; +import { MOCK_IDP_LOGIN_PATH, MOCK_IDP_LOGOUT_PATH, createSAMLResponse } from '../common'; -import { - MOCK_IDP_LOGIN_PATH, - MOCK_IDP_LOGOUT_PATH, - createSAMLResponse, - parseSAMLAuthnRequest, -} from '../common'; +const createSAMLResponseSchema = schema.object({ + username: schema.string(), + full_name: schema.maybe(schema.nullable(schema.string())), + email: schema.maybe(schema.nullable(schema.string())), + roles: schema.arrayOf(schema.string()), +}); + +export type CreateSAMLResponseParams = TypeOf; export const plugin: PluginInitializer = async (): Promise => ({ setup(core) { + const router = core.http.createRouter(); + core.http.resources.register( { path: MOCK_IDP_LOGIN_PATH, - validate: { - query: schema.object({ - SAMLRequest: schema.string(), - }), - }, + validate: false, options: { authRequired: false }, }, async (context, request, response) => { - let samlRequest: Awaited>; - try { - samlRequest = await parseSAMLAuthnRequest(request.query.SAMLRequest); - } catch (error) { - return response.badRequest({ - body: '[request query.SAMLRequest]: value is not valid SAMLRequest.', - }); - } - - const userRoles: Array<[string, string]> = [ - ['system_indices_superuser', 'system_indices_superuser'], - ['t1_analyst', 't1_analyst'], - ['t2_analyst', 't2_analyst'], - ['t3_analyst', 't3_analyst'], - ['threat_intelligence_analyst', 'threat_intelligence_analyst'], - ['rule_author', 'rule_author'], - ['soc_manager', 'soc_manager'], - ['detections_admin', 'detections_admin'], - ['platform_engineer', 'platform_engineer'], - ['endpoint_operations_analyst', 'endpoint_operations_analyst'], - ['endpoint_policy_manager', 'endpoint_policy_manager'], - ]; - - const samlResponses = await Promise.all( - userRoles.map(([username, role]) => - createSAMLResponse({ - authnRequestId: samlRequest.ID, - kibanaUrl: samlRequest.AssertionConsumerServiceURL, - username, - roles: [role], - }) - ) - ); - - return response.renderHtml({ - body: ` - - Mock Identity Provider - - -

Mock Identity Provider

-
-

Pick a role:

-
    - ${userRoles - .map( - ([username], i) => - ` -
  • - -
  • - ` - ) - .join('')} -
- - - `, - }); + return response.renderAnonymousCoreApp(); } ); - core.http.resources.register( + router.post( { - path: `${MOCK_IDP_LOGIN_PATH}/submit.js`, - validate: false, + path: '/mock_idp/saml_response', + validate: { + body: createSAMLResponseSchema, + }, options: { authRequired: false }, }, - (context, request, response) => { - return response.renderJs({ body: 'document.getElementById("loginForm").submit();' }); + async (context, request, response) => { + const { protocol, hostname, port } = core.http.getServerInfo(); + const pathname = core.http.basePath.prepend('/api/security/saml/callback'); + + return response.ok({ + body: { + SAMLResponse: await createSAMLResponse({ + kibanaUrl: `${protocol}://${hostname}:${port}${pathname}`, + username: request.body.username, + full_name: request.body.full_name ?? undefined, + email: request.body.email ?? undefined, + roles: request.body.roles, + }), + }, + }); } ); From f1eb108f2f40d704e4198f9435c6212b7cd1e11d Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:19:49 +0000 Subject: [PATCH 02/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- packages/kbn-mock-idp-plugin/tsconfig.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json index 1420a34208f13..e9afd4a6739dd 100644 --- a/packages/kbn-mock-idp-plugin/tsconfig.json +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -13,6 +13,18 @@ "kbn_references": [ "@kbn/core-plugins-server", "@kbn/config-schema", - "@kbn/dev-utils" + "@kbn/dev-utils", + "@kbn/core-plugins-browser", + "@kbn/core-application-browser", + "@kbn/react-kibana-context-theme", + "@kbn/kibana-react-plugin", + "@kbn/i18n-react", + "@kbn/i18n", + "@kbn/react-kibana-mount", + "@kbn/core-notifications-browser", + "@kbn/core-i18n-browser", + "@kbn/core-theme-browser", + "@kbn/security-plugin", + "@kbn/core-lifecycle-browser" ] } From f0a38eb19bde6c9943817ac4ac7fa2bee90e37ce Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 16:10:44 +0000 Subject: [PATCH 03/32] Separate mock IDP package --- package.json | 1 + packages/kbn-es/src/utils/docker.test.ts | 4 +-- packages/kbn-es/src/utils/docker.ts | 2 +- packages/kbn-es/tsconfig.json | 4 +-- .../kbn-mock-idp-plugin/public/login_page.tsx | 2 +- .../kbn-mock-idp-plugin/public/plugin.tsx | 2 +- .../public/reload_page_toast.tsx | 2 +- .../public/role_switcher.tsx | 8 ++++-- packages/kbn-mock-idp-plugin/server/plugin.ts | 2 +- packages/kbn-mock-idp-plugin/tsconfig.json | 19 +++++++++++-- packages/kbn-mock-idp-utils/index.ts | 9 ++++++ packages/kbn-mock-idp-utils/kibana.jsonc | 6 ++++ packages/kbn-mock-idp-utils/package.json | 6 ++++ .../src}/constants.ts | 0 .../src}/index.ts | 10 +------ .../src}/utils.ts | 28 +------------------ packages/kbn-mock-idp-utils/tsconfig.json | 16 +++++++++++ tsconfig.base.json | 2 ++ yarn.lock | 4 +++ 19 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 packages/kbn-mock-idp-utils/index.ts create mode 100644 packages/kbn-mock-idp-utils/kibana.jsonc create mode 100644 packages/kbn-mock-idp-utils/package.json rename packages/{kbn-mock-idp-plugin/common => kbn-mock-idp-utils/src}/constants.ts (100%) rename packages/{kbn-mock-idp-plugin/common => kbn-mock-idp-utils/src}/index.ts (75%) rename packages/{kbn-mock-idp-plugin/common => kbn-mock-idp-utils/src}/utils.ts (90%) create mode 100644 packages/kbn-mock-idp-utils/tsconfig.json diff --git a/package.json b/package.json index 50e5754aaaf6c..a5bc66d825960 100644 --- a/package.json +++ b/package.json @@ -1246,6 +1246,7 @@ "@kbn/managed-vscode-config-cli": "link:packages/kbn-managed-vscode-config-cli", "@kbn/management-storybook-config": "link:packages/kbn-management/storybook/config", "@kbn/mock-idp-plugin": "link:packages/kbn-mock-idp-plugin", + "@kbn/mock-idp-utils": "link:packages/kbn-mock-idp-utils", "@kbn/openapi-bundler": "link:packages/kbn-openapi-bundler", "@kbn/openapi-generator": "link:packages/kbn-openapi-generator", "@kbn/optimizer": "link:packages/kbn-optimizer", diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index b574447a20508..f21f163580a36 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -42,7 +42,7 @@ import { } from '../paths'; import * as waitClusterUtil from './wait_until_cluster_ready'; import * as waitForSecurityIndexUtil from './wait_for_security_index'; -import * as mockIdpPluginUtil from '@kbn/mock-idp-plugin/common'; +import * as mockIdpPluginUtil from '@kbn/mock-idp-utils'; jest.mock('execa'); const execa = jest.requireMock('execa'); @@ -60,7 +60,7 @@ jest.mock('./wait_for_security_index', () => ({ waitForSecurityIndex: jest.fn(), })); -jest.mock('@kbn/mock-idp-plugin/common'); +jest.mock('@kbn/mock-idp-utils'); const log = new ToolingLog(); const logWriter = new ToolingLogCollectingWriter(); diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index 31c00beb7a71f..dbdfbac19dfe8 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -24,7 +24,7 @@ import { MOCK_IDP_ATTRIBUTE_NAME, ensureSAMLRoleMapping, createMockIdpMetadata, -} from '@kbn/mock-idp-plugin/common'; +} from '@kbn/mock-idp-utils'; import { waitForSecurityIndex } from './wait_for_security_index'; import { createCliError } from '../errors'; diff --git a/packages/kbn-es/tsconfig.json b/packages/kbn-es/tsconfig.json index b40ca33825562..34fcfb16e027a 100644 --- a/packages/kbn-es/tsconfig.json +++ b/packages/kbn-es/tsconfig.json @@ -16,8 +16,8 @@ "@kbn/dev-utils", "@kbn/dev-proc-runner", "@kbn/ci-stats-reporter", - "@kbn/mock-idp-plugin", + "@kbn/mock-idp-utils", "@kbn/jest-serializers", "@kbn/repo-info" ] -} +} \ No newline at end of file diff --git a/packages/kbn-mock-idp-plugin/public/login_page.tsx b/packages/kbn-mock-idp-plugin/public/login_page.tsx index 80e20bd776625..36bd7bbc831e7 100644 --- a/packages/kbn-mock-idp-plugin/public/login_page.tsx +++ b/packages/kbn-mock-idp-plugin/public/login_page.tsx @@ -20,8 +20,8 @@ import { import React, { ChangeEvent } from 'react'; import { FormikProvider, useFormik, Field, Form } from 'formik'; +import { MOCK_IDP_ROLE_NAMES } from '@kbn/mock-idp-utils/src/constants'; import { useAuthenticator } from './role_switcher'; -import { MOCK_IDP_ROLE_NAMES } from '../common/constants'; export function LoginPage() { const [, switchCurrentUser] = useAuthenticator(true); diff --git a/packages/kbn-mock-idp-plugin/public/plugin.tsx b/packages/kbn-mock-idp-plugin/public/plugin.tsx index b8719d83a7894..fc4e513d9895f 100644 --- a/packages/kbn-mock-idp-plugin/public/plugin.tsx +++ b/packages/kbn-mock-idp-plugin/public/plugin.tsx @@ -13,7 +13,7 @@ import ReactDOM from 'react-dom'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { I18nProvider } from '@kbn/i18n-react'; -import { MOCK_IDP_LOGIN_PATH } from '../common/constants'; +import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils/src/constants'; import { RoleSwitcher } from './role_switcher'; export const plugin: PluginInitializer = (): Plugin => ({ diff --git a/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx index d045f69bee0ca..21b76abb489fb 100644 --- a/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx +++ b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx @@ -14,7 +14,7 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import type { ToastInput } from '@kbn/core-notifications-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; -import type { AuthenticatedUser } from '@kbn/security-plugin/common'; +import type { AuthenticatedUser } from '@kbn/security-plugin-types-common'; export const DATA_TEST_SUBJ_PAGE_RELOAD_BUTTON = 'pageReloadButton'; diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx index d8b0d1ffcf496..4d7cb02f264bf 100644 --- a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -11,8 +11,12 @@ import { EuiButton, EuiPopover, EuiContextMenu } from '@elastic/eui'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { CoreStart } from '@kbn/core-lifecycle-browser'; import useAsyncFn from 'react-use/lib/useAsyncFn'; -import type { AuthenticatedUser } from '@kbn/security-plugin/common'; -import { MOCK_IDP_REALM_NAME, MOCK_IDP_REALM_TYPE, MOCK_IDP_ROLE_NAMES } from '../common/constants'; +import type { AuthenticatedUser } from '@kbn/security-plugin-types-common'; +import { + MOCK_IDP_REALM_NAME, + MOCK_IDP_REALM_TYPE, + MOCK_IDP_ROLE_NAMES, +} from '@kbn/mock-idp-utils/src/constants'; import { createReloadPageToast } from './reload_page_toast'; import type { CreateSAMLResponseParams } from '../server'; diff --git a/packages/kbn-mock-idp-plugin/server/plugin.ts b/packages/kbn-mock-idp-plugin/server/plugin.ts index dab1f1488d3ac..53f79798ed3ce 100644 --- a/packages/kbn-mock-idp-plugin/server/plugin.ts +++ b/packages/kbn-mock-idp-plugin/server/plugin.ts @@ -9,7 +9,7 @@ import type { PluginInitializer, Plugin } from '@kbn/core-plugins-server'; import { schema } from '@kbn/config-schema'; import type { TypeOf } from '@kbn/config-schema'; -import { MOCK_IDP_LOGIN_PATH, MOCK_IDP_LOGOUT_PATH, createSAMLResponse } from '../common'; +import { MOCK_IDP_LOGIN_PATH, MOCK_IDP_LOGOUT_PATH, createSAMLResponse } from '@kbn/mock-idp-utils'; const createSAMLResponseSchema = schema.object({ username: schema.string(), diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json index 1420a34208f13..a923c39bca654 100644 --- a/packages/kbn-mock-idp-plugin/tsconfig.json +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -11,8 +11,21 @@ "target/**/*" ], "kbn_references": [ - "@kbn/core-plugins-server", "@kbn/config-schema", - "@kbn/dev-utils" + "@kbn/core-application-browser", + "@kbn/core-i18n-browser", + "@kbn/core-lifecycle-browser", + "@kbn/core-notifications-browser", + "@kbn/core-plugins-browser", + "@kbn/core-plugins-server", + "@kbn/core-theme-browser", + "@kbn/dev-utils", + "@kbn/i18n-react", + "@kbn/i18n", + "@kbn/kibana-react-plugin", + "@kbn/react-kibana-context-theme", + "@kbn/react-kibana-mount", + "@kbn/security-plugin-types-common", + "@kbn/mock-idp-utils", ] -} +} \ No newline at end of file diff --git a/packages/kbn-mock-idp-utils/index.ts b/packages/kbn-mock-idp-utils/index.ts new file mode 100644 index 0000000000000..de0577ee3ed83 --- /dev/null +++ b/packages/kbn-mock-idp-utils/index.ts @@ -0,0 +1,9 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +export * from './src'; diff --git a/packages/kbn-mock-idp-utils/kibana.jsonc b/packages/kbn-mock-idp-utils/kibana.jsonc new file mode 100644 index 0000000000000..443dd39d1e6d6 --- /dev/null +++ b/packages/kbn-mock-idp-utils/kibana.jsonc @@ -0,0 +1,6 @@ +{ + "type": "shared-common", + "id": "@kbn/mock-idp-utils", + "owner": "@elastic/kibana-security", + "devOnly": true, +} \ No newline at end of file diff --git a/packages/kbn-mock-idp-utils/package.json b/packages/kbn-mock-idp-utils/package.json new file mode 100644 index 0000000000000..d0a52e2090808 --- /dev/null +++ b/packages/kbn-mock-idp-utils/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/mock-idp-utils", + "private": true, + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0" +} \ No newline at end of file diff --git a/packages/kbn-mock-idp-plugin/common/constants.ts b/packages/kbn-mock-idp-utils/src/constants.ts similarity index 100% rename from packages/kbn-mock-idp-plugin/common/constants.ts rename to packages/kbn-mock-idp-utils/src/constants.ts diff --git a/packages/kbn-mock-idp-plugin/common/index.ts b/packages/kbn-mock-idp-utils/src/index.ts similarity index 75% rename from packages/kbn-mock-idp-plugin/common/index.ts rename to packages/kbn-mock-idp-utils/src/index.ts index 4e257b3c70b6c..56f81ba1103ae 100644 --- a/packages/kbn-mock-idp-plugin/common/index.ts +++ b/packages/kbn-mock-idp-utils/src/index.ts @@ -5,9 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { resolve } from 'path'; - -export const MOCK_IDP_PLUGIN_PATH = resolve(__dirname, '..'); export { MOCK_IDP_LOGIN_PATH, @@ -23,9 +20,4 @@ export { MOCK_IDP_ROLE_NAMES, } from './constants'; -export { - createMockIdpMetadata, - createSAMLResponse, - ensureSAMLRoleMapping, - parseSAMLAuthnRequest, -} from './utils'; +export { createMockIdpMetadata, createSAMLResponse, ensureSAMLRoleMapping } from './utils'; diff --git a/packages/kbn-mock-idp-plugin/common/utils.ts b/packages/kbn-mock-idp-utils/src/utils.ts similarity index 90% rename from packages/kbn-mock-idp-plugin/common/utils.ts rename to packages/kbn-mock-idp-utils/src/utils.ts index 8289394c1fd9b..f6211f7d67ad9 100644 --- a/packages/kbn-mock-idp-plugin/common/utils.ts +++ b/packages/kbn-mock-idp-utils/src/utils.ts @@ -10,9 +10,6 @@ import { Client } from '@elastic/elasticsearch'; import { SignedXml } from 'xml-crypto'; import { KBN_KEY_PATH, KBN_CERT_PATH } from '@kbn/dev-utils'; import { readFile } from 'fs/promises'; -import zlib from 'zlib'; -import { promisify } from 'util'; -import { parseString } from 'xml2js'; import { X509Certificate } from 'crypto'; import { @@ -27,9 +24,6 @@ import { MOCK_IDP_LOGOUT_PATH, } from './constants'; -const inflateRawAsync = promisify(zlib.inflateRaw); -const parseStringAsync = promisify(parseString); - /** * Creates XML metadata for our mock identity provider. * @@ -76,7 +70,7 @@ export async function createMockIdpMetadata(kibanaUrl: string) { * const samlResponse = await createSAMLResponse({ * username: '1234567890', * email: 'mail@elastic.co', - * fullname: 'Test User', + * full_nname: 'Test User', * roles: ['t1_analyst', 'editor'], * }) * ``` @@ -87,7 +81,6 @@ export async function createMockIdpMetadata(kibanaUrl: string) { * fetch('/api/security/saml/callback', { * method: 'POST', * body: JSON.stringify({ SAMLResponse: samlResponse }), - * redirect: 'manual' * }) * ``` */ @@ -210,22 +203,3 @@ export async function ensureSAMLRoleMapping(client: Client) { }, }); } - -interface SAMLAuthnRequest { - 'saml2p:AuthnRequest': { - $: { - AssertionConsumerServiceURL: string; - Destination: string; - ID: string; - IssueInstant: string; - }; - }; -} - -export async function parseSAMLAuthnRequest(samlRequest: string) { - const inflatedSAMLRequest = (await inflateRawAsync(Buffer.from(samlRequest, 'base64'))) as Buffer; - const parsedSAMLRequest = (await parseStringAsync( - inflatedSAMLRequest.toString() - )) as SAMLAuthnRequest; - return parsedSAMLRequest['saml2p:AuthnRequest'].$; -} diff --git a/packages/kbn-mock-idp-utils/tsconfig.json b/packages/kbn-mock-idp-utils/tsconfig.json new file mode 100644 index 0000000000000..96dc88cab46ed --- /dev/null +++ b/packages/kbn-mock-idp-utils/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types" + }, + "include": [ + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/dev-utils", + ] +} \ No newline at end of file diff --git a/tsconfig.base.json b/tsconfig.base.json index 4591e22581156..d903dd80c01ac 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1078,6 +1078,8 @@ "@kbn/ml-url-state/*": ["x-pack/packages/ml/url_state/*"], "@kbn/mock-idp-plugin": ["packages/kbn-mock-idp-plugin"], "@kbn/mock-idp-plugin/*": ["packages/kbn-mock-idp-plugin/*"], + "@kbn/mock-idp-utils": ["packages/kbn-mock-idp-utils"], + "@kbn/mock-idp-utils/*": ["packages/kbn-mock-idp-utils/*"], "@kbn/monaco": ["packages/kbn-monaco"], "@kbn/monaco/*": ["packages/kbn-monaco/*"], "@kbn/monitoring-collection-plugin": ["x-pack/plugins/monitoring_collection"], diff --git a/yarn.lock b/yarn.lock index 7fd9e085b974e..cda6c36b9a46f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5093,6 +5093,10 @@ version "0.0.0" uid "" +"@kbn/mock-idp-utils@link:packages/kbn-mock-idp-utils": + version "0.0.0" + uid "" + "@kbn/monaco@link:packages/kbn-monaco": version "0.0.0" uid "" From eb345085c7fb3954cc4351fb45ef788823816833 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:19:51 +0000 Subject: [PATCH 04/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- packages/kbn-es/tsconfig.json | 2 +- packages/kbn-mock-idp-plugin/tsconfig.json | 3 +-- packages/kbn-mock-idp-utils/tsconfig.json | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/kbn-es/tsconfig.json b/packages/kbn-es/tsconfig.json index 34fcfb16e027a..fdeae934ce9ee 100644 --- a/packages/kbn-es/tsconfig.json +++ b/packages/kbn-es/tsconfig.json @@ -20,4 +20,4 @@ "@kbn/jest-serializers", "@kbn/repo-info" ] -} \ No newline at end of file +} diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json index a923c39bca654..0aa421dfaf7f1 100644 --- a/packages/kbn-mock-idp-plugin/tsconfig.json +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -19,7 +19,6 @@ "@kbn/core-plugins-browser", "@kbn/core-plugins-server", "@kbn/core-theme-browser", - "@kbn/dev-utils", "@kbn/i18n-react", "@kbn/i18n", "@kbn/kibana-react-plugin", @@ -28,4 +27,4 @@ "@kbn/security-plugin-types-common", "@kbn/mock-idp-utils", ] -} \ No newline at end of file +} diff --git a/packages/kbn-mock-idp-utils/tsconfig.json b/packages/kbn-mock-idp-utils/tsconfig.json index 96dc88cab46ed..080fe38e30b6d 100644 --- a/packages/kbn-mock-idp-utils/tsconfig.json +++ b/packages/kbn-mock-idp-utils/tsconfig.json @@ -13,4 +13,4 @@ "kbn_references": [ "@kbn/dev-utils", ] -} \ No newline at end of file +} From f1d598f41de3487c4bade706bdf6c6a89418a899 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:28:33 +0000 Subject: [PATCH 05/32] [CI] Auto-commit changed files from 'node scripts/generate codeowners' --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a366324620ab0..d5045a70fbc84 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -542,6 +542,7 @@ x-pack/packages/ml/trained_models_utils @elastic/ml-ui x-pack/packages/ml/ui_actions @elastic/ml-ui x-pack/packages/ml/url_state @elastic/ml-ui packages/kbn-mock-idp-plugin @elastic/kibana-security +packages/kbn-mock-idp-utils @elastic/kibana-security packages/kbn-monaco @elastic/appex-sharedux x-pack/plugins/monitoring_collection @elastic/obs-ux-infra_services-team x-pack/plugins/monitoring @elastic/obs-ux-infra_services-team From 2e47f43a1bc83655eb6faddbf233b101be1e9115 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 16:51:28 +0000 Subject: [PATCH 06/32] Update limits --- packages/kbn-optimizer/limits.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index e79e6b4fa8be9..d3109aaa9c5e8 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -97,6 +97,7 @@ pageLoadAssetSize: mapsEms: 26072 metricsDataAccess: 60000 ml: 82187 + mockIdpPlugin: 30000 monitoring: 80000 navigation: 37269 newsfeed: 42228 From 75755eb0c56221a5dc9147862460bf91ba658e3b Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 17:14:58 +0000 Subject: [PATCH 07/32] Remove translations --- .../kbn-mock-idp-plugin/public/reload_page_toast.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx index 21b76abb489fb..38b5e1ba86c73 100644 --- a/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx +++ b/packages/kbn-mock-idp-plugin/public/reload_page_toast.tsx @@ -8,7 +8,6 @@ import React from 'react'; -import { i18n } from '@kbn/i18n'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import type { ToastInput } from '@kbn/core-notifications-browser'; @@ -30,9 +29,7 @@ export const createReloadPageToast = (options: { i18n: I18nStart; }): ToastInput => { return { - title: i18n.translate('management.settings.form.requiresPageReloadToastDescription', { - defaultMessage: `Your role has been set to '${options.user.roles.join(`', '`)}'.`, - }), + title: `Your role has been set to '${options.user.roles.join(`', '`)}'.`, text: toMountPoint( @@ -41,9 +38,7 @@ export const createReloadPageToast = (options: { onClick={() => window.location.reload()} data-test-subj={DATA_TEST_SUBJ_PAGE_RELOAD_BUTTON} > - {i18n.translate('management.settings.form.requiresPageReloadToastButtonLabel', { - defaultMessage: 'Reload page', - })} + Reload page , From a458759da4bb9410e504618faf1e6ea7d3d3c658 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:22:35 +0000 Subject: [PATCH 08/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- packages/kbn-mock-idp-plugin/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json index 0aa421dfaf7f1..3101364ed3729 100644 --- a/packages/kbn-mock-idp-plugin/tsconfig.json +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -20,7 +20,6 @@ "@kbn/core-plugins-server", "@kbn/core-theme-browser", "@kbn/i18n-react", - "@kbn/i18n", "@kbn/kibana-react-plugin", "@kbn/react-kibana-context-theme", "@kbn/react-kibana-mount", From 0501827669d9d8c98ec2c6c9504224f1900d88e6 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 17:45:11 +0000 Subject: [PATCH 09/32] Fix plugin path --- packages/kbn-mock-idp-plugin/common/index.ts | 9 +++++++++ src/cli/serve/serve.js | 8 +++----- 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 packages/kbn-mock-idp-plugin/common/index.ts diff --git a/packages/kbn-mock-idp-plugin/common/index.ts b/packages/kbn-mock-idp-plugin/common/index.ts new file mode 100644 index 0000000000000..3143e81ce6899 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/common/index.ts @@ -0,0 +1,9 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +export * from '@kbn/mock-idp-utils'; diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 75a18378f56b3..36d5d1df41ce0 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -113,10 +113,8 @@ export function applyConfigOverrides(rawConfig, opts, extraCliOptions) { // Load mock identity provider plugin and configure realm if supported (ES only supports SAML when run with SSL) if (opts.ssl && canRequire('@kbn/mock-idp-plugin/common')) { // Ensure the plugin is loaded in dynamically to exclude from production build - const { - MOCK_IDP_PLUGIN_PATH, - MOCK_IDP_REALM_NAME, - } = require('@kbn/mock-idp-plugin/common'); + const { MOCK_IDP_REALM_NAME } = require('@kbn/mock-idp-plugin/common'); + const pluginPath = resolve(require.resolve('@kbn/mock-idp-plugin/common'), '..'); if (has('server.basePath')) { console.log( @@ -125,7 +123,7 @@ export function applyConfigOverrides(rawConfig, opts, extraCliOptions) { _.unset(rawConfig, 'server.basePath'); } - set('plugins.paths', _.compact([].concat(get('plugins.paths'), MOCK_IDP_PLUGIN_PATH))); + set('plugins.paths', _.compact([].concat(get('plugins.paths'), pluginPath))); set(`xpack.security.authc.providers.saml.${MOCK_IDP_REALM_NAME}`, { order: Number.MAX_SAFE_INTEGER, realm: MOCK_IDP_REALM_NAME, From f2c74a1116c3c003189a884dc995424686e7e7b7 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 18:57:05 +0000 Subject: [PATCH 10/32] Fix snapshot test --- packages/kbn-es/src/utils/docker.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index f21f163580a36..a467c24478965 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -462,9 +462,9 @@ describe('resolveEsArgs()', () => { "--env", "xpack.security.authc.realms.saml.mock-idp.attributes.groups=http://saml.elastic-cloud.com/attributes/roles", "--env", - "xpack.security.authc.realms.saml.mock-idp.attributes.name=http://saml.elastic-cloud.com/attributes/email", + "xpack.security.authc.realms.saml.mock-idp.attributes.name=http://saml.elastic-cloud.com/attributes/name", "--env", - "xpack.security.authc.realms.saml.mock-idp.attributes.mail=http://saml.elastic-cloud.com/attributes/name", + "xpack.security.authc.realms.saml.mock-idp.attributes.mail=http://saml.elastic-cloud.com/attributes/email", ] `); }); From 40259a95ca8fa8bd22ddd8eef5782104ebeff2a3 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 19:05:31 +0000 Subject: [PATCH 11/32] Fix offset --- packages/kbn-mock-idp-plugin/public/role_switcher.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx index 4d7cb02f264bf..d35fed1028235 100644 --- a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -95,6 +95,7 @@ export const RoleSwitcher: FunctionComponent = () => { } panelPaddingSize="none" + offset={4} anchorPosition="downRight" repositionOnScroll repositionToCrossAxis={false} From d6a7623125531926ac67bb2012656c448a096fe8 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 21:29:50 +0000 Subject: [PATCH 12/32] Fix application usage test --- .../server/collectors/application_usage/schema.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts index c7ec7deaa16a9..b06cddb67e5e9 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts @@ -153,6 +153,7 @@ export const applicationUsageSchema = { lens: commonSchema, maps: commonSchema, ml: commonSchema, + mock_idp: commonSchema, // Allows SAML login during functional testing which is why it's showing up in this test. Not used in production monitoring: commonSchema, 'observability-log-explorer': commonSchema, 'observability-overview': commonSchema, From 0da9c1c415453a0fc4b1df956d2f782228b65bd2 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Thu, 30 Nov 2023 21:59:01 +0000 Subject: [PATCH 13/32] . --- src/plugins/telemetry/schema/oss_plugins.json | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 0854944f39404..af90bfdca33de 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -4456,6 +4456,137 @@ } } }, + "mock_idp": { + "properties": { + "appId": { + "type": "keyword", + "_meta": { + "description": "The application being tracked" + } + }, + "viewId": { + "type": "keyword", + "_meta": { + "description": "Always `main`" + } + }, + "clicks_total": { + "type": "long", + "_meta": { + "description": "General number of clicks in the application since we started counting them" + } + }, + "clicks_7_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the application over the last 7 days" + } + }, + "clicks_30_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the application over the last 30 days" + } + }, + "clicks_90_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the application over the last 90 days" + } + }, + "minutes_on_screen_total": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen since we started counting them." + } + }, + "minutes_on_screen_7_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen over the last 7 days" + } + }, + "minutes_on_screen_30_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen over the last 30 days" + } + }, + "minutes_on_screen_90_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen over the last 90 days" + } + }, + "views": { + "type": "array", + "items": { + "properties": { + "appId": { + "type": "keyword", + "_meta": { + "description": "The application being tracked" + } + }, + "viewId": { + "type": "keyword", + "_meta": { + "description": "The application view being tracked" + } + }, + "clicks_total": { + "type": "long", + "_meta": { + "description": "General number of clicks in the application sub view since we started counting them" + } + }, + "clicks_7_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the active application sub view over the last 7 days" + } + }, + "clicks_30_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the active application sub view over the last 30 days" + } + }, + "clicks_90_days": { + "type": "long", + "_meta": { + "description": "General number of clicks in the active application sub view over the last 90 days" + } + }, + "minutes_on_screen_total": { + "type": "float", + "_meta": { + "description": "Minutes the application sub view is active and on-screen since we started counting them." + } + }, + "minutes_on_screen_7_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen active application sub view over the last 7 days" + } + }, + "minutes_on_screen_30_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen active application sub view over the last 30 days" + } + }, + "minutes_on_screen_90_days": { + "type": "float", + "_meta": { + "description": "Minutes the application is active and on-screen active application sub view over the last 90 days" + } + } + } + } + } + } + }, "monitoring": { "properties": { "appId": { From 3e2ed3899fca4d685b6fbcf1f21e11bfa56318c6 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Fri, 1 Dec 2023 16:10:55 +0000 Subject: [PATCH 14/32] Only show relevant roles --- packages/kbn-mock-idp-plugin/kibana.jsonc | 3 +++ .../kbn-mock-idp-plugin/public/login_page.tsx | 27 ++++++++++++++----- .../kbn-mock-idp-plugin/public/plugin.tsx | 26 +++++++++++++----- .../public/role_switcher.tsx | 19 ++++++++++--- packages/kbn-mock-idp-utils/src/constants.ts | 6 ++--- packages/kbn-mock-idp-utils/src/index.ts | 4 ++- 6 files changed, 66 insertions(+), 19 deletions(-) diff --git a/packages/kbn-mock-idp-plugin/kibana.jsonc b/packages/kbn-mock-idp-plugin/kibana.jsonc index e486c534348a2..e5bfa29ddc8b4 100644 --- a/packages/kbn-mock-idp-plugin/kibana.jsonc +++ b/packages/kbn-mock-idp-plugin/kibana.jsonc @@ -8,6 +8,9 @@ "server": true, "browser": true, "enabledOnAnonymousPages": true, + "requiredPlugins": [ + "cloud" + ], "requiredBundles": [ "kibanaReact" ] diff --git a/packages/kbn-mock-idp-plugin/public/login_page.tsx b/packages/kbn-mock-idp-plugin/public/login_page.tsx index 36bd7bbc831e7..d5eead71dbfb8 100644 --- a/packages/kbn-mock-idp-plugin/public/login_page.tsx +++ b/packages/kbn-mock-idp-plugin/public/login_page.tsx @@ -17,18 +17,33 @@ import { EuiComboBoxOptionOption, EuiButtonEmpty, } from '@elastic/eui'; -import React, { ChangeEvent } from 'react'; +import React, { ChangeEvent, FunctionComponent } from 'react'; import { FormikProvider, useFormik, Field, Form } from 'formik'; -import { MOCK_IDP_ROLE_NAMES } from '@kbn/mock-idp-utils/src/constants'; +import { + MOCK_IDP_SECURITY_ROLE_NAMES, + MOCK_IDP_OBSERVABILITY_ROLE_NAMES, + MOCK_IDP_SEARCH_ROLE_NAMES, +} from '@kbn/mock-idp-utils/src/constants'; import { useAuthenticator } from './role_switcher'; -export function LoginPage() { +export interface LoginPageProps { + projectType?: string; +} + +export const LoginPage: FunctionComponent = ({ projectType }) => { + const roles = + projectType === 'security' + ? MOCK_IDP_SECURITY_ROLE_NAMES + : projectType === 'observability' + ? MOCK_IDP_OBSERVABILITY_ROLE_NAMES + : MOCK_IDP_SEARCH_ROLE_NAMES; + const [, switchCurrentUser] = useAuthenticator(true); const formik = useFormik({ initialValues: { full_name: 'Test User', - role: MOCK_IDP_ROLE_NAMES[0], + role: roles[0], }, async onSubmit(values) { await switchCurrentUser({ @@ -86,7 +101,7 @@ export function LoginPage() { name="role" placeholder="Select your role" singleSelection={{ asPlainText: true }} - options={MOCK_IDP_ROLE_NAMES.map((role) => ({ label: role }))} + options={roles.map((role) => ({ label: role }))} selectedOptions={ formik.values.role ? [{ label: formik.values.role }] : undefined } @@ -130,7 +145,7 @@ export function LoginPage() { ); -} +}; const sanitizeUsername = (username: string) => username.replace(/[^a-zA-Z0-9_]/g, '_').toLowerCase(); diff --git a/packages/kbn-mock-idp-plugin/public/plugin.tsx b/packages/kbn-mock-idp-plugin/public/plugin.tsx index fc4e513d9895f..3a7ad8b12951f 100644 --- a/packages/kbn-mock-idp-plugin/public/plugin.tsx +++ b/packages/kbn-mock-idp-plugin/public/plugin.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { PluginInitializer, Plugin } from '@kbn/core-plugins-browser'; +import type { PluginInitializer } from '@kbn/core-plugins-browser'; import { AppNavLinkStatus } from '@kbn/core-application-browser'; import React from 'react'; import ReactDOM from 'react-dom'; @@ -14,10 +14,24 @@ import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { I18nProvider } from '@kbn/i18n-react'; import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils/src/constants'; +import type { CloudStart, CloudSetup } from '@kbn/cloud-plugin/public'; import { RoleSwitcher } from './role_switcher'; -export const plugin: PluginInitializer = (): Plugin => ({ - setup(coreSetup) { +export interface PluginSetupDependencies { + cloud?: CloudSetup; +} + +export interface PluginStartDependencies { + cloud?: CloudStart; +} + +export const plugin: PluginInitializer< + void, + void, + PluginSetupDependencies, + PluginStartDependencies +> = () => ({ + setup(coreSetup, plugins) { // Register Mock IDP login page coreSetup.http.anonymousPaths.register(MOCK_IDP_LOGIN_PATH); coreSetup.application.register({ @@ -36,7 +50,7 @@ export const plugin: PluginInitializer = (): Plugin => ({ - + , @@ -47,7 +61,7 @@ export const plugin: PluginInitializer = (): Plugin => ({ }, }); }, - start(coreStart) { + start(coreStart, plugins) { // Register role switcher dropdown menu in the top right navigation of the Kibana UI coreStart.chrome.navControls.registerRight({ order: 4000 + 1, // Make sure it comes after the user menu @@ -56,7 +70,7 @@ export const plugin: PluginInitializer = (): Plugin => ({ - + , diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx index d35fed1028235..cf536d54b885c 100644 --- a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -15,7 +15,9 @@ import type { AuthenticatedUser } from '@kbn/security-plugin-types-common'; import { MOCK_IDP_REALM_NAME, MOCK_IDP_REALM_TYPE, - MOCK_IDP_ROLE_NAMES, + MOCK_IDP_SECURITY_ROLE_NAMES, + MOCK_IDP_OBSERVABILITY_ROLE_NAMES, + MOCK_IDP_SEARCH_ROLE_NAMES, } from '@kbn/mock-idp-utils/src/constants'; import { createReloadPageToast } from './reload_page_toast'; import type { CreateSAMLResponseParams } from '../server'; @@ -51,7 +53,11 @@ export const useAuthenticator = (reloadPage = false) => { }); }; -export const RoleSwitcher: FunctionComponent = () => { +export interface RoleSwitcherProps { + projectType?: string; +} + +export const RoleSwitcher: FunctionComponent = ({ projectType }) => { const [isOpen, setIsOpen] = useState(false); const { services } = useKibana(); const [currentUserState, getCurrentUser] = useCurrentUser(); @@ -79,6 +85,13 @@ export const RoleSwitcher: FunctionComponent = () => { const [currentRole] = currentUserState.value.roles; + const roles = + projectType === 'security' + ? MOCK_IDP_SECURITY_ROLE_NAMES + : projectType === 'observability' + ? MOCK_IDP_OBSERVABILITY_ROLE_NAMES + : MOCK_IDP_SEARCH_ROLE_NAMES; + return ( { { id: 0, title: 'Switch role', - items: MOCK_IDP_ROLE_NAMES.map((role) => ({ + items: roles.map((role) => ({ name: role, icon: currentUserState.value!.roles.includes(role) ? 'check' : 'empty', onClick: () => { diff --git a/packages/kbn-mock-idp-utils/src/constants.ts b/packages/kbn-mock-idp-utils/src/constants.ts index b6dd15c43795b..dc20dc850daa9 100644 --- a/packages/kbn-mock-idp-utils/src/constants.ts +++ b/packages/kbn-mock-idp-utils/src/constants.ts @@ -20,9 +20,9 @@ export const MOCK_IDP_ATTRIBUTE_EMAIL = 'http://saml.elastic-cloud.com/attribute export const MOCK_IDP_ATTRIBUTE_NAME = 'http://saml.elastic-cloud.com/attributes/name'; /** List of roles from `packages/kbn-es/src/serverless_resources/roles.yml` */ -export const MOCK_IDP_ROLE_NAMES = [ - 'viewer', - 'editor', +export const MOCK_IDP_SEARCH_ROLE_NAMES = ['viewer', 'editor', 'system_indices_superuser']; +export const MOCK_IDP_OBSERVABILITY_ROLE_NAMES = ['viewer', 'editor', 'system_indices_superuser']; +export const MOCK_IDP_SECURITY_ROLE_NAMES = [ 't1_analyst', 't2_analyst', 't3_analyst', diff --git a/packages/kbn-mock-idp-utils/src/index.ts b/packages/kbn-mock-idp-utils/src/index.ts index 56f81ba1103ae..413d58da7d6a1 100644 --- a/packages/kbn-mock-idp-utils/src/index.ts +++ b/packages/kbn-mock-idp-utils/src/index.ts @@ -17,7 +17,9 @@ export { MOCK_IDP_ATTRIBUTE_ROLES, MOCK_IDP_ATTRIBUTE_EMAIL, MOCK_IDP_ATTRIBUTE_NAME, - MOCK_IDP_ROLE_NAMES, + MOCK_IDP_SEARCH_ROLE_NAMES, + MOCK_IDP_OBSERVABILITY_ROLE_NAMES, + MOCK_IDP_SECURITY_ROLE_NAMES, } from './constants'; export { createMockIdpMetadata, createSAMLResponse, ensureSAMLRoleMapping } from './utils'; From 86827f238211c7b2a8aa65a9aae69ad6d1a13365 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:18:05 +0000 Subject: [PATCH 15/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- packages/kbn-mock-idp-plugin/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json index 3101364ed3729..c0a6e574cb2e4 100644 --- a/packages/kbn-mock-idp-plugin/tsconfig.json +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -25,5 +25,6 @@ "@kbn/react-kibana-mount", "@kbn/security-plugin-types-common", "@kbn/mock-idp-utils", + "@kbn/cloud-plugin", ] } From d341fb5f63c0b2b1441507bb1cdc0cd1d99a911a Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Fri, 1 Dec 2023 19:54:32 +0000 Subject: [PATCH 16/32] Fix functional test --- .../test_suites/core_plugins/rendering.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 8b248c5bccc68..ca8204421e8dd 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -397,6 +397,23 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'telemetry.sendUsageTo (any)', 'usageCollection.uiCounters.debug (boolean)', 'usageCollection.uiCounters.enabled (boolean)', + + // Included because Mock IDP plugin is enabled in functional tests and depends on cloud plugin to determine serverless project type + 'xpack.cloud.base_url (string)', + 'xpack.cloud.billing_url (string)', + 'xpack.cloud.cname (string)', + 'xpack.cloud.deployment_url (string)', + 'xpack.cloud.id (string)', + 'xpack.cloud.is_elastic_staff_owned (boolean)', + 'xpack.cloud.organization_url (string)', + 'xpack.cloud.performance_url (string)', + 'xpack.cloud.profile_url (string)', + 'xpack.cloud.projects_url (any)', + 'xpack.cloud.serverless.project_id (string)', + 'xpack.cloud.serverless.project_name (string)', + 'xpack.cloud.serverless.project_type (string)', + 'xpack.cloud.trial_end_date (string)', + 'xpack.cloud.users_and_roles_url (string)', ]; // We don't assert that actualExposedConfigKeys and expectedExposedConfigKeys are equal, because test failure messages with large // arrays are hard to grok. Instead, we take the difference between the two arrays and assert them separately, that way it's From 933e2251eeb8874bd2cd25366531a893b88ea487 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Tue, 12 Dec 2023 10:25:42 +0000 Subject: [PATCH 17/32] Fix dynamic imports --- src/cli/serve/serve.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 36d5d1df41ce0..82dafb1ea3a12 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -18,6 +18,8 @@ import { getConfigFromFiles } from '@kbn/config'; const DEV_MODE_PATH = '@kbn/cli-dev-mode'; const DEV_MODE_SUPPORTED = canRequire(DEV_MODE_PATH); +const MOCK_IDP_PLUGIN_PATH = '@kbn/mock-idp-plugin/common'; +const MOCK_IDP_PLUGIN_SUPPORTED = canRequire(MOCK_IDP_PLUGIN_PATH); function canRequire(path) { try { @@ -111,10 +113,11 @@ export function applyConfigOverrides(rawConfig, opts, extraCliOptions) { setServerlessKibanaDevServiceAccountIfPossible(get, set, opts); // Load mock identity provider plugin and configure realm if supported (ES only supports SAML when run with SSL) - if (opts.ssl && canRequire('@kbn/mock-idp-plugin/common')) { + if (opts.ssl && MOCK_IDP_PLUGIN_SUPPORTED) { // Ensure the plugin is loaded in dynamically to exclude from production build - const { MOCK_IDP_REALM_NAME } = require('@kbn/mock-idp-plugin/common'); - const pluginPath = resolve(require.resolve('@kbn/mock-idp-plugin/common'), '..'); + // eslint-disable-next-line import/no-dynamic-require + const { MOCK_IDP_REALM_NAME } = require(MOCK_IDP_PLUGIN_PATH); + const pluginPath = resolve(require.resolve(MOCK_IDP_PLUGIN_PATH), '..'); if (has('server.basePath')) { console.log( From 680575570e6752a08d4ea32033003d3fc5133ba6 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:34:14 +0000 Subject: [PATCH 18/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- src/cli/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cli/tsconfig.json b/src/cli/tsconfig.json index 3b3c0854975d3..ebbbc19f75c79 100644 --- a/src/cli/tsconfig.json +++ b/src/cli/tsconfig.json @@ -17,7 +17,6 @@ "@kbn/config", "@kbn/dev-utils", "@kbn/apm-config-loader", - "@kbn/mock-idp-plugin", ], "exclude": [ "target/**/*", From aaa7c7248f5226b5e5eadfae1f43b570041bb327 Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Tue, 12 Dec 2023 11:01:15 +0000 Subject: [PATCH 19/32] Fix cyclic dependencies --- packages/kbn-test/src/auth/saml_auth.ts | 2 +- packages/kbn-test/tsconfig.json | 9 ++++++--- .../api_integration/services/saml_tools.ts | 2 +- x-pack/test_serverless/shared/config.base.ts | 2 +- x-pack/test_serverless/tsconfig.json | 4 ++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/kbn-test/src/auth/saml_auth.ts b/packages/kbn-test/src/auth/saml_auth.ts index 996f16eace38a..2c0552e39c477 100644 --- a/packages/kbn-test/src/auth/saml_auth.ts +++ b/packages/kbn-test/src/auth/saml_auth.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { createSAMLResponse as createMockedSAMLResponse } from '@kbn/mock-idp-plugin/common'; +import { createSAMLResponse as createMockedSAMLResponse } from '@kbn/mock-idp-utils'; import { ToolingLog } from '@kbn/tooling-log'; import axios, { AxiosResponse } from 'axios'; import * as cheerio from 'cheerio'; diff --git a/packages/kbn-test/tsconfig.json b/packages/kbn-test/tsconfig.json index abf0a35c4438a..30460f9660afb 100644 --- a/packages/kbn-test/tsconfig.json +++ b/packages/kbn-test/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "outDir": "target/types", "stripInternal": true, - "types": ["jest", "node"] + "types": [ + "jest", + "node" + ] }, "include": [ "**/*.ts", @@ -32,6 +35,6 @@ "@kbn/babel-register", "@kbn/repo-packages", "@kbn/core-saved-objects-api-server", - "@kbn/mock-idp-plugin", + "@kbn/mock-idp-utils", ] -} +} \ No newline at end of file diff --git a/x-pack/test_serverless/api_integration/services/saml_tools.ts b/x-pack/test_serverless/api_integration/services/saml_tools.ts index bd5cd03a7edbb..925f963f1223e 100644 --- a/x-pack/test_serverless/api_integration/services/saml_tools.ts +++ b/x-pack/test_serverless/api_integration/services/saml_tools.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { parse as parseCookie } from 'tough-cookie'; import Url from 'url'; -import { createSAMLResponse } from '@kbn/mock-idp-plugin/common'; +import { createSAMLResponse } from '@kbn/mock-idp-utils'; import { FtrProviderContext } from '../ftr_provider_context'; export function SamlToolsProvider({ getService }: FtrProviderContext) { diff --git a/x-pack/test_serverless/shared/config.base.ts b/x-pack/test_serverless/shared/config.base.ts index 6dee26203b532..9c2454d4e7a39 100644 --- a/x-pack/test_serverless/shared/config.base.ts +++ b/x-pack/test_serverless/shared/config.base.ts @@ -18,7 +18,7 @@ import { } from '@kbn/test'; import { CA_CERT_PATH, kibanaDevServiceAccount } from '@kbn/dev-utils'; import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; -import { MOCK_IDP_REALM_NAME } from '@kbn/mock-idp-plugin/common'; +import { MOCK_IDP_REALM_NAME } from '@kbn/mock-idp-utils'; import { services } from './services'; export default async () => { diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 72039a6ad1368..05dc1ffdcdd6d 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -79,9 +79,9 @@ "@kbn/apm-synthtrace", "@kbn/apm-synthtrace-client", "@kbn/reporting-export-types-csv-common", - "@kbn/mock-idp-plugin", + "@kbn/mock-idp-utils", "@kbn/io-ts-utils", "@kbn/log-explorer-plugin", "@kbn/index-management-plugin", ] -} +} \ No newline at end of file From e52244e08d4fc9daad3a2660197347d390503901 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:09:57 +0000 Subject: [PATCH 20/32] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- packages/kbn-test/tsconfig.json | 2 +- x-pack/test_serverless/tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kbn-test/tsconfig.json b/packages/kbn-test/tsconfig.json index 30460f9660afb..992765534cfbc 100644 --- a/packages/kbn-test/tsconfig.json +++ b/packages/kbn-test/tsconfig.json @@ -37,4 +37,4 @@ "@kbn/core-saved-objects-api-server", "@kbn/mock-idp-utils", ] -} \ No newline at end of file +} diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 05dc1ffdcdd6d..a4043ab33dac5 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -84,4 +84,4 @@ "@kbn/log-explorer-plugin", "@kbn/index-management-plugin", ] -} \ No newline at end of file +} From 7dd3e444e4ff2dcb0793697a28dc022184a92c5a Mon Sep 17 00:00:00 2001 From: Thom Heymann Date: Tue, 12 Dec 2023 11:37:56 +0000 Subject: [PATCH 21/32] Fix types --- packages/kbn-test/src/auth/saml_auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-test/src/auth/saml_auth.ts b/packages/kbn-test/src/auth/saml_auth.ts index 2c0552e39c477..23ec880cbc44d 100644 --- a/packages/kbn-test/src/auth/saml_auth.ts +++ b/packages/kbn-test/src/auth/saml_auth.ts @@ -217,7 +217,7 @@ export const createLocalSAMLSession = async (params: LocalSamlSessionParams) => const samlResponse = await createMockedSAMLResponse({ kibanaUrl: kbnHost + '/api/security/saml/callback', username, - fullname, + full_name: fullname, email, roles: [role], }); From 404d4ab34eb1cf7f70161f6727c2bee05cfa4a7f Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:47:34 +0000 Subject: [PATCH 22/32] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- packages/kbn-mock-idp-utils/src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-mock-idp-utils/src/utils.ts b/packages/kbn-mock-idp-utils/src/utils.ts index 9a8dce01fe762..c1b4824ec0d13 100644 --- a/packages/kbn-mock-idp-utils/src/utils.ts +++ b/packages/kbn-mock-idp-utils/src/utils.ts @@ -8,7 +8,7 @@ import { Client } from '@elastic/elasticsearch'; // xml-crypto is part of devDependencies -// eslint-disable-next-line import/no-extraneous-dependencies + import { SignedXml } from 'xml-crypto'; import { KBN_KEY_PATH, KBN_CERT_PATH } from '@kbn/dev-utils'; import { readFile } from 'fs/promises'; From 3f6db79ee5f4566ed7851bf1a457fbfa58d27cae Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 3 Jan 2024 13:38:46 +0100 Subject: [PATCH 23/32] [will be reverted] add debug info --- packages/kbn-repo-packages/modern/get_packages.js | 14 ++++++++++---- .../modern/parse_package_manifest.js | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/kbn-repo-packages/modern/get_packages.js b/packages/kbn-repo-packages/modern/get_packages.js index 45978baba86ed..7c1e883ae6fb3 100644 --- a/packages/kbn-repo-packages/modern/get_packages.js +++ b/packages/kbn-repo-packages/modern/get_packages.js @@ -114,10 +114,16 @@ function getPackages(repoRoot) { return packages; } catch (error) { if (error.code === 'ENOENT') { - // a package manifest was removed, auto-regenerate the package map - const manifests = Array.from(getRepoRelsSync(repoRoot, ['**/kibana.jsonc'])); - if (updatePackageMap(repoRoot, manifests)) { - return getPackages(repoRoot); + try { + // a package manifest was removed, auto-regenerate the package map + const manifests = Array.from(getRepoRelsSync(repoRoot, ['**/kibana.jsonc'])); + if (updatePackageMap(repoRoot, manifests)) { + return getPackages(repoRoot); + } + } catch (error2) { + throw new Error( + `Error reconstructing package list following ENOENT for path ${error.manifestPath}. message: ${error2}` + ); } } diff --git a/packages/kbn-repo-packages/modern/parse_package_manifest.js b/packages/kbn-repo-packages/modern/parse_package_manifest.js index d82ca10bf2b1c..123ca75f37e38 100644 --- a/packages/kbn-repo-packages/modern/parse_package_manifest.js +++ b/packages/kbn-repo-packages/modern/parse_package_manifest.js @@ -317,7 +317,7 @@ function readPackageManifest(repoRoot, path) { } catch (error) { if (error.code === 'ENOENT') { const err = new Error(`Missing kibana.jsonc file at ${path}`); - throw Object.assign(err, { code: 'ENOENT' }); + throw Object.assign(err, { code: 'ENOENT', manifestPath: path }); } throw error; From b14d5ee895ecc9b4ffadaf70a0419f5a0cd99d8e Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 3 Jan 2024 13:47:28 +0100 Subject: [PATCH 24/32] Revert "[will be reverted] add debug info" This reverts commit 3f6db79ee5f4566ed7851bf1a457fbfa58d27cae. --- packages/kbn-repo-packages/modern/get_packages.js | 14 ++++---------- .../modern/parse_package_manifest.js | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/kbn-repo-packages/modern/get_packages.js b/packages/kbn-repo-packages/modern/get_packages.js index 7c1e883ae6fb3..45978baba86ed 100644 --- a/packages/kbn-repo-packages/modern/get_packages.js +++ b/packages/kbn-repo-packages/modern/get_packages.js @@ -114,16 +114,10 @@ function getPackages(repoRoot) { return packages; } catch (error) { if (error.code === 'ENOENT') { - try { - // a package manifest was removed, auto-regenerate the package map - const manifests = Array.from(getRepoRelsSync(repoRoot, ['**/kibana.jsonc'])); - if (updatePackageMap(repoRoot, manifests)) { - return getPackages(repoRoot); - } - } catch (error2) { - throw new Error( - `Error reconstructing package list following ENOENT for path ${error.manifestPath}. message: ${error2}` - ); + // a package manifest was removed, auto-regenerate the package map + const manifests = Array.from(getRepoRelsSync(repoRoot, ['**/kibana.jsonc'])); + if (updatePackageMap(repoRoot, manifests)) { + return getPackages(repoRoot); } } diff --git a/packages/kbn-repo-packages/modern/parse_package_manifest.js b/packages/kbn-repo-packages/modern/parse_package_manifest.js index 123ca75f37e38..d82ca10bf2b1c 100644 --- a/packages/kbn-repo-packages/modern/parse_package_manifest.js +++ b/packages/kbn-repo-packages/modern/parse_package_manifest.js @@ -317,7 +317,7 @@ function readPackageManifest(repoRoot, path) { } catch (error) { if (error.code === 'ENOENT') { const err = new Error(`Missing kibana.jsonc file at ${path}`); - throw Object.assign(err, { code: 'ENOENT', manifestPath: path }); + throw Object.assign(err, { code: 'ENOENT' }); } throw error; From a7596116a80bc8d05e2976109e301a9c3738234d Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Wed, 3 Jan 2024 14:38:21 +0100 Subject: [PATCH 25/32] Exclude dev-only packages from `package-map.json`. --- src/dev/build/tasks/build_packages_task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dev/build/tasks/build_packages_task.ts b/src/dev/build/tasks/build_packages_task.ts index 5db703481b7df..1f6e150496921 100644 --- a/src/dev/build/tasks/build_packages_task.ts +++ b/src/dev/build/tasks/build_packages_task.ts @@ -255,7 +255,7 @@ export const BuildPackages: Task = { Path.resolve(pkgDistPath, 'package-map.json'), JSON.stringify( packages - .filter((p) => p.isPlugin()) + .filter((p) => p.isPlugin() && !p.isDevOnly()) .map((p) => [p.manifest.id, `node_modules/${p.manifest.id}`]) ) ); From 65df3a335f5bba779e32f11bc46415c461d6b30e Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Wed, 3 Jan 2024 18:15:02 +0100 Subject: [PATCH 26/32] Revert unnecessary test/telemetry changes. --- packages/kbn-mock-idp-utils/src/utils.ts | 1 - .../collectors/application_usage/schema.ts | 1 - src/plugins/telemetry/schema/oss_plugins.json | 131 ------------------ .../test_suites/core_plugins/rendering.ts | 17 --- 4 files changed, 150 deletions(-) diff --git a/packages/kbn-mock-idp-utils/src/utils.ts b/packages/kbn-mock-idp-utils/src/utils.ts index c1b4824ec0d13..f4b492bf90560 100644 --- a/packages/kbn-mock-idp-utils/src/utils.ts +++ b/packages/kbn-mock-idp-utils/src/utils.ts @@ -7,7 +7,6 @@ */ import { Client } from '@elastic/elasticsearch'; -// xml-crypto is part of devDependencies import { SignedXml } from 'xml-crypto'; import { KBN_KEY_PATH, KBN_CERT_PATH } from '@kbn/dev-utils'; diff --git a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts index b06cddb67e5e9..c7ec7deaa16a9 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts @@ -153,7 +153,6 @@ export const applicationUsageSchema = { lens: commonSchema, maps: commonSchema, ml: commonSchema, - mock_idp: commonSchema, // Allows SAML login during functional testing which is why it's showing up in this test. Not used in production monitoring: commonSchema, 'observability-log-explorer': commonSchema, 'observability-overview': commonSchema, diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 5774752dec6dd..e04e83dc46feb 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -4456,137 +4456,6 @@ } } }, - "mock_idp": { - "properties": { - "appId": { - "type": "keyword", - "_meta": { - "description": "The application being tracked" - } - }, - "viewId": { - "type": "keyword", - "_meta": { - "description": "Always `main`" - } - }, - "clicks_total": { - "type": "long", - "_meta": { - "description": "General number of clicks in the application since we started counting them" - } - }, - "clicks_7_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the application over the last 7 days" - } - }, - "clicks_30_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the application over the last 30 days" - } - }, - "clicks_90_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the application over the last 90 days" - } - }, - "minutes_on_screen_total": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen since we started counting them." - } - }, - "minutes_on_screen_7_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen over the last 7 days" - } - }, - "minutes_on_screen_30_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen over the last 30 days" - } - }, - "minutes_on_screen_90_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen over the last 90 days" - } - }, - "views": { - "type": "array", - "items": { - "properties": { - "appId": { - "type": "keyword", - "_meta": { - "description": "The application being tracked" - } - }, - "viewId": { - "type": "keyword", - "_meta": { - "description": "The application view being tracked" - } - }, - "clicks_total": { - "type": "long", - "_meta": { - "description": "General number of clicks in the application sub view since we started counting them" - } - }, - "clicks_7_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the active application sub view over the last 7 days" - } - }, - "clicks_30_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the active application sub view over the last 30 days" - } - }, - "clicks_90_days": { - "type": "long", - "_meta": { - "description": "General number of clicks in the active application sub view over the last 90 days" - } - }, - "minutes_on_screen_total": { - "type": "float", - "_meta": { - "description": "Minutes the application sub view is active and on-screen since we started counting them." - } - }, - "minutes_on_screen_7_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen active application sub view over the last 7 days" - } - }, - "minutes_on_screen_30_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen active application sub view over the last 30 days" - } - }, - "minutes_on_screen_90_days": { - "type": "float", - "_meta": { - "description": "Minutes the application is active and on-screen active application sub view over the last 90 days" - } - } - } - } - } - } - }, "monitoring": { "properties": { "appId": { diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index ca8204421e8dd..8b248c5bccc68 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -397,23 +397,6 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'telemetry.sendUsageTo (any)', 'usageCollection.uiCounters.debug (boolean)', 'usageCollection.uiCounters.enabled (boolean)', - - // Included because Mock IDP plugin is enabled in functional tests and depends on cloud plugin to determine serverless project type - 'xpack.cloud.base_url (string)', - 'xpack.cloud.billing_url (string)', - 'xpack.cloud.cname (string)', - 'xpack.cloud.deployment_url (string)', - 'xpack.cloud.id (string)', - 'xpack.cloud.is_elastic_staff_owned (boolean)', - 'xpack.cloud.organization_url (string)', - 'xpack.cloud.performance_url (string)', - 'xpack.cloud.profile_url (string)', - 'xpack.cloud.projects_url (any)', - 'xpack.cloud.serverless.project_id (string)', - 'xpack.cloud.serverless.project_name (string)', - 'xpack.cloud.serverless.project_type (string)', - 'xpack.cloud.trial_end_date (string)', - 'xpack.cloud.users_and_roles_url (string)', ]; // We don't assert that actualExposedConfigKeys and expectedExposedConfigKeys are equal, because test failure messages with large // arrays are hard to grok. Instead, we take the difference between the two arrays and assert them separately, that way it's From b1cd8ab67907b3f1bfbfc49c8cb9a47d77662f70 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 4 Jan 2024 13:23:11 +0100 Subject: [PATCH 27/32] Add workaround for missing `mock_idp` plugin in serverless tests. --- .../plugins/saml_provider/server/init_routes.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts index 6ef30b808ada2..f9cf437122cb9 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts +++ b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts @@ -59,6 +59,18 @@ export function initRoutes(core: CoreSetup) { } ); + // [HACK]: Incredible hack to workaround absence of the Mock IDP plugin in production build used for testing. + core.http.resources.register( + { + path: '/mock_idp/login', + validate: false, + options: { authRequired: false }, + }, + async (context, request, response) => { + return response.redirected({ headers: { location: 'https://cloud.elastic.co/projects' } }); + } + ); + let attemptsCounter = 0; core.http.resources.register( { From 2aafc3bea83e46bbff61f2ec2897e3a50e5cbde2 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 4 Jan 2024 14:11:41 +0100 Subject: [PATCH 28/32] Register fake root only in production mode to please Cypress tests that seem to run in dev mode (why?????). --- .../plugins/saml_provider/server/index.ts | 4 +-- .../saml_provider/server/init_routes.ts | 26 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts b/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts index 9a5efa5fa6861..1a8dbd3c4c983 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts +++ b/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts @@ -8,8 +8,8 @@ import type { PluginInitializer, Plugin } from '@kbn/core/server'; import { initRoutes } from './init_routes'; -export const plugin: PluginInitializer = async (): Promise => ({ - setup: (core) => initRoutes(core), +export const plugin: PluginInitializer = async (context): Promise => ({ + setup: (core) => initRoutes(context, core), start: () => {}, stop: () => {}, }); diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts index f9cf437122cb9..eed2ce6394ad6 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts +++ b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { CoreSetup } from '@kbn/core/server'; +import { CoreSetup, PluginInitializerContext } from '@kbn/core/server'; import { getSAMLResponse, getSAMLRequestId, } from '@kbn/security-api-integration-helpers/saml/saml_tools'; -export function initRoutes(core: CoreSetup) { +export function initRoutes(pluginContext: PluginInitializerContext, core: CoreSetup) { const serverInfo = core.http.getServerInfo(); core.http.resources.register( { @@ -60,16 +60,18 @@ export function initRoutes(core: CoreSetup) { ); // [HACK]: Incredible hack to workaround absence of the Mock IDP plugin in production build used for testing. - core.http.resources.register( - { - path: '/mock_idp/login', - validate: false, - options: { authRequired: false }, - }, - async (context, request, response) => { - return response.redirected({ headers: { location: 'https://cloud.elastic.co/projects' } }); - } - ); + if (pluginContext.env.mode.prod) { + core.http.resources.register( + { + path: '/mock_idp/login', + validate: false, + options: { authRequired: false }, + }, + async (context, request, response) => { + return response.redirected({ headers: { location: 'https://cloud.elastic.co/projects' } }); + } + ); + } let attemptsCounter = 0; core.http.resources.register( From 6f6b5af5535460bda44534cfc41272a2aebb6ad1 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Fri, 5 Jan 2024 13:07:35 +0100 Subject: [PATCH 29/32] Apply builkite patch from @delanni --- .buildkite/scripts/steps/cloud/build_and_deploy.sh | 2 +- .buildkite/scripts/steps/serverless/build_and_deploy.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.buildkite/scripts/steps/cloud/build_and_deploy.sh b/.buildkite/scripts/steps/cloud/build_and_deploy.sh index b6c2dcd0968e3..62f92b716b651 100755 --- a/.buildkite/scripts/steps/cloud/build_and_deploy.sh +++ b/.buildkite/scripts/steps/cloud/build_and_deploy.sh @@ -62,7 +62,7 @@ fi echo "--- Create Deployment" CLOUD_DEPLOYMENT_ID=$(ecctl deployment list --output json | jq -r '.deployments[] | select(.name == "'$CLOUD_DEPLOYMENT_NAME'") | .id') -if [ -z "${CLOUD_DEPLOYMENT_ID}" ]; then +if [ -z "${CLOUD_DEPLOYMENT_ID}" ] || [ "${CLOUD_DEPLOYMENT_ID}" = 'null' ]; then jq ' .resources.kibana[0].plan.kibana.docker_image = "'$KIBANA_CLOUD_IMAGE'" | .resources.elasticsearch[0].plan.elasticsearch.docker_image = "'$ELASTICSEARCH_CLOUD_IMAGE'" | diff --git a/.buildkite/scripts/steps/serverless/build_and_deploy.sh b/.buildkite/scripts/steps/serverless/build_and_deploy.sh index a78252e3baec0..3e69f4b4878b7 100644 --- a/.buildkite/scripts/steps/serverless/build_and_deploy.sh +++ b/.buildkite/scripts/steps/serverless/build_and_deploy.sh @@ -59,6 +59,11 @@ deploy() { -XPOST -d "$PROJECT_CREATE_CONFIGURATION" &>> $DEPLOY_LOGS PROJECT_ID=$(jq -r --slurp '.[1].id' $DEPLOY_LOGS) + if [ -z "${PROJECT_ID}" ] || [ "$PROJECT_ID" = 'null' ]; then + echo "Failed to create project. Deploy logs:" + cat $DEPLOY_LOGS + exit 1 + fi echo "Get credentials..." curl -s -XPOST -H "Authorization: ApiKey $PROJECT_API_KEY" \ From ae6aabf3027b9e7825bb3e0431480ea2b26ca0a2 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 11 Jan 2024 12:18:45 +0200 Subject: [PATCH 30/32] A few minor tweaks. --- packages/kbn-mock-idp-plugin/common/index.ts | 2 +- .../kbn-mock-idp-plugin/public/login_page.tsx | 2 +- packages/kbn-mock-idp-plugin/public/plugin.tsx | 2 +- .../public/role_switcher.tsx | 2 +- .../plugins/saml_provider/kibana.jsonc | 5 ++++- .../plugins/saml_provider/server/index.ts | 11 +++++++++-- .../plugins/saml_provider/server/init_routes.ts | 17 ++++++++++++++--- .../plugins/saml_provider/tsconfig.json | 1 + 8 files changed, 32 insertions(+), 10 deletions(-) diff --git a/packages/kbn-mock-idp-plugin/common/index.ts b/packages/kbn-mock-idp-plugin/common/index.ts index 3143e81ce6899..9b79606d51f88 100644 --- a/packages/kbn-mock-idp-plugin/common/index.ts +++ b/packages/kbn-mock-idp-plugin/common/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from '@kbn/mock-idp-utils'; +export { MOCK_IDP_REALM_NAME } from '@kbn/mock-idp-utils'; diff --git a/packages/kbn-mock-idp-plugin/public/login_page.tsx b/packages/kbn-mock-idp-plugin/public/login_page.tsx index d5eead71dbfb8..145685eb0449f 100644 --- a/packages/kbn-mock-idp-plugin/public/login_page.tsx +++ b/packages/kbn-mock-idp-plugin/public/login_page.tsx @@ -24,7 +24,7 @@ import { MOCK_IDP_SECURITY_ROLE_NAMES, MOCK_IDP_OBSERVABILITY_ROLE_NAMES, MOCK_IDP_SEARCH_ROLE_NAMES, -} from '@kbn/mock-idp-utils/src/constants'; +} from '@kbn/mock-idp-utils'; import { useAuthenticator } from './role_switcher'; export interface LoginPageProps { diff --git a/packages/kbn-mock-idp-plugin/public/plugin.tsx b/packages/kbn-mock-idp-plugin/public/plugin.tsx index 3a7ad8b12951f..c125aca6e31f5 100644 --- a/packages/kbn-mock-idp-plugin/public/plugin.tsx +++ b/packages/kbn-mock-idp-plugin/public/plugin.tsx @@ -13,7 +13,7 @@ import ReactDOM from 'react-dom'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { I18nProvider } from '@kbn/i18n-react'; -import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils/src/constants'; +import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils'; import type { CloudStart, CloudSetup } from '@kbn/cloud-plugin/public'; import { RoleSwitcher } from './role_switcher'; diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx index cf536d54b885c..a066f2009f532 100644 --- a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -18,7 +18,7 @@ import { MOCK_IDP_SECURITY_ROLE_NAMES, MOCK_IDP_OBSERVABILITY_ROLE_NAMES, MOCK_IDP_SEARCH_ROLE_NAMES, -} from '@kbn/mock-idp-utils/src/constants'; +} from '@kbn/mock-idp-utils'; import { createReloadPageToast } from './reload_page_toast'; import type { CreateSAMLResponseParams } from '../server'; diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/kibana.jsonc b/x-pack/test/security_api_integration/plugins/saml_provider/kibana.jsonc index 82ab9eb2cf59a..1aa22257908ce 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/kibana.jsonc +++ b/x-pack/test/security_api_integration/plugins/saml_provider/kibana.jsonc @@ -5,6 +5,9 @@ "plugin": { "id": "samlProviderPlugin", "server": true, - "browser": false + "browser": false, + "optionalPlugins": [ + "cloud" + ] } } diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts b/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts index 1a8dbd3c4c983..ad297baf7246f 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts +++ b/x-pack/test/security_api_integration/plugins/saml_provider/server/index.ts @@ -6,10 +6,17 @@ */ import type { PluginInitializer, Plugin } from '@kbn/core/server'; +import { CloudSetup } from '@kbn/cloud-plugin/server'; import { initRoutes } from './init_routes'; -export const plugin: PluginInitializer = async (context): Promise => ({ - setup: (core) => initRoutes(context, core), +export interface PluginSetupDependencies { + cloud?: CloudSetup; +} + +export const plugin: PluginInitializer = async ( + context +): Promise => ({ + setup: (core, plugins: PluginSetupDependencies) => initRoutes(context, core, plugins), start: () => {}, stop: () => {}, }); diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts index eed2ce6394ad6..ea23e04201a61 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts +++ b/x-pack/test/security_api_integration/plugins/saml_provider/server/init_routes.ts @@ -10,8 +10,13 @@ import { getSAMLResponse, getSAMLRequestId, } from '@kbn/security-api-integration-helpers/saml/saml_tools'; +import { PluginSetupDependencies } from '.'; -export function initRoutes(pluginContext: PluginInitializerContext, core: CoreSetup) { +export function initRoutes( + pluginContext: PluginInitializerContext, + core: CoreSetup, + plugins: PluginSetupDependencies +) { const serverInfo = core.http.getServerInfo(); core.http.resources.register( { @@ -59,7 +64,11 @@ export function initRoutes(pluginContext: PluginInitializerContext, core: CoreSe } ); - // [HACK]: Incredible hack to workaround absence of the Mock IDP plugin in production build used for testing. + // [HACK]: On CI, Kibana runs Serverless functional tests against the production Kibana build but still relies on Mock + // IdP for SAML authentication in tests. The Mock IdP SAML realm, in turn, is linked to a Mock IDP plugin in Kibana + // that's only included in development mode and not available in the production Kibana build. Until our testing + // framework can properly support all SAML flows, we should forward all relevant Mock IDP plugin endpoints to a logout + // destination normally used in the Serverless setup. if (pluginContext.env.mode.prod) { core.http.resources.register( { @@ -68,7 +77,9 @@ export function initRoutes(pluginContext: PluginInitializerContext, core: CoreSe options: { authRequired: false }, }, async (context, request, response) => { - return response.redirected({ headers: { location: 'https://cloud.elastic.co/projects' } }); + return response.redirected({ + headers: { location: plugins.cloud?.projectsUrl ?? '/login' }, + }); } ); } diff --git a/x-pack/test/security_api_integration/plugins/saml_provider/tsconfig.json b/x-pack/test/security_api_integration/plugins/saml_provider/tsconfig.json index 5063eccab4842..5021e45b8f8b3 100644 --- a/x-pack/test/security_api_integration/plugins/saml_provider/tsconfig.json +++ b/x-pack/test/security_api_integration/plugins/saml_provider/tsconfig.json @@ -11,6 +11,7 @@ "target/**/*", ], "kbn_references": [ + "@kbn/cloud-plugin", "@kbn/core", "@kbn/security-api-integration-helpers", ] From eaba0ef02509702ea75d5278406e3ed8631fd714 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Thu, 11 Jan 2024 12:46:41 +0200 Subject: [PATCH 31/32] Few more tweaks. --- packages/kbn-mock-idp-plugin/public/login_page.tsx | 2 +- packages/kbn-mock-idp-plugin/public/plugin.tsx | 2 +- packages/kbn-mock-idp-plugin/public/role_switcher.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kbn-mock-idp-plugin/public/login_page.tsx b/packages/kbn-mock-idp-plugin/public/login_page.tsx index 145685eb0449f..d5eead71dbfb8 100644 --- a/packages/kbn-mock-idp-plugin/public/login_page.tsx +++ b/packages/kbn-mock-idp-plugin/public/login_page.tsx @@ -24,7 +24,7 @@ import { MOCK_IDP_SECURITY_ROLE_NAMES, MOCK_IDP_OBSERVABILITY_ROLE_NAMES, MOCK_IDP_SEARCH_ROLE_NAMES, -} from '@kbn/mock-idp-utils'; +} from '@kbn/mock-idp-utils/src/constants'; import { useAuthenticator } from './role_switcher'; export interface LoginPageProps { diff --git a/packages/kbn-mock-idp-plugin/public/plugin.tsx b/packages/kbn-mock-idp-plugin/public/plugin.tsx index c125aca6e31f5..3a7ad8b12951f 100644 --- a/packages/kbn-mock-idp-plugin/public/plugin.tsx +++ b/packages/kbn-mock-idp-plugin/public/plugin.tsx @@ -13,7 +13,7 @@ import ReactDOM from 'react-dom'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { I18nProvider } from '@kbn/i18n-react'; -import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils'; +import { MOCK_IDP_LOGIN_PATH } from '@kbn/mock-idp-utils/src/constants'; import type { CloudStart, CloudSetup } from '@kbn/cloud-plugin/public'; import { RoleSwitcher } from './role_switcher'; diff --git a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx index a066f2009f532..cf536d54b885c 100644 --- a/packages/kbn-mock-idp-plugin/public/role_switcher.tsx +++ b/packages/kbn-mock-idp-plugin/public/role_switcher.tsx @@ -18,7 +18,7 @@ import { MOCK_IDP_SECURITY_ROLE_NAMES, MOCK_IDP_OBSERVABILITY_ROLE_NAMES, MOCK_IDP_SEARCH_ROLE_NAMES, -} from '@kbn/mock-idp-utils'; +} from '@kbn/mock-idp-utils/src/constants'; import { createReloadPageToast } from './reload_page_toast'; import type { CreateSAMLResponseParams } from '../server'; From f979aa7a006f698822271af4fb97bd672989b112 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Fri, 12 Jan 2024 21:24:56 +0200 Subject: [PATCH 32/32] Review#1: move `isDevOnly` check to `getDistPackagesFromRepo`. --- src/dev/build/lib/config.ts | 2 +- src/dev/build/tasks/build_packages_task.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dev/build/lib/config.ts b/src/dev/build/lib/config.ts index a27592e3f6427..19fbd6ae8bd37 100644 --- a/src/dev/build/lib/config.ts +++ b/src/dev/build/lib/config.ts @@ -246,7 +246,7 @@ export class Config { return getPackages(this.repoRoot).filter( (p) => (this.pluginSelector.testPlugins || !p.isDevOnly()) && - (!p.isPlugin() || this.pluginFilter(p)) + (!p.isPlugin() || (this.pluginFilter(p) && !p.isDevOnly())) ); } diff --git a/src/dev/build/tasks/build_packages_task.ts b/src/dev/build/tasks/build_packages_task.ts index 1f6e150496921..5db703481b7df 100644 --- a/src/dev/build/tasks/build_packages_task.ts +++ b/src/dev/build/tasks/build_packages_task.ts @@ -255,7 +255,7 @@ export const BuildPackages: Task = { Path.resolve(pkgDistPath, 'package-map.json'), JSON.stringify( packages - .filter((p) => p.isPlugin() && !p.isDevOnly()) + .filter((p) => p.isPlugin()) .map((p) => [p.manifest.id, `node_modules/${p.manifest.id}`]) ) );