[SECURITY SOLUTION] Remove timeline alert search strategy (#160310)

## Summary

Fix https://github.com/elastic/security-team/issues/6488 for `timeline
alert strategy`

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Xavier Mouligneau 2023-06-23 12:57:26 -04:00 committed by GitHub
parent f5a111eaab
commit c40cd0365d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 5 additions and 109 deletions

View file

@ -65,7 +65,7 @@ const ACTION_BUTTON_COUNT = 4;
const testProps: EventsViewerProps = {
defaultModel: eventsDefaultModel,
end: to,
entityType: EntityType.ALERTS,
entityType: EntityType.EVENTS,
indexNames: [],
tableId: TableId.test,
leadingControlColumns: getDefaultControlColumn(ACTION_BUTTON_COUNT),

View file

@ -66,7 +66,7 @@ describe('epicLocalStorage', () => {
testProps = {
defaultModel: eventsDefaultModel,
end: to,
entityType: EntityType.ALERTS,
entityType: EntityType.EVENTS,
tableId: TableId.test,
leadingControlColumns: getDefaultControlColumn(ACTION_BUTTON_COUNT),
renderCellValue: DefaultCellRenderer,

View file

@ -18,7 +18,6 @@ export enum TimelineEventsQueries {
}
export const EntityType = {
ALERTS: 'alerts',
EVENTS: 'events',
SESSIONS: 'sessions',
} as const;

View file

@ -32,7 +32,6 @@ export class TimelinesPlugin
core.getStartServices().then(([_, depsStart]) => {
const TimelineSearchStrategy = timelineSearchStrategyProvider(
depsStart.data,
depsStart.alerting,
this.logger,
this.security
);

View file

@ -5,14 +5,7 @@
* 2.0.
*/
import { ALERT_RULE_CONSUMER, ALERT_RULE_TYPE_ID, SPACE_IDS } from '@kbn/rule-data-utils';
import { map, mergeMap, catchError } from 'rxjs/operators';
import { from } from 'rxjs';
import {
AlertingAuthorizationEntity,
AlertingAuthorizationFilterType,
PluginStartContract as AlertingPluginStartContract,
} from '@kbn/alerting-plugin/server';
import { map, mergeMap } from 'rxjs/operators';
import {
ISearchStrategy,
PluginStart,
@ -20,8 +13,7 @@ import {
shimHitsTotal,
} from '@kbn/data-plugin/server';
import { ENHANCED_ES_SEARCH_STRATEGY, ISearchOptions } from '@kbn/data-plugin/common';
import { AuditLogger, SecurityPluginSetup } from '@kbn/security-plugin/server';
import { AlertAuditAction, alertAuditEvent } from '@kbn/rule-registry-plugin/server';
import { SecurityPluginSetup } from '@kbn/security-plugin/server';
import { Logger } from '@kbn/logging';
import {
TimelineFactoryQueryTypes,
@ -35,15 +27,12 @@ import { isAggCardinalityAggregate } from './factory/helpers/is_agg_cardinality_
export const timelineSearchStrategyProvider = <T extends TimelineFactoryQueryTypes>(
data: PluginStart,
alerting: AlertingPluginStartContract,
logger: Logger,
security?: SecurityPluginSetup
): ISearchStrategy<TimelineStrategyRequestType<T>, TimelineStrategyResponseType<T>> => {
const esAsInternal = data.search.searchAsInternalUser;
const es = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY);
return {
search: (request, options, deps) => {
const securityAuditLogger = security?.audit.asScoped(deps.request);
const factoryQueryType = request.factoryQueryType;
const entityType = request.entityType;
@ -53,17 +42,7 @@ export const timelineSearchStrategyProvider = <T extends TimelineFactoryQueryTyp
const queryFactory: TimelineFactory<T> = timelineFactory[factoryQueryType];
if (entityType != null && entityType === EntityType.ALERTS) {
return timelineAlertsSearchStrategy({
es: esAsInternal,
request,
options,
deps,
queryFactory,
alerting,
auditLogger: securityAuditLogger,
});
} else if (entityType != null && entityType === EntityType.SESSIONS) {
if (entityType != null && entityType === EntityType.SESSIONS) {
return timelineSessionsSearchStrategy({
es,
request,
@ -109,87 +88,6 @@ const timelineSearchStrategy = <T extends TimelineFactoryQueryTypes>({
);
};
const timelineAlertsSearchStrategy = <T extends TimelineFactoryQueryTypes>({
es,
request,
options,
deps,
queryFactory,
alerting,
auditLogger,
}: {
es: ISearchStrategy;
request: TimelineStrategyRequestType<T>;
options: ISearchOptions;
deps: SearchStrategyDependencies;
alerting: AlertingPluginStartContract;
queryFactory: TimelineFactory<T>;
auditLogger: AuditLogger | undefined;
}) => {
const indices = request.defaultIndex ?? request.indexType;
const requestWithAlertsIndices = { ...request, defaultIndex: indices, indexName: indices };
// Note: Alerts RBAC are built off of the alerting's authorization class, which
// is why we are pulling from alerting, not ther alertsClient here
const alertingAuthorizationClient = alerting.getAlertingAuthorizationWithRequest(deps.request);
const getAuthFilter = async () =>
alertingAuthorizationClient.getFindAuthorizationFilter(AlertingAuthorizationEntity.Alert, {
type: AlertingAuthorizationFilterType.ESDSL,
// Not passing in values, these are the paths for these fields
fieldNames: {
consumer: ALERT_RULE_CONSUMER,
ruleTypeId: ALERT_RULE_TYPE_ID,
spaceIds: SPACE_IDS,
},
});
return from(getAuthFilter()).pipe(
mergeMap(({ filter }) => {
const dsl = queryFactory.buildDsl({
...requestWithAlertsIndices,
authFilter: filter,
});
return es.search({ ...requestWithAlertsIndices, params: dsl }, options, deps);
}),
map((response) => {
const rawResponse = shimHitsTotal(response.rawResponse, options);
// Do we have to loop over each hit? Yes.
// ecs auditLogger requires that we log each alert independently
if (auditLogger != null) {
rawResponse.hits?.hits?.forEach((hit) => {
auditLogger.log(
alertAuditEvent({
action: AlertAuditAction.FIND,
id: hit._id,
outcome: 'success',
})
);
});
}
return {
...response,
rawResponse,
};
}),
mergeMap((esSearchRes) => queryFactory.parse(requestWithAlertsIndices, esSearchRes)),
catchError((err) => {
// check if auth error, if yes, write to ecs logger
if (auditLogger != null && err?.output?.statusCode === 403) {
auditLogger.log(
alertAuditEvent({
action: AlertAuditAction.FIND,
outcome: 'failure',
error: err,
})
);
}
throw err;
})
);
};
const timelineSessionsSearchStrategy = <T extends TimelineFactoryQueryTypes>({
es,
request,