diff --git a/src/core/server/integration_tests/http/lifecycle_handlers.test.ts b/src/core/server/integration_tests/http/lifecycle_handlers.test.ts index 2ba0aa0e6f8e4..912618b91739d 100644 --- a/src/core/server/integration_tests/http/lifecycle_handlers.test.ts +++ b/src/core/server/integration_tests/http/lifecycle_handlers.test.ts @@ -7,14 +7,10 @@ */ import supertest from 'supertest'; -import moment from 'moment'; import { kibanaPackageJson } from '@kbn/repo-info'; -import { BehaviorSubject } from 'rxjs'; -import { ByteSizeValue } from '@kbn/config-schema'; -import { configServiceMock } from '@kbn/config-mocks'; import type { IRouter, RouteRegistrar } from '@kbn/core-http-server'; import { contextServiceMock } from '@kbn/core-http-context-server-mocks'; -import { createHttpServer } from '@kbn/core-http-server-mocks'; +import { createConfigService, createHttpServer } from '@kbn/core-http-server-mocks'; import { HttpService, HttpServerSetup } from '@kbn/core-http-server-internal'; import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks'; @@ -31,97 +27,29 @@ const setupDeps = { executionContext: executionContextServiceMock.createInternalSetupContract(), }; -interface HttpConfigTestOptions { - enabled?: boolean; -} -const setUpDefaultServerConfig = ({ enabled }: HttpConfigTestOptions = {}) => - ({ - hosts: ['localhost'], - maxPayload: new ByteSizeValue(1024), - shutdownTimeout: moment.duration(30, 'seconds'), - autoListen: true, - ssl: { - enabled: false, - }, - cors: { - enabled: false, - }, - compression: { enabled: true, brotli: { enabled: false } }, - name: kibanaName, - securityResponseHeaders: { - // reflects default config - strictTransportSecurity: null, - xContentTypeOptions: 'nosniff', - referrerPolicy: 'strict-origin-when-cross-origin', - permissionsPolicy: null, - crossOriginOpenerPolicy: 'same-origin', - }, - customResponseHeaders: { - 'some-header': 'some-value', - 'referrer-policy': 'strict-origin', // overrides a header that is defined by securityResponseHeaders - }, - xsrf: { disableProtection: false, allowlist: [allowlistedTestPath] }, - requestId: { - allowFromAnyIp: true, - ipAllowlist: [], - }, - restrictInternalApis: enabled ?? false, // reflects default for public routes - } as any); - describe('core lifecycle handlers', () => { let server: HttpService; let innerServer: HttpServerSetup['server']; let router: IRouter; beforeEach(async () => { - const configService = configServiceMock.create(); - configService.atPath.mockImplementation((path) => { - if (path === 'server') { - return new BehaviorSubject({ - hosts: ['localhost'], - maxPayload: new ByteSizeValue(1024), - shutdownTimeout: moment.duration(30, 'seconds'), - autoListen: true, - ssl: { - enabled: false, - }, - cors: { - enabled: false, - }, - compression: { enabled: true, brotli: { enabled: false } }, - name: kibanaName, - securityResponseHeaders: { - // reflects default config - strictTransportSecurity: null, - xContentTypeOptions: 'nosniff', - referrerPolicy: 'strict-origin-when-cross-origin', - permissionsPolicy: null, - crossOriginOpenerPolicy: 'same-origin', - }, - customResponseHeaders: { - 'some-header': 'some-value', - 'referrer-policy': 'strict-origin', // overrides a header that is defined by securityResponseHeaders - }, - xsrf: { disableProtection: false, allowlist: [allowlistedTestPath] }, - requestId: { - allowFromAnyIp: true, - ipAllowlist: [], - }, - } as any); - } - if (path === 'externalUrl') { - return new BehaviorSubject({ - policy: [], - } as any); - } - if (path === 'csp') { - return new BehaviorSubject({ - strict: false, - disableEmbedding: false, - warnLegacyBrowsers: true, - }); - } - throw new Error(`Unexpected config path: ${path}`); + const configService = createConfigService({ + server: { + name: kibanaName, + securityResponseHeaders: { + // reflects default config + strictTransportSecurity: null, + xContentTypeOptions: 'nosniff', + referrerPolicy: 'strict-origin-when-cross-origin', + permissionsPolicy: null, + crossOriginOpenerPolicy: 'same-origin', + } as any, + customResponseHeaders: { + 'some-header': 'some-value', + 'referrer-policy': 'strict-origin', // overrides a header that is defined by securityResponseHeaders + }, + xsrf: { disableProtection: false, allowlist: [allowlistedTestPath] }, + }, }); server = createHttpServer({ configService }); @@ -321,32 +249,13 @@ describe('core lifecycle handlers', () => { }); }); -describe('core lifecyle handers with restrict internal routes enforced', () => { +describe('core lifecycle handlers with restrict internal routes enforced', () => { let server: HttpService; let innerServer: HttpServerSetup['server']; let router: IRouter; beforeEach(async () => { - const configService = configServiceMock.create(); - configService.atPath.mockImplementation((path) => { - if (path === 'server') { - return new BehaviorSubject(setUpDefaultServerConfig({ enabled: true })); - } - if (path === 'externalUrl') { - return new BehaviorSubject({ - policy: [], - } as any); - } - if (path === 'csp') { - return new BehaviorSubject({ - strict: false, - disableEmbedding: false, - warnLegacyBrowsers: true, - }); - } - - throw new Error(`Unexpected config path: ${path}`); - }); + const configService = createConfigService({ server: { restrictInternalApis: true } }); server = createHttpServer({ configService }); await server.preboot({ context: contextServiceMock.createPrebootContract() }); @@ -391,3 +300,45 @@ describe('core lifecyle handers with restrict internal routes enforced', () => { }); }); }); + +describe('core lifecycle handlers with no strict client version check', () => { + const testRoute = '/version_check/test/route'; + let server: HttpService; + let innerServer: HttpServerSetup['server']; + let router: IRouter; + + beforeEach(async () => { + const configService = createConfigService({ + server: { + versioned: { + strictClientVersionCheck: false, + handlerResolution: 'newest', + }, + }, + }); + server = createHttpServer({ configService }); + await server.preboot({ context: contextServiceMock.createPrebootContract() }); + const serverSetup = await server.setup(setupDeps); + router = serverSetup.createRouter('/'); + router.get({ path: testRoute, validate: false }, (context, req, res) => { + return res.ok({ body: 'ok' }); + }); + innerServer = serverSetup.server; + await server.start(); + }); + + afterEach(async () => { + await server.stop(); + }); + + it('accepts requests that do not include a version header', async () => { + await supertest(innerServer.listener).get(testRoute).expect(200, 'ok'); + }); + + it('accepts requests with any version passed in the version header', async () => { + await supertest(innerServer.listener) + .get(testRoute) + .set(versionHeader, 'what-have-you') + .expect(200, 'ok'); + }); +});