Skip to content

Commit

Permalink
[Osquery] Change prebuilt saved queries to include prebuilt flag (ela…
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsonpl authored May 23, 2022
1 parent 6b846af commit ba84602
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const EditSavedQueryPageComponent = () => {
useBreadcrumbs('saved_query_edit', { savedQueryName: savedQueryDetails?.attributes?.id ?? '' });

const elasticPrebuiltQuery = useMemo(
() => savedQueryDetails?.attributes?.version,
() => savedQueryDetails?.attributes?.prebuilt,
[savedQueryDetails]
);
const viewMode = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { isSavedQueryPrebuilt } from './utils';

export const deleteSavedQueryRoute = (router: IRouter) => {
export const deleteSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.delete(
{
path: '/internal/osquery/saved_query/{id}',
Expand All @@ -25,6 +27,11 @@ export const deleteSavedQueryRoute = (router: IRouter) => {
const coreContext = await context.core;
const savedObjectsClient = coreContext.savedObjects.client;

const isPrebuilt = await isSavedQueryPrebuilt(osqueryContext, request.params.id);
if (isPrebuilt) {
return response.conflict({ body: `Elastic prebuilt Saved query cannot be deleted.` });
}

await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, {
refresh: 'wait_for',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';

import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { convertECSMappingToObject } from '../utils';
import { getInstalledSavedQueriesMap } from './utils';

export const findSavedQueryRoute = (router: IRouter) => {
export const findSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
path: '/internal/osquery/saved_query',
Expand All @@ -34,6 +37,7 @@ export const findSavedQueryRoute = (router: IRouter) => {

const savedQueries = await savedObjectsClient.find<{
ecs_mapping: Array<{ field: string; value: string }>;
prebuilt: boolean;
}>({
type: savedQuerySavedObjectType,
page: parseInt(request.query.pageIndex ?? '0', 10) + 1,
Expand All @@ -43,10 +47,13 @@ export const findSavedQueryRoute = (router: IRouter) => {
sortOrder: request.query.sortDirection ?? 'desc',
});

const prebuiltSavedQueriesMap = await getInstalledSavedQueriesMap(osqueryContext);
const savedObjects = savedQueries.saved_objects.map((savedObject) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const ecs_mapping = savedObject.attributes.ecs_mapping;

savedObject.attributes.prebuilt = !!prebuiltSavedQueriesMap[savedObject.id];

if (ecs_mapping) {
// @ts-expect-error update types
savedObject.attributes.ecs_mapping = convertECSMappingToObject(ecs_mapping);
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/osquery/server/routes/saved_query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

export const initSavedQueryRoutes = (router: IRouter, context: OsqueryAppContext) => {
createSavedQueryRoute(router, context);
deleteSavedQueryRoute(router);
findSavedQueryRoute(router);
readSavedQueryRoute(router);
deleteSavedQueryRoute(router, context);
findSavedQueryRoute(router, context);
readSavedQueryRoute(router, context);
updateSavedQueryRoute(router, context);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import { isSavedQueryPrebuilt } from './utils';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { convertECSMappingToObject } from '../utils';

export const readSavedQueryRoute = (router: IRouter) => {
export const readSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAppContext) => {
router.get(
{
path: '/internal/osquery/saved_query/{id}',
Expand All @@ -28,6 +30,7 @@ export const readSavedQueryRoute = (router: IRouter) => {

const savedQuery = await savedObjectsClient.get<{
ecs_mapping: Array<{ key: string; value: Record<string, object> }>;
prebuilt: boolean;
}>(savedQuerySavedObjectType, request.params.id);

if (savedQuery.attributes.ecs_mapping) {
Expand All @@ -37,6 +40,8 @@ export const readSavedQueryRoute = (router: IRouter) => {
);
}

savedQuery.attributes.prebuilt = await isSavedQueryPrebuilt(osqueryContext, savedQuery.id);

return response.ok({
body: savedQuery,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { filter } from 'lodash';
import { schema } from '@kbn/config-schema';

import { IRouter } from '@kbn/core/server';
import { isSavedQueryPrebuilt } from './utils';
import { PLUGIN_ID } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';
Expand Down Expand Up @@ -63,6 +64,12 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp
ecs_mapping,
} = request.body;

const isPrebuilt = await isSavedQueryPrebuilt(osqueryContext, request.params.id);

if (isPrebuilt) {
return response.conflict({ body: `Elastic prebuilt Saved query cannot be updated.` });
}

const conflictingEntries = await savedObjectsClient.find<{ id: string }>({
type: savedQuerySavedObjectType,
filter: `${savedQuerySavedObjectType}.attributes.id: "${id}"`,
Expand Down
54 changes: 54 additions & 0 deletions x-pack/plugins/osquery/server/routes/saved_query/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 { find, reduce } from 'lodash';
import { KibanaAssetReference } from '@kbn/fleet-plugin/common';

import { OSQUERY_INTEGRATION_NAME } from '../../../common';
import { savedQuerySavedObjectType } from '../../../common/types';
import { OsqueryAppContext } from '../../lib/osquery_app_context_services';

const getInstallation = async (osqueryContext: OsqueryAppContext) =>
await osqueryContext.service
.getPackageService()
?.asInternalUser?.getInstallation(OSQUERY_INTEGRATION_NAME);

export const getInstalledSavedQueriesMap = async (osqueryContext: OsqueryAppContext) => {
const installation = await getInstallation(osqueryContext);
if (installation) {
return reduce(
installation.installed_kibana,
// @ts-expect-error not sure why it shouts, but still it's properly typed
(acc: Record<string, KibanaAssetReference>, item: KibanaAssetReference) => {
if (item.type === savedQuerySavedObjectType) {
return { ...acc, [item.id]: item };
}
},
{}
);
}

return {};
};

export const isSavedQueryPrebuilt = async (
osqueryContext: OsqueryAppContext,
savedQueryId: string
) => {
const installation = await getInstallation(osqueryContext);

if (installation) {
const installationSavedQueries = find(
installation.installed_kibana,
(item) => item.type === savedQuerySavedObjectType && item.id === savedQueryId
);

return !!installationSavedQueries;
}

return false;
};

0 comments on commit ba84602

Please sign in to comment.