Skip to content

Commit

Permalink
Fix UI issues (opensearch-project#1107)
Browse files Browse the repository at this point in the history
* updated vega imports; fixed get correlated findings

Signed-off-by: Amardeepsingh Siglani <[email protected]>

* fixed correlation alerts filtering; improved list iocs pagination

Signed-off-by: Amardeepsingh Siglani <[email protected]>

* updated help text for data source selection

Signed-off-by: Amardeepsingh Siglani <[email protected]>

* fixed active condition for threat intel source

Signed-off-by: Amardeepsingh Siglani <[email protected]>

---------

Signed-off-by: Amardeepsingh Siglani <[email protected]>
  • Loading branch information
amsiglan authored Aug 10, 2024
1 parent 62ab170 commit d3548eb
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 78 deletions.
4 changes: 2 additions & 2 deletions public/pages/Alerts/containers/Alerts/Alerts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ import { ThreatIntelAlertsTable } from '../../components/ThreatIntelAlertsTable/

type FilterAlertParams =
| { alerts: AlertItem[]; timeField: 'last_notification_time' }
| { alerts: CorrelationAlertTableItem[]; timeField: 'end_time' }
| { alerts: CorrelationAlertTableItem[]; timeField: 'start_time' }
| { alerts: ThreatIntelAlert[]; timeField: 'start_time' };

export interface AlertsProps extends RouteComponentProps, DataSourceProps {
Expand Down Expand Up @@ -255,7 +255,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
const { correlationAlerts } = this.state;
const filteredCorrelationAlerts = this.filterAlerts({
alerts: correlationAlerts,
timeField: 'end_time',
timeField: 'start_time',
});

this.setState({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
EuiCallOut,
EuiTextColor,
EuiTitle,
EuiLink,
} from '@elastic/eui';
import { FormFieldHeader } from '../../../../../../components/FormFieldHeader/FormFieldHeader';
import { IndexOption } from '../../../../../Detectors/models/interfaces';
Expand Down Expand Up @@ -163,6 +162,10 @@ export default class DetectorDataSource extends Component<
<span>
<a href="https://opensearch.org/docs/latest/im-plugin/index-alias" target="_blank">
Aliases
</a>
{' and '}
<a href="https://opensearch.org/docs/latest/im-plugin/data-streams/" target="_blank">
data streams
</a>{' '}
are recommended for optimal functioning of detectors.
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,13 @@ exports[`<UpdateDetectorBasicDetails /> spec renders the component 1`] = `
>
Aliases
</a>
and
<a
href="https://opensearch.org/docs/latest/im-plugin/data-streams/"
target="_blank"
>
data streams
</a>
are recommended for optimal functioning of detectors.
</span>
Expand Down Expand Up @@ -1113,6 +1120,13 @@ exports[`<UpdateDetectorBasicDetails /> spec renders the component 1`] = `
>
Aliases
</a>
and
<a
href="https://opensearch.org/docs/latest/im-plugin/data-streams/"
target="_blank"
>
data streams
</a>
are recommended for optimal functioning of detectors.
</span>
Expand Down
120 changes: 110 additions & 10 deletions public/pages/ThreatIntel/components/IoCsTable/IoCsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,43 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { EuiBasicTableColumn, EuiInMemoryTable, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui';
import React, { useState, useEffect } from 'react';
import {
EuiBasicTableColumn,
EuiPanel,
EuiSpacer,
EuiText,
EuiBasicTable,
Pagination,
CriteriaWithPagination,
EuiSearchBar,
} from '@elastic/eui';
import { ThreatIntelIocData } from '../../../../../types';
import { renderTime } from '../../../../utils/helpers';
import { IocLabel, ThreatIntelIocType } from '../../../../../common/constants';
import { ThreatIntelService } from '../../../../services';

export interface IoCsTableProps {
threatIntelService: ThreatIntelService;
sourceId?: string;
loadingIoCs: boolean;
iocs: ThreatIntelIocData[];
registerRefreshHandler: (handler: () => void) => void;
}

export const IoCsTable: React.FC<IoCsTableProps> = ({ sourceId, iocs, loadingIoCs }) => {
export const IoCsTable: React.FC<IoCsTableProps> = ({
sourceId,
threatIntelService,
registerRefreshHandler,
}) => {
const [loading, setLoading] = useState(false);
const [searchString, setSearchString] = useState('');
const [paginationState, setPaginationState] = useState<Pagination>({
pageIndex: 0,
pageSize: 10,
totalItemCount: 0,
pageSizeOptions: [10, 25, 50],
});
const [iocs, setIocs] = useState([]);

const columns: EuiBasicTableColumn<ThreatIntelIocData>[] = [
{
name: 'Value',
Expand Down Expand Up @@ -46,18 +70,94 @@ export const IoCsTable: React.FC<IoCsTableProps> = ({ sourceId, iocs, loadingIoC
},
];

const getIocs = async () => {
if (sourceId) {
setLoading(true);
const iocsRes = await threatIntelService.getThreatIntelIocs({
feed_ids: sourceId,
startIndex: paginationState.pageIndex * paginationState.pageSize,
size: paginationState.pageSize,
searchString,
});

if (iocsRes.ok) {
setIocs(iocsRes.response.iocs);
setPaginationState({
...paginationState,
totalItemCount: iocsRes.response.total,
});
}
setLoading(false);
}
};

useEffect(() => {
registerRefreshHandler(getIocs);
}, []);

useEffect(() => {
getIocs();
}, [paginationState.pageIndex, paginationState.pageSize, searchString]);

const onTableChange = ({ page }: CriteriaWithPagination<ThreatIntelIocData>) => {
if (paginationState.pageIndex !== page.index || paginationState.pageSize !== page.size) {
setPaginationState({
...paginationState,
pageIndex: page.index,
pageSize: page.size,
});
}
};

const renderSearch = () => {
const schema = {
strict: true,
fields: {
value: {
type: 'string',
},
type: {
type: 'string',
},
created: {
type: 'date',
},
modified: {
type: 'date',
},
num_findings: {
type: 'number',
},
},
};

return (
<EuiSearchBar
defaultQuery={EuiSearchBar.Query.MATCH_ALL}
box={{
placeholder: 'Search',
incremental: false,
schema,
}}
onChange={({ queryText }) => setSearchString(queryText)}
/>
);
};

return (
<EuiPanel>
<EuiText>
<span>{iocs.length} malicious IoCs</span>
<span>{paginationState.totalItemCount} malicious IoCs</span>
</EuiText>
<EuiSpacer />
<EuiInMemoryTable
{renderSearch()}
<EuiSpacer />
<EuiBasicTable
columns={columns}
items={iocs}
search
pagination
loading={!sourceId || loadingIoCs}
pagination={paginationState}
onChange={onTableChange}
loading={!sourceId || loading}
/>
</EuiPanel>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,18 @@ export const SelectThreatIntelLogSources: React.FC<SelectThreatIntelLogSourcesPr
<EuiSpacer />
<EuiFormRow
label="Select Indexes/Aliases"
helpText="Using indexes and aliases is recommended for more precise field mapping"
helpText={
<span>
<a href="https://opensearch.org/docs/latest/im-plugin/index-alias" target="_blank">
Aliases
</a>
{' and '}
<a href="https://opensearch.org/docs/latest/im-plugin/data-streams/" target="_blank">
data streams
</a>{' '}
are recommended for optimal threat intel scans.
</span>
}
>
<EuiComboBox
options={logSourceOptions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,12 @@ export const ThreatIntelSourcesList: React.FC<ThreatIntelSourcesListProps> = ({
More details
</EuiButtonEmpty>
<EuiSpacer size="m" />
{source.enabled && (
<>
<EuiIcon
type={'dot'}
color={source.enabled ? 'success' : 'text'}
style={{ marginBottom: 4 }}
/>{' '}
Active
</>
)}
<EuiIcon
type={'dot'}
color={source.enabled_for_scan ? 'success' : 'text'}
style={{ marginBottom: 4 }}
/>{' '}
{source.enabled_for_scan ? 'Active' : 'Inactive'}
</>
}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useContext, useState } from 'react';
import { ThreatIntelIocData, ThreatIntelSourceItem } from '../../../../../types';
import React, { useContext, useState, useRef } from 'react';
import { ThreatIntelSourceItem } from '../../../../../types';
import { RouteComponentProps } from 'react-router-dom';
import { BREADCRUMBS, DEFAULT_EMPTY_DATA, ROUTES } from '../../../../utils/constants';
import { useEffect } from 'react';
Expand Down Expand Up @@ -49,8 +49,7 @@ export const ThreatIntelSource: React.FC<ThreatIntelSource> = ({
const sourceId =
source?.id ?? location.pathname.replace(`${ROUTES.THREAT_INTEL_SOURCE_DETAILS}/`, '');
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [iocs, setIocs] = useState<ThreatIntelIocData[]>([]);
const [loadingIoCs, setLoadingIoCs] = useState(true);
const refreshHandler = useRef(() => {});
const getSource = async (sourceId: string) => {
const res = await threatIntelService.getThreatIntelSource(sourceId);

Expand All @@ -65,22 +64,6 @@ export const ThreatIntelSource: React.FC<ThreatIntelSource> = ({
}
}, []);

const getIocs = async () => {
if (sourceId) {
setLoadingIoCs(true);
const iocsRes = await threatIntelService.getThreatIntelIocs({
feed_ids: sourceId,
startIndex: 0,
size: 10000,
});

if (iocsRes.ok) {
setIocs(iocsRes.response.iocs);
}
setLoadingIoCs(false);
}
};

useEffect(() => {
const baseCrumbs = [BREADCRUMBS.SECURITY_ANALYTICS, BREADCRUMBS.THREAT_INTEL_OVERVIEW];

Expand All @@ -89,8 +72,6 @@ export const ThreatIntelSource: React.FC<ThreatIntelSource> = ({
? baseCrumbs
: [...baseCrumbs, BREADCRUMBS.THREAT_INTEL_SOURCE_DETAILS(source.name, sourceId)]
);

getIocs();
}, [source]);

if (!source) {
Expand All @@ -105,7 +86,15 @@ export const ThreatIntelSource: React.FC<ThreatIntelSource> = ({
{
id: 'iocs',
name: <span>Indicators of Compromise</span>,
content: <IoCsTable sourceId={source?.id} iocs={iocs} loadingIoCs={loadingIoCs} />,
content: (
<IoCsTable
sourceId={source?.id}
threatIntelService={threatIntelService}
registerRefreshHandler={(handler) => {
refreshHandler.current = handler;
}}
/>
),
},
{
id: 'source-details',
Expand Down Expand Up @@ -139,7 +128,7 @@ export const ThreatIntelSource: React.FC<ThreatIntelSource> = ({
if (!res.ok) {
errorNotificationToast(notifications, 'refresh', 'source', res.error);
} else {
getIocs();
refreshHandler.current?.();
}
};

Expand Down
Loading

0 comments on commit d3548eb

Please sign in to comment.