diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts index 690807cc91e27f..3cd0ffb1a29421 100644 --- a/x-pack/legacy/plugins/uptime/index.ts +++ b/x-pack/legacy/plugins/uptime/index.ts @@ -41,7 +41,7 @@ export const uptime = (kibana: any) => plugin(initializerContext).setup( { - route: (arg: any) => server.route(arg), + route: server.newPlatform.setup.core.http.createRouter(), }, { elasticsearch, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts deleted file mode 100644 index 7dff7a02e0dc76..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UMAuthContainer, UMXPackLicenseStatus } from '../adapter_types'; -import { UMXPackAuthAdapter } from '../xpack_auth_adapter'; - -const setupXPack = (licenseStatus: UMXPackLicenseStatus) => ({ - info: { - feature: (pluginId: string) => ({ - registerLicenseCheckResultsGenerator: ( - licenseCheckResultsHandler: (status: UMXPackLicenseStatus) => void - ) => { - licenseCheckResultsHandler(licenseStatus); - }, - }), - }, - status: { - once: (status: string, registerLicenseCheck: () => void) => { - registerLicenseCheck(); - }, - }, -}); - -describe('X-PackAuthAdapter class', () => { - let xpack: UMAuthContainer; - - beforeEach(() => { - xpack = setupXPack({ - license: { - isActive: () => true, - getType: () => 'platinum', - }, - }); - }); - - it('returns the license type', () => { - const adapter = new UMXPackAuthAdapter(xpack); - expect(adapter.getLicenseType()).toBe('platinum'); - expect(adapter.licenseIsActive()).toBe(true); - }); - - it('returns null and false for undefined license values', () => { - xpack = setupXPack({ - license: { - getType: () => undefined, - isActive: () => undefined, - }, - }); - const adapter = new UMXPackAuthAdapter(xpack); - expect(adapter.licenseIsActive()).toBe(false); - expect(adapter.getLicenseType()).toBeNull(); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts deleted file mode 100644 index 016e623d7745d0..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export interface UMAuthContainer { - info: { - feature: ( - pluginId: string - ) => { - registerLicenseCheckResultsGenerator: ( - licenseCheckResultsHandler: (info: UMXPackLicenseStatus) => void - ) => void; - }; - }; - status: { - once: (status: string, registerLicenseCheck: () => void) => void; - }; -} - -export interface UMXPackLicenseStatus { - license: { - isActive: () => boolean | undefined; - getType: () => string | undefined; - }; -} - -export interface UMAuthAdapter { - getLicenseType(): string | null; - licenseIsActive(): boolean; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts deleted file mode 100644 index baa31ef752daa4..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { UMAuthAdapter, UMAuthContainer } from './adapter_types'; -export { UMXPackAuthAdapter } from './xpack_auth_adapter'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts deleted file mode 100644 index 3393cfd5fa758d..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { PLUGIN } from '../../../../common/constants'; -import { UMAuthAdapter, UMAuthContainer, UMXPackLicenseStatus } from './adapter_types'; - -// look at index-management for guidance, subscribe to licensecheckerresultsgenerator -// then check the license status -export class UMXPackAuthAdapter implements UMAuthAdapter { - private xpackLicenseStatus: { - isActive: boolean | undefined | null; - licenseType: string | undefined | null; - }; - - constructor(private readonly xpack: UMAuthContainer) { - this.xpack = xpack; - this.xpackLicenseStatus = { - isActive: null, - licenseType: null, - }; - this.xpack.status.once('green', this.registerLicenseCheck); - } - - public getLicenseType = (): string | null => this.xpackLicenseStatus.licenseType || null; - - public licenseIsActive = (): boolean => this.xpackLicenseStatus.isActive || false; - - private registerLicenseCheck = (): void => - this.xpack.info.feature(PLUGIN.ID).registerLicenseCheckResultsGenerator(this.updateLicenseInfo); - - private updateLicenseInfo = (xpackLicenseStatus: UMXPackLicenseStatus): void => { - this.xpackLicenseStatus = { - isActive: xpackLicenseStatus.license.isActive(), - licenseType: xpackLicenseStatus.license.getType(), - }; - }; -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index df2723283f88ce..e67f4fa59531c8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -4,35 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GraphQLOptions } from 'apollo-server-core'; import { GraphQLSchema } from 'graphql'; -import { Lifecycle, ResponseToolkit } from 'hapi'; -import { RouteOptions } from 'hapi'; -import { SavedObjectsLegacyService } from 'src/core/server'; +import { SavedObjectsLegacyService, RequestHandler, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; - -export interface UMFrameworkRequest { - user: string; - headers: Record; - payload: Record; - params: Record; - query: Record; -} - -export type UMFrameworkResponse = Lifecycle.ReturnValue; +import { ObjectType } from '@kbn/config-schema'; +import { UMRouteDefinition } from '../../../rest_api'; export interface UMFrameworkRouteOptions< - RouteRequest extends UMFrameworkRequest, - RouteResponse extends UMFrameworkResponse + P extends ObjectType, + Q extends ObjectType, + B extends ObjectType > { path: string; method: string; - handler: (req: Request, h: ResponseToolkit) => any; + handler: RequestHandler; config?: any; + validate: any; } export interface UptimeCoreSetup { - route: any; + route: IRouter; } export interface UptimeCorePlugins { @@ -42,24 +33,8 @@ export interface UptimeCorePlugins { xpack: any; } -export type UMFrameworkRouteHandler = ( - request: UMFrameworkRequest, - h: ResponseToolkit -) => void; - -export type HapiOptionsFunction = (req: Request) => GraphQLOptions | Promise; - -export interface UMHapiGraphQLPluginOptions { - path: string; - vhost?: string; - route?: RouteOptions; - graphQLOptions: GraphQLOptions | HapiOptionsFunction; -} - export interface UMBackendFrameworkAdapter { - registerRoute( - route: UMFrameworkRouteOptions - ): void; + registerRoute(route: UMRouteDefinition): void; registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void; getSavedObjectsClient(): any; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index c166530ca64287..a46a7e11bd7382 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -5,16 +5,11 @@ */ import { GraphQLSchema } from 'graphql'; -import { Request, ResponseToolkit } from 'hapi'; +import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; -import { - UMBackendFrameworkAdapter, - UMFrameworkRequest, - UMFrameworkResponse, - UMFrameworkRouteOptions, -} from './adapter_types'; -import { DEFAULT_GRAPHQL_PATH } from '../../../graphql'; +import { UMBackendFrameworkAdapter } from './adapter_types'; +import { UMRouteDefinition } from '../../../rest_api'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor( @@ -25,11 +20,22 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte this.plugins = plugins; } - public registerRoute< - RouteRequest extends UMFrameworkRequest, - RouteResponse extends UMFrameworkResponse - >(route: UMFrameworkRouteOptions) { - this.server.route(route); + public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) { + const routeDefinition = { + path, + validate, + options, + }; + switch (method) { + case 'GET': + this.server.route.get(routeDefinition, handler); + break; + case 'POST': + this.server.route.post(routeDefinition, handler); + break; + default: + throw new Error(`Handler for method ${method} is not defined`); + } } public registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void { @@ -43,37 +49,47 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte tags: ['access:uptime'], }, }; - this.server.route({ - options: options.route, - handler: async (request: Request, h: ResponseToolkit) => { + this.server.route.post( + { + path: routePath, + validate: { + body: kbnSchema.object({ + operationName: kbnSchema.nullable(kbnSchema.string()), + query: kbnSchema.string(), + variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), + }), + }, + options: { + tags: ['access:uptime'], + }, + }, + async (context, request, resp): Promise => { try { - const { method } = request; - const query = - method === 'post' - ? (request.payload as Record) - : (request.query as Record); + const query = request.body as Record; const graphQLResponse = await runHttpQuery([request], { - method: method.toUpperCase(), + method: 'POST', options: options.graphQLOptions, query, }); - return h.response(graphQLResponse).type('application/json'); + return resp.ok({ + body: graphQLResponse, + headers: { + 'content-type': 'application/json', + }, + }); } catch (error) { if (error.isGraphQLError === true) { - return h - .response(error.message) - .code(error.statusCode) - .type('application/json'); + return resp.internalError({ + body: { message: error.message }, + headers: { 'content-type': 'application/json' }, + }); } - return h.response(error).type('application/json'); + return resp.internalError(); } - }, - method: ['get', 'post'], - path: options.path || DEFAULT_GRAPHQL_PATH, - vhost: undefined, - }); + } + ); } public getSavedObjectsClient() { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts index a09f80ae3b40aa..2a88df91adc29f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './auth'; export * from './database'; export * from './framework'; export * from './monitor_states'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts index 1c9999fbf64516..a7c370e03490b1 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -4,26 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMXPackAuthAdapter } from '../adapters/auth'; import { UMKibanaDatabaseAdapter } from '../adapters/database/kibana_database_adapter'; import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; import { ElasticsearchPingsAdapter } from '../adapters/pings'; -import { UMAuthDomain } from '../domains'; +import { licenseCheck } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; import { ElasticsearchMonitorStatesAdapter } from '../adapters/monitor_states'; import { UMKibanaSavedObjectsAdapter } from '../adapters/saved_objects/kibana_saved_objects_adapter'; import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters/framework'; export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UMServerLibs { - const { elasticsearch, savedObjects, xpack } = plugins; + const { elasticsearch, savedObjects } = plugins; const framework = new UMKibanaBackendFrameworkAdapter(server, plugins); const database = new UMKibanaDatabaseAdapter(elasticsearch); - const authDomain = new UMAuthDomain(new UMXPackAuthAdapter(xpack), {}); - const domainLibs: UMDomainLibs = { - auth: authDomain, + license: licenseCheck, monitors: new ElasticsearchMonitorsAdapter(database), monitorStates: new ElasticsearchMonitorStatesAdapter(database), pings: new ElasticsearchPingsAdapter(database), diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap deleted file mode 100644 index 3a959d5af7933b..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Auth domain lib throws for inactive license 1`] = `"this.adapter.getLicenseType is not a function"`; - -exports[`Auth domain lib throws for null license 1`] = `"Missing license information"`; - -exports[`Auth domain lib throws for unsupported license type 1`] = `"License not supported"`; - -exports[`Auth domain lib throws if request is not authenticated 1`] = `"Missing authentication"`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap new file mode 100644 index 00000000000000..ab791cbd243f8f --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`license check returns result for a valid license 1`] = ` +Object { + "statusCode": 200, +} +`; + +exports[`license check throws for inactive license 1`] = ` +Object { + "message": "License not active", + "statusCode": 403, +} +`; + +exports[`license check throws for null license 1`] = ` +Object { + "message": "Missing license information", + "statusCode": 400, +} +`; + +exports[`license check throws for unsupported license type 1`] = ` +Object { + "message": "License not supported", + "statusCode": 401, +} +`; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts deleted file mode 100644 index 5d9de84a6ebbc0..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UMAuthDomain } from '../auth'; - -describe('Auth domain lib', () => { - let domain: UMAuthDomain; - let mockAdapter: any; - let mockGetLicenseType: jest.Mock; - let mockLicenseIsActive: jest.Mock; - - beforeEach(() => { - mockAdapter = jest.fn(); - mockGetLicenseType = jest.fn(); - mockLicenseIsActive = jest.fn(); - domain = new UMAuthDomain(mockAdapter, {}); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('throws for null license', () => { - mockGetLicenseType.mockReturnValue(null); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); - }); - - it('throws for unsupported license type', () => { - mockGetLicenseType.mockReturnValue('oss'); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); - }); - - it('throws for inactive license', () => { - mockLicenseIsActive.mockReturnValue(false); - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); - }); - - it('throws if request is not authenticated', () => { - mockGetLicenseType.mockReturnValue('basic'); - mockLicenseIsActive.mockReturnValue(true); - mockAdapter.getLicenseType = mockGetLicenseType; - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); - }); - - it('accepts request if authenticated', () => { - mockGetLicenseType.mockReturnValue('basic'); - mockLicenseIsActive.mockReturnValue(true); - mockAdapter.getLicenseType = mockGetLicenseType; - mockAdapter.licenseIsActive = mockLicenseIsActive; - expect(domain.requestIsValid({ auth: { isAuthenticated: true } })).toEqual(true); - }); -}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts new file mode 100644 index 00000000000000..b26cb99cf9b6b2 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ILicense } from '../../../../../../../plugins/licensing/server'; +import { licenseCheck } from '../license'; + +describe('license check', () => { + let mockLicense: Pick; + + it('throws for null license', () => { + expect(licenseCheck(null)).toMatchSnapshot(); + }); + + it('throws for unsupported license type', () => { + mockLicense = { + isOneOf: jest.fn().mockReturnValue(false), + isActive: false, + }; + expect(licenseCheck(mockLicense)).toMatchSnapshot(); + }); + + it('throws for inactive license', () => { + mockLicense = { + isOneOf: jest.fn().mockReturnValue(true), + isActive: false, + }; + expect(licenseCheck(mockLicense)).toMatchSnapshot(); + }); + + it('returns result for a valid license', () => { + mockLicense = { + isOneOf: jest.fn().mockReturnValue(true), + isActive: true, + }; + expect(licenseCheck(mockLicense)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts deleted file mode 100644 index 62d17f121779ff..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; -import { get } from 'lodash'; -import { UMAuthAdapter } from '../adapters/auth/adapter_types'; - -const supportedLicenses = ['basic', 'standard', 'gold', 'platinum', 'trial']; - -export class UMAuthDomain { - constructor(private readonly adapter: UMAuthAdapter, libs: {}) { - this.adapter = adapter; - } - - public requestIsValid(request: any): boolean { - const license = this.adapter.getLicenseType(); - if (license === null) { - throw Boom.badRequest('Missing license information'); - } - if (!supportedLicenses.some(licenseType => licenseType === license)) { - throw Boom.forbidden('License not supported'); - } - if (this.adapter.licenseIsActive() === false) { - throw Boom.forbidden('License not active'); - } - - return this.checkRequest(request); - } - - private checkRequest(request: any): boolean { - const authenticated = get(request, 'auth.isAuthenticated', null); - if (authenticated === null) { - throw Boom.forbidden('Missing authentication'); - } - return authenticated; - } -} diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts index 5be591708fab12..6a35b9b41020bb 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { UMAuthDomain } from './auth'; +export { licenseCheck, UMLicenseCheck } from './license'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts new file mode 100644 index 00000000000000..9c52667aeeab49 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ILicense } from '../../../../../../plugins/licensing/server'; + +export interface UMLicenseStatusResponse { + statusCode: number; + message?: string; +} +export type UMLicenseCheck = ( + license: Pick | null +) => UMLicenseStatusResponse; + +export const licenseCheck: UMLicenseCheck = license => { + if (license === null) { + return { + message: 'Missing license information', + statusCode: 400, + }; + } + if (!license.isOneOf(['basic', 'standard', 'gold', 'platinum', 'trial'])) { + return { + message: 'License not supported', + statusCode: 401, + }; + } + if (license.isActive === false) { + return { + message: 'License not active', + statusCode: 403, + }; + } + return { + statusCode: 200, + }; +}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index 217195488677e9..e68a6dd18ef5f2 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/lib.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMAuthDomain } from './domains'; import { DatabaseAdapter, UMBackendFrameworkAdapter, @@ -13,9 +12,10 @@ import { UMPingsAdapter, UMSavedObjectsAdapter, } from './adapters'; +import { UMLicenseCheck } from './domains'; export interface UMDomainLibs { - auth: UMAuthDomain; + license: UMLicenseCheck; monitors: UMMonitorsAdapter; monitorStates: UMMonitorStatesAdapter; pings: UMPingsAdapter; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts deleted file mode 100644 index 242d9bf73a946c..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { createIsValidRoute } from './is_valid'; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts b/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts deleted file mode 100644 index 15024f7c5f4978..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UMServerLibs } from '../../lib/lib'; - -export const createIsValidRoute = (libs: UMServerLibs) => ({ - method: 'GET', - path: '/api/uptime/is_valid', - handler: async (request: any): Promise => await libs.auth.requestIsValid(request), - options: { - tags: ['access:uptime'], - }, -}); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 727ed78624a489..a1976ef046e8ee 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -4,26 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; +import { RequestHandler } from 'kibana/server'; +import { ObjectType } from '@kbn/config-schema'; import { UMServerLibs } from '../lib/lib'; -import { UMRestApiRouteCreator, UMServerRoute } from './types'; +import { UMRestApiRouteCreator, UMRouteDefinition } from './types'; export const createRouteWithAuth = ( libs: UMServerLibs, routeCreator: UMRestApiRouteCreator -): UMServerRoute => { +): UMRouteDefinition => { const restRoute = routeCreator(libs); - const { handler, method, path, options } = restRoute; - const authHandler = async (request: any, h: any) => { - if (libs.auth.requestIsValid(request)) { - return await handler(request, h); + const { handler, method, path, options, ...rest } = restRoute; + const authHandler: RequestHandler = async ( + context, + request, + response + ) => { + if (libs.license(context.licensing.license)) { + return await handler(context, request, response); } - return Boom.badRequest(); + return response.badRequest(); }; return { method, path, options, handler: authHandler, + ...rest, }; }; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 889f8a820b2f38..2810982fb0c6c7 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { createIsValidRoute } from './auth'; import { createGetAllRoute } from './pings'; import { createGetIndexPatternRoute } from './index_pattern'; import { createLogMonitorPageRoute, createLogOverviewPageRoute } from './telemetry'; @@ -19,7 +18,6 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetIndexPatternRoute, createGetMonitorDetailsRoute, createGetSnapshotCount, - createIsValidRoute, createLogMonitorPageRoute, createLogOverviewPageRoute, ]; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts index 3cdd71fda3e43b..55f0af57ed847e 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts @@ -5,12 +5,24 @@ */ import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetIndexPatternRoute = (libs: UMServerLibs) => ({ +export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/index_pattern', - tags: ['access:uptime'], - handler: async (): Promise => { - return await libs.savedObjects.getUptimeIndexPattern(); + validate: false, + options: { + tags: ['access:uptime'], + }, + handler: async (_context, _request, response): Promise => { + try { + return response.ok({ + body: { + ...(await libs.savedObjects.getUptimeIndexPattern()), + }, + }); + } catch (e) { + return response.internalError({ body: { message: e.message } }); + } }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts index 1440b55c1c1378..00860248ff1538 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -3,23 +3,27 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; + +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { MonitorDetails } from '../../../common/runtime_types/monitor/monitor_details'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetMonitorDetailsRoute = (libs: UMServerLibs) => ({ +export const createGetMonitorDetailsRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/monitor/details', + validate: { + query: schema.object({ + monitorId: schema.maybe(schema.string()), + }), + }, options: { - validate: { - query: Joi.object({ - monitorId: Joi.string(), - }), - }, tags: ['access:uptime'], }, - handler: async (request: any): Promise => { + handler: async (_context, request, response): Promise => { const { monitorId } = request.query; - return await libs.monitors.getMonitorDetails(request, monitorId); + + return response.ok({ + body: { ...(await libs.monitors.getMonitorDetails(request, monitorId)) }, + }); }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index 70f9a5c0611912..e2bdbca9fbfa07 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts @@ -4,36 +4,45 @@ * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; -import { PingResults } from '../../../common/graphql/types'; +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetAllRoute = (libs: UMServerLibs) => ({ +export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/pings', + validate: { + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + location: schema.maybe(schema.string()), + monitorId: schema.maybe(schema.string()), + size: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + status: schema.maybe(schema.string()), + }), + }, options: { - validate: { - query: Joi.object({ - dateRangeStart: Joi.number().required(), - dateRangeEnd: Joi.number().required(), - monitorId: Joi.string(), - size: Joi.number(), - sort: Joi.string(), - status: Joi.string(), - }), - }, tags: ['access:uptime'], }, - handler: async (request: any): Promise => { - const { size, sort, dateRangeStart, dateRangeEnd, monitorId, status } = request.query; - return await libs.pings.getAll( + handler: async (_context, request, response): Promise => { + const { size, sort, dateRangeStart, dateRangeEnd, location, monitorId, status } = request.query; + + const result = await libs.pings.getAll( request, dateRangeStart, dateRangeEnd, monitorId, status, sort, - size + size, + location ); + + return response.ok({ + body: { + ...result, + }, + }); }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index ddca622005d637..9b2b26f52699e5 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -4,32 +4,37 @@ * you may not use this file except in compliance with the Elastic License. */ -import Joi from 'joi'; +import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; -import { Snapshot } from '../../../common/runtime_types'; +import { UMRestApiRouteCreator } from '../types'; -export const createGetSnapshotCount = (libs: UMServerLibs) => ({ +export const createGetSnapshotCount: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/snapshot/count', + validate: { + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + filters: schema.maybe(schema.string()), + statusFilter: schema.maybe(schema.string()), + }), + }, options: { - validate: { - query: Joi.object({ - dateRangeStart: Joi.string().required(), - dateRangeEnd: Joi.string().required(), - filters: Joi.string(), - statusFilter: Joi.string(), - }), - }, tags: ['access:uptime'], }, - handler: async (request: any): Promise => { + handler: async (_context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; - return await libs.monitorStates.getSnapshotCount( + const result = await libs.monitorStates.getSnapshotCount( request, dateRangeStart, dateRangeEnd, filters, statusFilter ); + return response.ok({ + body: { + ...result, + }, + }); }, }); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts index 34c689be6e5215..f3e926493143b8 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts @@ -5,13 +5,15 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; +import { UMRestApiRouteCreator } from '../types'; -export const createLogMonitorPageRoute = () => ({ +export const createLogMonitorPageRoute: UMRestApiRouteCreator = () => ({ method: 'POST', path: '/api/uptime/logMonitor', - handler: async (request: any, h: any): Promise => { + validate: false, + handler: async (_context, _request, response): Promise => { await KibanaTelemetryAdapter.countMonitor(); - return h.response().code(200); + return response.ok(); }, options: { tags: ['access:uptime'], diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts index bd7e7d85637e7d..277ef2235fb69c 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts @@ -5,13 +5,15 @@ */ import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; +import { UMRestApiRouteCreator } from '../types'; -export const createLogOverviewPageRoute = () => ({ +export const createLogOverviewPageRoute: UMRestApiRouteCreator = () => ({ method: 'POST', path: '/api/uptime/logOverview', - handler: async (request: any, h: any): Promise => { + validate: false, + handler: async (_context, _request, response): Promise => { await KibanaTelemetryAdapter.countOverview(); - return h.response().code(200); + return response.ok(); }, options: { tags: ['access:uptime'], diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts index acbc50828f8745..b4d7e438f51be3 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -4,13 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ObjectType } from '@kbn/config-schema'; +import { RequestHandler, RouteConfig, RouteMethod } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; - path: string; - options?: any; - handler: (request: any, h?: any) => any; + handler: RequestHandler; } -export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMServerRoute; +export type UMRouteDefinition = UMServerRoute & + RouteConfig; + +export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; diff --git a/x-pack/test/api_integration/apis/uptime/feature_controls.ts b/x-pack/test/api_integration/apis/uptime/feature_controls.ts index a0161c0beb945b..adbfacb014e9f9 100644 --- a/x-pack/test/api_integration/apis/uptime/feature_controls.ts +++ b/x-pack/test/api_integration/apis/uptime/feature_controls.ts @@ -46,17 +46,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) .catch((error: any) => ({ error, response: undefined })); }; - const executeIsValidRequest = async (username: string, password: string, spaceId?: string) => { - const basePath = spaceId ? `/s/${spaceId}` : ''; - - return await supertest - .get(`${basePath}/api/uptime/is_valid`) - .auth(username, password) - .set('kbn-xsrf', 'foo') - .then((response: any) => ({ error: undefined, response })) - .catch((error: any) => ({ error, response: undefined })); - }; - const executePingsRequest = async (username: string, password: string, spaceId?: string) => { const basePath = spaceId ? `/s/${spaceId}` : ''; @@ -96,9 +85,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); } finally { @@ -138,9 +124,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expectResponse(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expectResponse(isValidResult); - const pingsResult = await executePingsRequest(username, password); expectResponse(pingsResult); } finally { @@ -183,9 +166,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); } finally { @@ -255,9 +235,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password, space1Id); expectResponse(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password, space1Id); - expectResponse(isValidResult); - const pingsResult = await executePingsRequest(username, password, space1Id); expectResponse(pingsResult); }); @@ -266,9 +243,6 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const graphQLResult = await executeGraphQLQuery(username, password); expect404(graphQLResult); - const isValidResult = await executeIsValidRequest(username, password); - expect404(isValidResult); - const pingsResult = await executePingsRequest(username, password); expect404(pingsResult); });