From 793b42476b6f85d8934d5669cef9533b702686ab Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 19 Nov 2019 17:59:33 -0500 Subject: [PATCH 01/13] Move a REST endpoint and the GQL endpoint to NP routing. --- x-pack/legacy/plugins/uptime/index.ts | 2 +- .../lib/adapters/framework/adapter_types.ts | 15 ++-- .../framework/kibana_framework_adapter.ts | 72 ++++++++++++------ .../server/rest_api/create_route_with_auth.ts | 18 ++--- .../plugins/uptime/server/rest_api/index.ts | 2 - .../uptime/server/rest_api/pings/get_all.ts | 75 ++++++++++++------- .../rest_api/snapshot/get_snapshot_count.ts | 39 +++++----- .../plugins/uptime/server/rest_api/types.ts | 4 +- 8 files changed, 137 insertions(+), 90 deletions(-) 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/framework/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index df2723283f88ce..10fa9b836028af 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 @@ -8,8 +8,9 @@ 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, RouteMethod, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { ObjectType } from '@kbn/config-schema'; export interface UMFrameworkRequest { user: string; @@ -22,17 +23,19 @@ export interface UMFrameworkRequest { export type UMFrameworkResponse = Lifecycle.ReturnValue; 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 { @@ -58,7 +61,7 @@ export interface UMHapiGraphQLPluginOptions { export interface UMBackendFrameworkAdapter { registerRoute( - route: UMFrameworkRouteOptions + route: UMFrameworkRouteOptions ): 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..01cf84a3eb5208 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,8 +5,9 @@ */ import { GraphQLSchema } from 'graphql'; -import { Request, ResponseToolkit } from 'hapi'; +import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; +import { ObjectType } from '@kbn/config-schema'; import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; import { UMBackendFrameworkAdapter, @@ -14,7 +15,6 @@ import { UMFrameworkResponse, UMFrameworkRouteOptions, } from './adapter_types'; -import { DEFAULT_GRAPHQL_PATH } from '../../../graphql'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor( @@ -28,8 +28,25 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte public registerRoute< RouteRequest extends UMFrameworkRequest, RouteResponse extends UMFrameworkResponse - >(route: UMFrameworkRouteOptions) { - this.server.route(route); + >({ + handler, + method, + path, + validate, + }: UMFrameworkRouteOptions) { + switch (method) { + case 'GET': + this.server.route.get( + { + path, + validate, + }, + handler + ); + break; + default: + throw new Error(`Handler for method ${method} is not defined`); + } } public registerGraphQLEndpoint(routePath: string, schema: GraphQLSchema): void { @@ -43,37 +60,44 @@ 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.string(), + query: kbnSchema.string(), + variables: kbnSchema.recordOf(kbnSchema.string(), kbnSchema.any()), + }), + }, + }, + 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/rest_api/create_route_with_auth.ts b/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts index 727ed78624a489..eb3932c367709c 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,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; import { UMServerLibs } from '../lib/lib'; import { UMRestApiRouteCreator, UMServerRoute } from './types'; @@ -13,17 +12,18 @@ export const createRouteWithAuth = ( routeCreator: UMRestApiRouteCreator ): UMServerRoute => { 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); - } - return Boom.badRequest(); - }; + const { handler, method, path, options, ...rest } = restRoute; + // const authHandler = async (request: any, h: any) => { + // if (libs.auth.requestIsValid(request)) { + // return await handler(request, h); + // } + // return Boom.badRequest(); + // }; return { method, path, options, - handler: authHandler, + 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/pings/get_all.ts b/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_all.ts index 70f9a5c0611912..cf0a4cec44e92a 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,55 @@ * 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) => ({ - method: 'GET', - path: '/api/uptime/pings', - options: { +export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => { + return { + method: 'GET', + path: '/api/uptime/pings', validate: { - query: Joi.object({ - dateRangeStart: Joi.number().required(), - dateRangeEnd: Joi.number().required(), - monitorId: Joi.string(), - size: Joi.number(), - sort: Joi.string(), - status: Joi.string(), + 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()), }), }, - tags: ['access:uptime'], - }, - handler: async (request: any): Promise => { - const { size, sort, dateRangeStart, dateRangeEnd, monitorId, status } = request.query; - return await libs.pings.getAll( - request, - dateRangeStart, - dateRangeEnd, - monitorId, - status, - sort, - size - ); - }, -}); + options: { + tags: ['access:uptime'], + }, + handler: async (context, request, resp): Promise => { + const { + size, + sort, + dateRangeStart, + dateRangeEnd, + location, + monitorId, + status, + } = request.query; + + const result = await libs.pings.getAll( + request, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location + ); + + return resp.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..5f5ce03d2cd7f3 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 @@ -7,29 +7,30 @@ import Joi from 'joi'; 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', - options: { - validate: { - query: Joi.object({ - dateRangeStart: Joi.string().required(), - dateRangeEnd: Joi.string().required(), - filters: Joi.string(), - statusFilter: Joi.string(), - }), - }, - tags: ['access:uptime'], + validate: { + query: Joi.object({ + dateRangeStart: Joi.string().required(), + dateRangeEnd: Joi.string().required(), + filters: Joi.string(), + statusFilter: Joi.string(), + }), }, - handler: async (request: any): Promise => { + tags: ['access:uptime'], + handler: async (_context: any, request: any, response: any): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; - return await libs.monitorStates.getSnapshotCount( - request, - dateRangeStart, - dateRangeEnd, - filters, - statusFilter - ); + return response.ok({ + body: await libs.monitorStates.getSnapshotCount( + request, + dateRangeStart, + dateRangeEnd, + filters, + statusFilter + ), + }); }, }); 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..68672b9651386c 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,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ObjectType } from '@kbn/config-schema'; +import { RequestHandler } 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; From b53f41541c3955812898ca11221498247be4060a Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:31:40 -0500 Subject: [PATCH 02/13] Delete obsolete REST endpoint. --- .../plugins/uptime/server/rest_api/auth/index.ts | 7 ------- .../uptime/server/rest_api/auth/is_valid.ts | 16 ---------------- 2 files changed, 23 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/rest_api/auth/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/rest_api/auth/is_valid.ts 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'], - }, -}); From 1dfe5bb256716997a247bff2cb201dd7647857e8 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 12:35:15 -0500 Subject: [PATCH 03/13] Update remaining REST routes to work with NP router. --- .../auth/__tests__/xpack_auth_adapter.test.ts | 56 ------------- .../server/lib/adapters/auth/adapter_types.ts | 32 -------- .../uptime/server/lib/adapters/auth/index.ts | 8 -- .../lib/adapters/auth/xpack_auth_adapter.ts | 40 --------- .../framework/kibana_framework_adapter.ts | 9 ++ .../uptime/server/lib/compose/kibana.ts | 7 +- .../plugins/uptime/server/lib/domains/auth.ts | 39 +++------ .../uptime/server/lib/domains/index.ts | 2 +- .../legacy/plugins/uptime/server/lib/lib.ts | 4 +- .../server/rest_api/create_route_with_auth.ts | 24 ++++-- .../plugins/uptime/server/rest_api/index.ts | 1 + .../index_pattern/get_index_pattern.ts | 18 +++- .../uptime/server/rest_api/pings/get_all.ts | 82 ++++++++----------- .../rest_api/telemetry/log_monitor_page.ts | 8 +- .../rest_api/telemetry/log_overview_page.ts | 8 +- .../plugins/uptime/server/rest_api/types.ts | 8 +- 16 files changed, 105 insertions(+), 241 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/__tests__/xpack_auth_adapter.test.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/adapter_types.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/adapters/auth/xpack_auth_adapter.ts 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/kibana_framework_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 01cf84a3eb5208..4242522004d74e 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 @@ -44,6 +44,15 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte handler ); break; + case 'POST': + this.server.route.post( + { + path, + validate, + }, + handler + ); + break; default: throw new Error(`Handler for method ${method} is not defined`); } 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..7027a30bfce179 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -4,24 +4,21 @@ * 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 { authDomain } 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, monitors: new ElasticsearchMonitorsAdapter(database), diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts index 62d17f121779ff..e7edc6913ab072 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts @@ -5,36 +5,19 @@ */ import Boom from 'boom'; -import { get } from 'lodash'; -import { UMAuthAdapter } from '../adapters/auth/adapter_types'; +import { RequestHandlerContext } from 'kibana/server'; -const supportedLicenses = ['basic', 'standard', 'gold', 'platinum', 'trial']; +export type UMLicenseCheck = (context: RequestHandlerContext) => boolean; -export class UMAuthDomain { - constructor(private readonly adapter: UMAuthAdapter, libs: {}) { - this.adapter = adapter; +export const authDomain: UMLicenseCheck = ({ licensing: { license } }) => { + if (license === null) { + throw Boom.badRequest('Missing license information'); } - - 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); + if (!license.isOneOf(['basic', 'standard', 'gold', 'platinum', 'trial'])) { + throw Boom.forbidden('License not supported'); } - - private checkRequest(request: any): boolean { - const authenticated = get(request, 'auth.isAuthenticated', null); - if (authenticated === null) { - throw Boom.forbidden('Missing authentication'); - } - return authenticated; + if (license.isActive === false) { + throw Boom.forbidden('License not active'); } -} + return true; +}; 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..b2d7503a6a192c 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 { authDomain, UMLicenseCheck } from './auth'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index 217195488677e9..9a6a8217d12789 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; + auth: UMLicenseCheck; monitors: UMMonitorsAdapter; monitorStates: UMMonitorStatesAdapter; pings: UMPingsAdapter; 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 eb3932c367709c..26ae3b454cfb89 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 { 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, ...rest } = restRoute; - // const authHandler = async (request: any, h: any) => { - // if (libs.auth.requestIsValid(request)) { - // return await handler(request, h); - // } - // return Boom.badRequest(); - // }; + const authHandler: RequestHandler = async ( + context, + request, + response + ) => { + if (libs.auth(context)) { + return await handler(context, request, response); + } + return response.badRequest(); + }; return { method, path, options, - handler, // : authHandler, + 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 2810982fb0c6c7..9d1d8c38ad9daf 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,4 +20,5 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, + createGetMonitorDetailsRoute, ]; 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..b78fb8376cf6bc 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,22 @@ */ 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({ + ...(await libs.savedObjects.getUptimeIndexPattern()), + }); + } catch (e) { + return response.internalError({ body: { message: e.message } }); + } }, }); 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 cf0a4cec44e92a..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 @@ -8,51 +8,41 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteCreator } from '../types'; -export const createGetAllRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => { - return { - 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: { - tags: ['access:uptime'], - }, - handler: async (context, request, resp): Promise => { - const { - size, - sort, - dateRangeStart, - dateRangeEnd, - location, - monitorId, - status, - } = request.query; +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: { + tags: ['access:uptime'], + }, + 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, - location - ); + const result = await libs.pings.getAll( + request, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location + ); - return resp.ok({ - body: { - ...result, - }, - }); - }, - }; -}; + 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 68672b9651386c..d9a675b3c4cbac 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -5,14 +5,14 @@ */ import { ObjectType } from '@kbn/config-schema'; -import { RequestHandler } from 'kibana/server'; +import { RequestHandler, RouteConfig } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { method: string; - path: string; - options?: any; handler: RequestHandler; } -export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMServerRoute; +export type UMRouteDefinition = UMServerRoute & RouteConfig; + +export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From 2129e5013bc4bf68505c5f2c9895b2cbe918a7f5 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 20 Nov 2019 23:12:54 -0500 Subject: [PATCH 04/13] Remove obsolete code, update some unit tests. --- .../lib/adapters/framework/adapter_types.ts | 34 +--------- .../framework/kibana_framework_adapter.ts | 19 +----- .../uptime/server/lib/adapters/index.ts | 1 - .../__tests__/__snapshots__/auth.test.ts.snap | 8 +-- .../server/lib/domains/__tests__/auth.test.ts | 62 +++++++------------ .../plugins/uptime/server/rest_api/types.ts | 4 +- 6 files changed, 33 insertions(+), 95 deletions(-) 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 10fa9b836028af..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,23 +4,11 @@ * 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, RequestHandler, RouteMethod, IRouter } from 'src/core/server'; +import { SavedObjectsLegacyService, RequestHandler, IRouter } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { ObjectType } from '@kbn/config-schema'; - -export interface UMFrameworkRequest { - user: string; - headers: Record; - payload: Record; - params: Record; - query: Record; -} - -export type UMFrameworkResponse = Lifecycle.ReturnValue; +import { UMRouteDefinition } from '../../../rest_api'; export interface UMFrameworkRouteOptions< P extends ObjectType, @@ -45,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 4242522004d74e..915d795f4855d8 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 @@ -7,14 +7,9 @@ import { GraphQLSchema } from 'graphql'; import { schema as kbnSchema } from '@kbn/config-schema'; import { runHttpQuery } from 'apollo-server-core'; -import { ObjectType } from '@kbn/config-schema'; import { UptimeCorePlugins, UptimeCoreSetup } from './adapter_types'; -import { - UMBackendFrameworkAdapter, - UMFrameworkRequest, - UMFrameworkResponse, - UMFrameworkRouteOptions, -} from './adapter_types'; +import { UMBackendFrameworkAdapter } from './adapter_types'; +import { UMRouteDefinition } from '../../../rest_api'; export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapter { constructor( @@ -25,15 +20,7 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte this.plugins = plugins; } - public registerRoute< - RouteRequest extends UMFrameworkRequest, - RouteResponse extends UMFrameworkResponse - >({ - handler, - method, - path, - validate, - }: UMFrameworkRouteOptions) { + public registerRoute({ handler, method, path, validate }: UMRouteDefinition) { switch (method) { case 'GET': this.server.route.get( 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/domains/__tests__/__snapshots__/auth.test.ts.snap b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap index 3a959d5af7933b..d7454d0d9066c1 100644 --- 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 @@ -1,9 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Auth domain lib throws for inactive license 1`] = `"this.adapter.getLicenseType is not a function"`; +exports[`authDomain throws for inactive license 1`] = `"License not active"`; -exports[`Auth domain lib throws for null license 1`] = `"Missing license information"`; +exports[`authDomain 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"`; +exports[`authDomain throws for unsupported license type 1`] = `"License not supported"`; 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 index 5d9de84a6ebbc0..4b6b3130091881 100644 --- 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 @@ -4,56 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMAuthDomain } from '../auth'; +import { authDomain } from '../auth'; +import { RequestHandlerContext } from 'kibana/server'; -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(); - }); +describe('authDomain', () => { + let mockContext: RequestHandlerContext; + const isOneOf = jest.fn(); it('throws for null license', () => { - mockGetLicenseType.mockReturnValue(null); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); + // @ts-ignore there's a null check in this function + mockContext = { licensing: { license: null } }; + expect(() => authDomain(mockContext)).toThrowErrorMatchingSnapshot(); }); it('throws for unsupported license type', () => { - mockGetLicenseType.mockReturnValue('oss'); - mockAdapter.getLicenseType = mockGetLicenseType; - expect(() => domain.requestIsValid({})).toThrowErrorMatchingSnapshot(); + isOneOf.mockReturnValue(false); + expect(() => + // @ts-ignore it needs to throw if the license is not supported + authDomain({ licensing: { license: { isOneOf } } }) + ).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(); + isOneOf.mockReturnValue(true); + expect(() => + // @ts-ignore it needs to throw if !isActive + authDomain({ licensing: { license: { isActive: false, isOneOf } } }) + ).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); + it('returns true for a valid license', () => { + isOneOf.mockReturnValue(true); + // @ts-ignore license type needs to be non-null + expect(authDomain({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); }); }); 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 d9a675b3c4cbac..4991cda99aff75 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -5,7 +5,7 @@ */ import { ObjectType } from '@kbn/config-schema'; -import { RequestHandler, RouteConfig } from 'kibana/server'; +import { RequestHandler, RouteConfig, RouteMethod } from 'kibana/server'; import { UMServerLibs } from '../lib/lib'; export interface UMServerRoute { @@ -13,6 +13,6 @@ export interface UMServerRoute { handler: RequestHandler; } -export type UMRouteDefinition = UMServerRoute & RouteConfig; +export type UMRouteDefinition = UMServerRoute & RouteConfig; export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From b6da0f6e7c4b16c80f9d7d7265f4204a4a13b4c6 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 13:12:07 -0500 Subject: [PATCH 05/13] Simplify route creation. --- .../framework/kibana_framework_adapter.ts | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) 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 915d795f4855d8..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 @@ -20,25 +20,18 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte this.plugins = plugins; } - public registerRoute({ handler, method, path, validate }: UMRouteDefinition) { + public registerRoute({ handler, method, options, path, validate }: UMRouteDefinition) { + const routeDefinition = { + path, + validate, + options, + }; switch (method) { case 'GET': - this.server.route.get( - { - path, - validate, - }, - handler - ); + this.server.route.get(routeDefinition, handler); break; case 'POST': - this.server.route.post( - { - path, - validate, - }, - handler - ); + this.server.route.post(routeDefinition, handler); break; default: throw new Error(`Handler for method ${method} is not defined`); @@ -61,11 +54,14 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte path: routePath, validate: { body: kbnSchema.object({ - operationName: kbnSchema.string(), + 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 { From 98c7f39a4ac8d1c3578763b36655a6859e8eab09 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 15:17:40 -0500 Subject: [PATCH 06/13] Remove tests of API decommissioned API endpoint. --- .../apis/uptime/feature_controls.ts | 26 ------------------- 1 file changed, 26 deletions(-) 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 1dd9d5ff798c45..7a5e887bbdd9e5 100644 --- a/x-pack/test/api_integration/apis/uptime/feature_controls.ts +++ b/x-pack/test/api_integration/apis/uptime/feature_controls.ts @@ -47,17 +47,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}` : ''; @@ -97,9 +86,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 { @@ -139,9 +125,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 { @@ -184,9 +167,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 { @@ -256,9 +236,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); }); @@ -267,9 +244,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); }); From 096eaf318fee2adf651d79e908e600110a3ca121 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 21 Nov 2019 15:47:03 -0500 Subject: [PATCH 07/13] Rename domain check. --- .../plugins/uptime/server/lib/compose/kibana.ts | 4 ++-- .../__tests__/__snapshots__/auth.test.ts.snap | 7 ------- .../__tests__/__snapshots__/license.test.ts.snap | 7 +++++++ .../__tests__/{auth.test.ts => license.test.ts} | 12 ++++++------ .../plugins/uptime/server/lib/domains/index.ts | 2 +- .../server/lib/domains/{auth.ts => license.ts} | 2 +- x-pack/legacy/plugins/uptime/server/lib/lib.ts | 2 +- .../uptime/server/rest_api/create_route_with_auth.ts | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap create mode 100644 x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap rename x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/{auth.test.ts => license.test.ts} (73%) rename x-pack/legacy/plugins/uptime/server/lib/domains/{auth.ts => license.ts} (90%) 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 7027a30bfce179..a7c370e03490b1 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts @@ -8,7 +8,7 @@ import { UMKibanaDatabaseAdapter } from '../adapters/database/kibana_database_ad import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import { ElasticsearchMonitorsAdapter } from '../adapters/monitors'; import { ElasticsearchPingsAdapter } from '../adapters/pings'; -import { authDomain } 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'; @@ -20,7 +20,7 @@ export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UM const database = new UMKibanaDatabaseAdapter(elasticsearch); 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 d7454d0d9066c1..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/auth.test.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`authDomain throws for inactive license 1`] = `"License not active"`; - -exports[`authDomain throws for null license 1`] = `"Missing license information"`; - -exports[`authDomain throws for unsupported license type 1`] = `"License not supported"`; 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..07d437112e888d --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`license check throws for inactive license 1`] = `"License not active"`; + +exports[`license check throws for null license 1`] = `"Missing license information"`; + +exports[`license check throws for unsupported license type 1`] = `"License not supported"`; 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__/license.test.ts similarity index 73% rename from x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts rename to x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts index 4b6b3130091881..73e70cb78626da 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/auth.test.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts @@ -4,24 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { authDomain } from '../auth'; +import { licenseCheck } from '../license'; import { RequestHandlerContext } from 'kibana/server'; -describe('authDomain', () => { +describe('license check', () => { let mockContext: RequestHandlerContext; const isOneOf = jest.fn(); it('throws for null license', () => { // @ts-ignore there's a null check in this function mockContext = { licensing: { license: null } }; - expect(() => authDomain(mockContext)).toThrowErrorMatchingSnapshot(); + expect(() => licenseCheck(mockContext)).toThrowErrorMatchingSnapshot(); }); it('throws for unsupported license type', () => { isOneOf.mockReturnValue(false); expect(() => // @ts-ignore it needs to throw if the license is not supported - authDomain({ licensing: { license: { isOneOf } } }) + licenseCheck({ licensing: { license: { isOneOf } } }) ).toThrowErrorMatchingSnapshot(); }); @@ -29,13 +29,13 @@ describe('authDomain', () => { isOneOf.mockReturnValue(true); expect(() => // @ts-ignore it needs to throw if !isActive - authDomain({ licensing: { license: { isActive: false, isOneOf } } }) + licenseCheck({ licensing: { license: { isActive: false, isOneOf } } }) ).toThrowErrorMatchingSnapshot(); }); it('returns true for a valid license', () => { isOneOf.mockReturnValue(true); // @ts-ignore license type needs to be non-null - expect(authDomain({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); + expect(licenseCheck({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); }); }); 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 b2d7503a6a192c..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 { authDomain, UMLicenseCheck } from './auth'; +export { licenseCheck, UMLicenseCheck } from './license'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts similarity index 90% rename from x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts rename to x-pack/legacy/plugins/uptime/server/lib/domains/license.ts index e7edc6913ab072..22bb30d42387d1 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/auth.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts @@ -9,7 +9,7 @@ import { RequestHandlerContext } from 'kibana/server'; export type UMLicenseCheck = (context: RequestHandlerContext) => boolean; -export const authDomain: UMLicenseCheck = ({ licensing: { license } }) => { +export const licenseCheck: UMLicenseCheck = ({ licensing: { license } }) => { if (license === null) { throw Boom.badRequest('Missing license information'); } diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/legacy/plugins/uptime/server/lib/lib.ts index 9a6a8217d12789..e68a6dd18ef5f2 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/lib.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/lib.ts @@ -15,7 +15,7 @@ import { import { UMLicenseCheck } from './domains'; export interface UMDomainLibs { - auth: UMLicenseCheck; + license: UMLicenseCheck; monitors: UMMonitorsAdapter; monitorStates: UMMonitorStatesAdapter; pings: UMPingsAdapter; 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 26ae3b454cfb89..7fbae1d2091fee 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 @@ -20,7 +20,7 @@ export const createRouteWithAuth = ( request, response ) => { - if (libs.auth(context)) { + if (libs.license(context)) { return await handler(context, request, response); } return response.badRequest(); From 4337ec16ec39fbb59c9dce455a63bcd7140e8bf6 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 25 Nov 2019 13:21:30 -0500 Subject: [PATCH 08/13] Make return shape of index pattern endpoint correspond to required NP resp body. --- .../uptime/server/rest_api/index_pattern/get_index_pattern.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b78fb8376cf6bc..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 @@ -17,7 +17,9 @@ export const createGetIndexPatternRoute: UMRestApiRouteCreator = (libs: UMServer handler: async (_context, _request, response): Promise => { try { return response.ok({ - ...(await libs.savedObjects.getUptimeIndexPattern()), + body: { + ...(await libs.savedObjects.getUptimeIndexPattern()), + }, }); } catch (e) { return response.internalError({ body: { message: e.message } }); From 2f85847bcc29918e13f653f1334067554299987e Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 25 Nov 2019 13:24:50 -0500 Subject: [PATCH 09/13] Move validate to appropriate level of route definition object for monitor details endpoint. --- .../rest_api/monitors/monitors_details.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) 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)) }, + }); }, }); From 73efb70f781bf7ee76e0a8307f65ac31392076e8 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 2 Dec 2019 13:15:13 -0500 Subject: [PATCH 10/13] Update snapshot count route. --- .../plugins/uptime/server/rest_api/index.ts | 1 - .../rest_api/snapshot/get_snapshot_count.ts | 36 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) 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 9d1d8c38ad9daf..2810982fb0c6c7 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -20,5 +20,4 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, - createGetMonitorDetailsRoute, ]; 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 5f5ce03d2cd7f3..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,33 +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: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ method: 'GET', path: '/api/uptime/snapshot/count', validate: { - query: Joi.object({ - dateRangeStart: Joi.string().required(), - dateRangeEnd: Joi.string().required(), - filters: Joi.string(), - statusFilter: Joi.string(), + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + filters: schema.maybe(schema.string()), + statusFilter: schema.maybe(schema.string()), }), }, - tags: ['access:uptime'], - handler: async (_context: any, request: any, response: any): Promise => { + options: { + tags: ['access:uptime'], + }, + handler: async (_context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, filters, statusFilter } = request.query; + const result = await libs.monitorStates.getSnapshotCount( + request, + dateRangeStart, + dateRangeEnd, + filters, + statusFilter + ); return response.ok({ - body: await libs.monitorStates.getSnapshotCount( - request, - dateRangeStart, - dateRangeEnd, - filters, - statusFilter - ), + body: { + ...result, + }, }); }, }); From 441deced1e59af5f4e0b6f0759be97222c592736 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 2 Dec 2019 18:08:26 -0500 Subject: [PATCH 11/13] Fix broken lint rule. --- x-pack/legacy/plugins/uptime/server/rest_api/types.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 4991cda99aff75..b4d7e438f51be3 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/types.ts @@ -13,6 +13,7 @@ export interface UMServerRoute { handler: RequestHandler; } -export type UMRouteDefinition = UMServerRoute & RouteConfig; +export type UMRouteDefinition = UMServerRoute & + RouteConfig; export type UMRestApiRouteCreator = (libs: UMServerLibs) => UMRouteDefinition; From 296c7b322af67be454478b23e51e7e603503ef85 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 5 Dec 2019 13:28:54 -0500 Subject: [PATCH 12/13] Remove usages of Boom. --- .../__snapshots__/license.test.ts.snap | 27 +++++++++++-- .../lib/domains/__tests__/license.test.ts | 39 +++++++++---------- .../uptime/server/lib/domains/license.ts | 32 +++++++++++---- 3 files changed, 67 insertions(+), 31 deletions(-) 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 index 07d437112e888d..ab791cbd243f8f 100644 --- 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 @@ -1,7 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`license check throws for inactive license 1`] = `"License not active"`; +exports[`license check returns result for a valid license 1`] = ` +Object { + "statusCode": 200, +} +`; -exports[`license check throws for null license 1`] = `"Missing license information"`; +exports[`license check throws for inactive license 1`] = ` +Object { + "message": "License not active", + "statusCode": 403, +} +`; -exports[`license check throws for unsupported license type 1`] = `"License not supported"`; +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__/license.test.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts index 73e70cb78626da..b26cb99cf9b6b2 100644 --- 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 @@ -4,38 +4,37 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ILicense } from '../../../../../../../plugins/licensing/server'; import { licenseCheck } from '../license'; -import { RequestHandlerContext } from 'kibana/server'; describe('license check', () => { - let mockContext: RequestHandlerContext; - const isOneOf = jest.fn(); + let mockLicense: Pick; it('throws for null license', () => { - // @ts-ignore there's a null check in this function - mockContext = { licensing: { license: null } }; - expect(() => licenseCheck(mockContext)).toThrowErrorMatchingSnapshot(); + expect(licenseCheck(null)).toMatchSnapshot(); }); it('throws for unsupported license type', () => { - isOneOf.mockReturnValue(false); - expect(() => - // @ts-ignore it needs to throw if the license is not supported - licenseCheck({ licensing: { license: { isOneOf } } }) - ).toThrowErrorMatchingSnapshot(); + mockLicense = { + isOneOf: jest.fn().mockReturnValue(false), + isActive: false, + }; + expect(licenseCheck(mockLicense)).toMatchSnapshot(); }); it('throws for inactive license', () => { - isOneOf.mockReturnValue(true); - expect(() => - // @ts-ignore it needs to throw if !isActive - licenseCheck({ licensing: { license: { isActive: false, isOneOf } } }) - ).toThrowErrorMatchingSnapshot(); + mockLicense = { + isOneOf: jest.fn().mockReturnValue(true), + isActive: false, + }; + expect(licenseCheck(mockLicense)).toMatchSnapshot(); }); - it('returns true for a valid license', () => { - isOneOf.mockReturnValue(true); - // @ts-ignore license type needs to be non-null - expect(licenseCheck({ licensing: { license: { isActive: true, isOneOf } } })).toBe(true); + 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/license.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts index 22bb30d42387d1..9c52667aeeab49 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts @@ -4,20 +4,36 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; -import { RequestHandlerContext } from 'kibana/server'; +import { ILicense } from '../../../../../../plugins/licensing/server'; -export type UMLicenseCheck = (context: RequestHandlerContext) => boolean; +export interface UMLicenseStatusResponse { + statusCode: number; + message?: string; +} +export type UMLicenseCheck = ( + license: Pick | null +) => UMLicenseStatusResponse; -export const licenseCheck: UMLicenseCheck = ({ licensing: { license } }) => { +export const licenseCheck: UMLicenseCheck = license => { if (license === null) { - throw Boom.badRequest('Missing license information'); + return { + message: 'Missing license information', + statusCode: 400, + }; } if (!license.isOneOf(['basic', 'standard', 'gold', 'platinum', 'trial'])) { - throw Boom.forbidden('License not supported'); + return { + message: 'License not supported', + statusCode: 401, + }; } if (license.isActive === false) { - throw Boom.forbidden('License not active'); + return { + message: 'License not active', + statusCode: 403, + }; } - return true; + return { + statusCode: 200, + }; }; From fb5626859ecfa78f6790c3eccd0ea725c65ab063 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Thu, 5 Dec 2019 13:47:00 -0500 Subject: [PATCH 13/13] Fix license router creation. --- .../plugins/uptime/server/rest_api/create_route_with_auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7fbae1d2091fee..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 @@ -20,7 +20,7 @@ export const createRouteWithAuth = ( request, response ) => { - if (libs.license(context)) { + if (libs.license(context.licensing.license)) { return await handler(context, request, response); } return response.badRequest();