diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 627d5e7fcdc590..59ce38cec2ce4d 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -179,13 +179,14 @@ export class MonitoringPlugin router.get({ path: '/monitoring-myfakepath', validate: false }, async (context, req, res) => { try { const racClient = await context.ruleRegistry?.getRacClient(); - const thing = await racClient?.get({ id: 'hello world', owner: 'observability' }); + const thing = await racClient?.find({ owner: 'observability' }); console.error('THE THING!!!', JSON.stringify(thing.body, null, 2)); - return res.ok({ body: { success: true } }); + return res.ok({ body: { success: true, alerts: thing.body.hits.hits } }); } catch (err) { console.error('monitoring route threw an error'); console.error(err); - return res.notFound({ body: { message: err.message } }); + return res.unauthorized({ body: { message: err.message } }); + // return res.customError({ statusCode: err.statusCode, body: { message: err.message } }); } }); } diff --git a/x-pack/plugins/rule_registry/server/index.ts b/x-pack/plugins/rule_registry/server/index.ts index 2dfbdef44685da..78b0b2c9160b86 100644 --- a/x-pack/plugins/rule_registry/server/index.ts +++ b/x-pack/plugins/rule_registry/server/index.ts @@ -9,7 +9,7 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { PluginInitializerContext } from 'src/core/server'; import { RuleRegistryPlugin } from './plugin'; -export { RacPluginSetupContract } from './plugin'; +export { RuleRegistryPluginSetupContract } from './plugin'; export { createLifecycleRuleTypeFactory } from './rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory'; export { FieldMapOf } from './types'; export { ScopedRuleRegistryClient } from './rule_registry/create_scoped_rule_registry_client/types'; diff --git a/x-pack/plugins/rule_registry/server/rac_client/rac_client.ts b/x-pack/plugins/rule_registry/server/rac_client/rac_client.ts index 56172d7964a9ab..6ebca65213b89b 100644 --- a/x-pack/plugins/rule_registry/server/rac_client/rac_client.ts +++ b/x-pack/plugins/rule_registry/server/rac_client/rac_client.ts @@ -15,6 +15,8 @@ import { GrantAPIKeyResult as SecurityPluginGrantAPIKeyResult, InvalidateAPIKeyResult as SecurityPluginInvalidateAPIKeyResult, } from '../../../security/server'; +import { SERVER_APP_ID } from '../../../security_solution/server'; + import { RacAuthorization, WriteOperations, @@ -61,6 +63,11 @@ export interface FindOptions extends IndexType { filter?: string; } +export interface CreateAlertParams { + esClient: ElasticsearchClient; + owner: 'observability' | 'securitySolution'; +} + interface IndexType { [key: string]: unknown; } @@ -117,14 +124,8 @@ export class RacClient { owner, }: { id: string; - owner: 'securitySolution' | 'observability'; + owner: typeof SERVER_APP_ID | 'observability'; }): Promise { - // TODO: type alert for the get method - const result = await this.esClient.search({ - index: '.siem*', - body: { query: { match_all: {} } }, - }); - console.error(`************\nRESULT ${JSON.stringify(result, null, 2)}\n************`); // .get('alert', id); try { await this.authorization.ensureAuthorized( @@ -133,7 +134,25 @@ export class RacClient { owner, ReadOperations.Get ); + // TODO: type alert for the get method + + try { + const result = await this.esClient.get({ + index: '.siem-signals-devin-hurley-default', + id, + }); + console.error(`************\nRESULT ${JSON.stringify(result, null, 2)}\n************`); + return result; + } catch (exc) { + console.error('THREW ERROR WHEN TRYING GET', JSON.stringify(exc, null, 2)); + } + + // const result = await this.esClient.search({ + // index: '.siem*', + // body: { query: { match_all: {} } }, + // }); } catch (error) { + console.error('HERES THE ERROR', error); // this.auditLogger?.log( // alertAuditEvent({ // action: AlertAuditAction.GET, @@ -152,7 +171,7 @@ export class RacClient { // TODO: strip out owner field maybe? // this.getAlertFromRaw(result.id, result.attributes, result.references); - return result; + // return result; // return Promise.resolve({ id: 'hello world!!!' }); // const result = await this.unsecuredSavedObjectsClient.get('alert', id); @@ -181,9 +200,58 @@ export class RacClient { // return this.getAlertFromRaw(result.id, result.attributes, result.references); } - public async find({ - options: { fields, ...options } = {}, - }: { options?: FindOptions } = {}): Promise> { + public async find({ + owner, + }: { + owner: typeof SERVER_APP_ID | 'observability'; + }): Promise { + try { + await this.authorization.ensureAuthorized( + // TODO: add spaceid here.. I think + // result.body._source?.owner, + owner, + ReadOperations.Get + ); + // TODO: type alert for the get method + + try { + // const result = await this.esClient.get({ + // index: '.siem-signals-devin-hurley-default', + // id: 'ecf1d03a9f3456bb28bf3af5ef9fd2ef441641f3b495d92112e5e76d8feae62e', + // }); + const result = await this.esClient.search({ + index: '.siem-signals*', + body: { + query: { + term: { + 'signal.owner': { + value: owner, + }, + }, + }, + }, + }); + console.error(`************\nRESULT ${JSON.stringify(result, null, 2)}\n************`); + return result; + } catch (exc) { + console.error('THREW ERROR WHEN TRYING GET', JSON.stringify(exc, null, 2)); + } + + // const result = await this.esClient.search({ + // index: '.siem*', + // body: { query: { match_all: {} } }, + // }); + } catch (error) { + console.error('HERES THE ERROR', error); + // this.auditLogger?.log( + // alertAuditEvent({ + // action: AlertAuditAction.GET, + // savedObject: { type: 'alert', id }, + // error, + // }) + // ); + throw error; + } // let authorizationTuple; // try { // authorizationTuple = await this.authorization.getFindAuthorizationFilter(); @@ -337,4 +405,6 @@ export class RacClient { // ]); // return updateResult; } + + static async create({ esClient, owner, data }: createAlertParams) {} } diff --git a/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts b/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts index 65eaf0964cfcab..6dcf47489631f1 100644 --- a/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts +++ b/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts @@ -169,6 +169,7 @@ export function createLifecycleRuleTypeFactory(): CreateLifecycleRuleType { @@ -46,7 +46,7 @@ export const config: PluginConfigDescriptor = { }; export { ConfigType, Plugin, PluginSetup, PluginStart }; -export { AppClient }; +export { AppClient, SERVER_APP_ID }; // Exports to be shared with plugins such as x-pack/lists plugin export { deleteTemplate } from './lib/detection_engine/index/delete_template'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json index d6a06848592cc7..81c5c3b296ba81 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/signals_mapping.json @@ -77,6 +77,9 @@ } } }, + "owner": { + "type": "keyword" + }, "rule": { "properties": { "id": { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts index 10cc1687004470..d20514661b3231 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts @@ -18,17 +18,19 @@ import { import { buildRuleWithoutOverrides, buildRuleWithOverrides } from './build_rule'; import { additionalSignalFields, buildSignal } from './build_signal'; import { buildEventTypeSignal } from './build_event_type_signal'; +import { SERVER_APP_ID } from '../../../../common/constants'; import { EqlSequence } from '../../../../common/detection_engine/types'; import { generateSignalId, wrapBuildingBlocks, wrapSignal } from './utils'; // format search_after result for signals index. export const buildBulkBody = ( ruleSO: SavedObject, - doc: SignalSourceHit + doc: SignalSourceHit, + owner: typeof SERVER_APP_ID ): SignalHit => { const rule = buildRuleWithOverrides(ruleSO, doc._source!); const signal: Signal = { - ...buildSignal([doc], rule), + ...buildSignal([doc], rule, owner), ...additionalSignalFields(doc), }; const event = buildEventTypeSignal(doc); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts index 237536a99c0f0e..06f2d09cd6d749 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts @@ -6,6 +6,7 @@ */ import { SearchTypes } from '../../../../common/detection_engine/types'; +import { SERVER_APP_ID } from '../../../../common/constants'; import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema'; import { SIGNALS_TEMPLATE_VERSION } from '../routes/index/get_signals_template'; import { isEventTypeSignal } from './build_event_type_signal'; @@ -76,7 +77,11 @@ export const removeClashes = (doc: BaseSignalHit): BaseSignalHit => { * @param docs The parent signals/events of the new signal to be built. * @param rule The rule that is generating the new signal. */ -export const buildSignal = (docs: BaseSignalHit[], rule: RulesSchema): Signal => { +export const buildSignal = ( + docs: BaseSignalHit[], + rule: RulesSchema, + owner: typeof SERVER_APP_ID +): Signal => { const _meta = { version: SIGNALS_TEMPLATE_VERSION, }; @@ -92,6 +97,7 @@ export const buildSignal = (docs: BaseSignalHit[], rule: RulesSchema): Signal => parents, ancestors, status: 'open', + owner, rule, depth, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts index 92d01fef6e50c3..91985a2e3f9fa1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts @@ -12,6 +12,8 @@ import { AlertInstanceState, AlertServices, } from '../../../../../alerting/server'; + +import { SERVER_APP_ID } from '../../../../common/constants'; import { AlertAttributes, SignalHit, SignalSearchResponse, WrappedSignalHit } from './types'; import { RefreshTypes } from '../types'; import { generateId, makeFloatString, errorAggregator } from './utils'; @@ -121,10 +123,10 @@ export const singleBulkCreate = async ({ ), }, }, - buildBulkBody(ruleSO, doc), + buildBulkBody(ruleSO, doc, SERVER_APP_ID), ]); const start = performance.now(); - const { body: response } = await services.scopedClusterClient.asCurrentUser.bulk({ + const { body: response } = await services.scopedClusterClient.asInternalUser.bulk({ index: signalsIndex, refresh, body: bulkBody, @@ -140,7 +142,7 @@ export const singleBulkCreate = async ({ .map((doc, index) => ({ _id: response.items[index].create?._id ?? '', _index: response.items[index].create?._index ?? '', - ...buildBulkBody(ruleSO, doc), + ...buildBulkBody(ruleSO, doc, SERVER_APP_ID), })) .filter((_, index) => get(response.items[index], 'create.status') === 201); const createdItemsCount = createdItems.length; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index 80d08a77ba5d2f..f77189ea393eac 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -211,6 +211,7 @@ export interface Signal { }; original_time?: string; original_event?: SearchTypes; + owner?: string; status: Status; threshold_result?: ThresholdResult; original_signal?: SearchTypes; diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 5d405f9df3d334..d572af8b36478f 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -217,13 +217,34 @@ export class Plugin implements IPlugin { try { const racClient = await context.ruleRegistry?.getRacClient(); - const thing = await racClient?.get({ id: 'hello world', owner: 'securitySolution' }); - console.error('THE THING EXISTS??', JSON.stringify(thing.body, null, 2)); - return res.ok({ body: { success: true } }); + const thing = await racClient?.find({ owner: SERVER_APP_ID }); + console.error('hits?', JSON.stringify(thing.body.hits.hits, null, 2)); + return res.ok({ body: { success: true, alerts: thing.body.hits.hits } }); } catch (err) { console.error('monitoring route threw an error'); - console.error(err); - return res.notFound({ body: { message: err.message } }); + console.error('ERROR JSON', JSON.stringify(err, null, 2)); + const statusCode = err.output.statusCode; + console.error('ERROR STATUSCODE?', statusCode); + // { message: err.message }, + + // const contentType = { + // 'Content-Type': 'application/json', + // }; + // const defaultedHeaders = { + // ...contentType, + // }; + + // return res.custom({ + // statusCode, + // headers: defaultedHeaders, + // body: Buffer.from( + // JSON.stringify({ + // message: 'hello world', //err.message, + // status_code: statusCode, + // }) + // ), + // }); + return res.unauthorized({ body: { message: err.message } }); } }); @@ -236,12 +257,12 @@ export class Plugin implements IPlugin