Skip to content

Commit

Permalink
adds get route, working when tested locally
Browse files Browse the repository at this point in the history
  • Loading branch information
yctercero committed May 19, 2021
1 parent d348de2 commit 626c893
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 15 deletions.
15 changes: 11 additions & 4 deletions x-pack/plugins/apm/server/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const APM_FEATURE = {
privileges: {
all: {
app: ['apm', 'ux', 'kibana'],
api: ['apm', 'apm_write'],
api: ['apm', 'apm_write', 'rac'],
catalogue: ['apm'],
savedObject: {
all: [],
Expand All @@ -52,7 +52,7 @@ export const APM_FEATURE = {
},
read: {
app: ['apm', 'ux', 'kibana'],
api: ['apm'],
api: ['apm', 'rac'],
catalogue: ['apm'],
savedObject: {
all: [],
Expand All @@ -74,14 +74,21 @@ export const APM_FEATURE = {
},
subFeatures: [
{
name: 'Manage Alerts',
name: i18n.translate('xpack.apm.featureRegistry.manageAlerts', {
defaultMessage: 'Manage Alerts',
}),
privilegeGroups: [
{
groupType: 'independent',
privileges: [
{
id: 'alert_manage',
name: 'Manage Alerts',
name: i18n.translate(
'xpack.apm.featureRegistry.subfeature.apmFeatureName',
{
defaultMessage: 'Manage Alerts',
}
),
includeIn: 'all',
alerting: {
alert: {
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/rule_registry/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export const BASE_RAC_ALERTS_API_PATH = '/api/rac/alerts';
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
AlertingAuthorizationEntity,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../alerting/server/authorization';
import { Logger, ElasticsearchClient } from '../../../../../src/core/server';
import { Logger, ElasticsearchClient, HttpResponsePayload } from '../../../../../src/core/server';
import { buildAlertsSearchQuery, buildAlertsUpdateParameters } from './utils';
import { RacAuthorizationAuditLogger } from './audit_logger';

Expand Down Expand Up @@ -108,7 +108,8 @@ export class AlertsClient {
this.auditLogger = auditLogger;
}

public async get({ id }: GetAlertParams): Promise<unknown> {
// TODO: Type out alerts (rule registry fields + alerting alerts type)
public async get({ id }: GetAlertParams): Promise<HttpResponsePayload> {
// first search for the alert specified, then check if user has access to it
// and return search results
const query = buildAlertsSearchQuery({
Expand All @@ -117,20 +118,21 @@ export class AlertsClient {
});
// TODO: Type out alerts (rule registry fields + alerting alerts type)
const { body: result } = await this.esClient.search<RawAlert>(query);
const hits = result.hits.hits[0];
// TODO: I thought we were moving away from using _source?
const hits = result.hits.hits[0]._source;

try {
// use security plugin routes to check what URIs user is authorized to
await this.authorization.ensureAuthorized({
ruleTypeId: hits['kibana.rac.alert.id'],
consumer: hits['kibana.rac.producer'],
ruleTypeId: hits['rule.id'],
consumer: hits['kibana.rac.alert.producer'],
operation: ReadOperations.Get,
entity: AlertingAuthorizationEntity.Alert,
});
} catch (error) {
throw Boom.forbidden(
this.auditLogger.racAuthorizationFailure({
owner: hits['kibana.rac.producer'],
owner: hits['kibana.rac.alert.producer'],
operation: ReadOperations.Get,
type: 'access',
})
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/rule_registry/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { AlertsClientFactory } from './alert_data_client/alert_client_factory';
import { PluginStartContract as AlertingStart } from '../../alerting/server';
import { SpacesPluginStart } from '../../spaces/server';
import { RacApiRequestHandlerContext, RacRequestHandlerContext } from './types';
import { defineRoutes } from './routes';
export type RuleRegistryPluginSetupContract = RuleDataPluginService;
export type RuleRegistryPluginStartContract = void;

Expand Down Expand Up @@ -70,11 +71,14 @@ export class RuleRegistryPlugin implements Plugin<RuleRegistryPluginSetupContrac
});

// ALERTS ROUTES
const router = core.http.createRouter<RacRequestHandlerContext>();
core.http.registerRouteHandlerContext<RacRequestHandlerContext, 'rac'>(
'rac',
this.createRouteHandlerContext()
);

defineRoutes(router);

return service;
}

Expand Down Expand Up @@ -111,7 +115,7 @@ export class RuleRegistryPlugin implements Plugin<RuleRegistryPluginSetupContrac
request
): Promise<RacApiRequestHandlerContext> {
return {
getRacClient: async () => {
getAlertsClient: async () => {
const createdClient = alertsClientFactory.create(request);
return createdClient;
},
Expand Down
42 changes: 42 additions & 0 deletions x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { IRouter } from 'kibana/server';
import * as t from 'io-ts';
import { id as _id } from '@kbn/securitysolution-io-ts-list-types';

import { RacRequestHandlerContext } from '../types';
import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants';
import { buildRouteValidation } from './utils/route_validation';

export const getAlertByIdRoute = (router: IRouter<RacRequestHandlerContext>) => {
router.get(
{
path: BASE_RAC_ALERTS_API_PATH,
validate: {
query: buildRouteValidation(
t.exact(
t.type({
id: _id,
})
)
),
},
options: {
tags: ['access:rac'],
},
},
async (context, request, response) => {
const alertsClient = await context.rac.getAlertsClient();
const { id } = request.query;
const alert = await alertsClient.get({ id });
return response.ok({
body: alert,
});
}
);
};
14 changes: 14 additions & 0 deletions x-pack/plugins/rule_registry/server/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { IRouter } from 'kibana/server';
import { RacRequestHandlerContext } from '../types';
import { getAlertByIdRoute } from './get_alert_by_id';

export function defineRoutes(router: IRouter<RacRequestHandlerContext>) {
getAlertByIdRoute(router);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { fold } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import * as rt from 'io-ts';
import { exactCheck, formatErrors } from '@kbn/securitysolution-io-ts-utils';

import {
RouteValidationError,
RouteValidationFunction,
RouteValidationResultFactory,
} from '../../../../../../src/core/server';

type RequestValidationResult<T> =
| {
value: T;
error?: undefined;
}
| {
value?: undefined;
error: RouteValidationError;
};

/**
* Copied from x-pack/plugins/security_solution/server/utils/build_validation/route_validation.ts
* This really should be in @kbn/securitysolution-io-ts-utils rather than copied yet again, however, this has types
* from a lot of places such as RouteValidationResultFactory from core/server which in turn can pull in @kbn/schema
* which cannot work on the front end and @kbn/securitysolution-io-ts-utils works on both front and backend.
*
* TODO: Figure out a way to move this function into a package rather than copying it/forking it within plugins
*/
export const buildRouteValidation = <T extends rt.Mixed, A = rt.TypeOf<T>>(
schema: T
): RouteValidationFunction<A> => (
inputValue: unknown,
validationResult: RouteValidationResultFactory
): RequestValidationResult<A> =>
pipe(
schema.decode(inputValue),
(decoded) => exactCheck(inputValue, decoded),
fold<rt.Errors, A, RequestValidationResult<A>>(
(errors: rt.Errors) => validationResult.badRequest(formatErrors(errors).join()),
(validatedInput: A) => validationResult.ok(validatedInput)
)
);
15 changes: 15 additions & 0 deletions x-pack/plugins/rule_registry/server/scripts/get_alert_by_id.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

#
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
#

set -e

# Example: ./get_alert_by_id.sh {id}
curl -s -k \
-u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \
-X GET ${KIBANA_URL}${SPACE_URL}/api/rac/alerts?id="$1" | jq .
4 changes: 2 additions & 2 deletions x-pack/plugins/rule_registry/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ export type AlertTypeWithExecutor<
* @public
*/
export interface RacApiRequestHandlerContext {
getRacClient: () => Promise<AlertsClient>;
getAlertsClient: () => Promise<AlertsClient>;
}

/**
* @internal
*/
export interface RacRequestHandlerContext extends RequestHandlerContext {
rac?: RacApiRequestHandlerContext;
rac: RacApiRequestHandlerContext;
}
4 changes: 2 additions & 2 deletions x-pack/plugins/security_solution/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
all: {
app: [...securitySubPlugins, 'kibana'],
catalogue: ['securitySolution'],
api: ['securitySolution', 'lists-all', 'lists-read'],
api: ['securitySolution', 'lists-all', 'lists-read', 'rac'],
savedObject: {
all: [
'alert',
Expand All @@ -254,7 +254,7 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
read: {
app: [...securitySubPlugins, 'kibana'],
catalogue: ['securitySolution'],
api: ['securitySolution', 'lists-read'],
api: ['securitySolution', 'lists-read', 'rac'],
savedObject: {
all: [],
read: [
Expand Down

0 comments on commit 626c893

Please sign in to comment.