Skip to content

Commit

Permalink
Alert Title in Alert Tables + minor changes on AlertDetails & AlertTa…
Browse files Browse the repository at this point in the history
…bles (#707)

* Add title in Alerts as required

* Removed dedupString from alertSummary

* isHash Util function and change for breadcrumb

* Added updateTime

* Updated AlertTables to a new format

* Added dedupString to AlertDetails that missing rule

* Fixed Fragments for Alerts

* Added severity to AlertSummary

* Updated Alert table on RuleDetails

* Changed flex for Title

* Reinstated licence for schema

* Updated naming for regex

* Changed flex for Title Column

* Fixed broken <Link>

Co-authored-by: Kostas Papageorgiou <[email protected]>
Co-authored-by: Aggelos Arvanitakis <[email protected]>
  • Loading branch information
3 people authored Apr 22, 2020
1 parent bb87501 commit ec23c4c
Show file tree
Hide file tree
Showing 17 changed files with 184 additions and 78 deletions.
3 changes: 2 additions & 1 deletion api/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ type LogIntegrationHealth {
type AlertDetails {
alertId: ID!
ruleId: ID
title: String!
creationTime: AWSDateTime!
updateTime: AWSDateTime!
eventsMatched: Int!
Expand All @@ -132,10 +133,10 @@ type AlertSummary {
alertId: String!
creationTime: AWSDateTime!
eventsMatched: Int!
title: String!
updateTime: AWSDateTime!
ruleId: String
severity: String
dedupString: String!
}

input ListRulesInput {
Expand Down
6 changes: 4 additions & 2 deletions web/__generated__/schema.tsx

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions web/src/components/Breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

import { Box, Breadcrumbs as PounceBreadcrumbs } from 'pouncejs';
import * as React from 'react';
import { isGuid, capitalize } from 'Helpers/utils';
import { isGuid, capitalize, shortenId, isHash } from 'Helpers/utils';
import { Link as RRLink } from 'react-router-dom';
import useRouter from 'Hooks/useRouter';

const transformBreadcrumbText = text => (isHash(text) ? shortenId(text) : text);

const Breadcrumbs: React.FC = () => {
const {
location: { pathname },
Expand Down Expand Up @@ -60,7 +62,7 @@ const Breadcrumbs: React.FC = () => {
items={fragments}
itemRenderer={item => (
<Box as={RRLink} to={item.href} display="block" maxWidth="450px" truncated>
{item.text}
{transformBreadcrumbText(item.text)}
</Box>
)}
/>
Expand Down
2 changes: 2 additions & 0 deletions web/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const INCLUDE_UPPERCASE_REGEX = new RegExp('(?=.*[A-Z])');

export const INCLUDE_SPECIAL_CHAR_REGEX = new RegExp('[^\\d\\sA-Za-z]');

export const CHECK_IF_HASH_REGEX = new RegExp('[a-f0-9]{32}');

export const DEFAULT_POLICY_FUNCTION =
'def policy(resource):\n\t# Return False if the resource is non-compliant, which will trigger alerts/remediation.\n\treturn True';

Expand Down
2 changes: 2 additions & 0 deletions web/src/graphql/fragments/AlertDetailsFull.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type AlertDetailsFull = Pick<
Types.AlertDetails,
| 'alertId'
| 'ruleId'
| 'title'
| 'creationTime'
| 'eventsMatched'
| 'updateTime'
Expand All @@ -38,6 +39,7 @@ export const AlertDetailsFull = gql`
fragment AlertDetailsFull on AlertDetails {
alertId
ruleId
title
creationTime
eventsMatched
updateTime
Expand Down
1 change: 1 addition & 0 deletions web/src/graphql/fragments/AlertDetailsFull.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fragment AlertDetailsFull on AlertDetails {
alertId
ruleId
title
creationTime
eventsMatched
updateTime
Expand Down
40 changes: 40 additions & 0 deletions web/src/graphql/fragments/AlertSummaryFull.generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Panther is a Cloud-Native SIEM for the Modern Security Team.
* Copyright (C) 2020 Panther Labs Inc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

/* eslint-disable import/order, import/no-duplicates, @typescript-eslint/no-unused-vars */

import * as Types from '../../../__generated__/schema';

import gql from 'graphql-tag';

export type AlertSummaryFull = Pick<
Types.AlertSummary,
'alertId' | 'ruleId' | 'title' | 'severity' | 'creationTime' | 'eventsMatched' | 'updateTime'
>;

export const AlertSummaryFull = gql`
fragment AlertSummaryFull on AlertSummary {
alertId
ruleId
title
severity
creationTime
eventsMatched
updateTime
}
`;
9 changes: 9 additions & 0 deletions web/src/graphql/fragments/AlertSummaryFull.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fragment AlertSummaryFull on AlertSummary {
alertId
ruleId
title
severity
creationTime
eventsMatched
updateTime
}
7 changes: 7 additions & 0 deletions web/src/helpers/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
INCLUDE_LOWERCASE_REGEX,
INCLUDE_SPECIAL_CHAR_REGEX,
INCLUDE_UPPERCASE_REGEX,
CHECK_IF_HASH_REGEX,
} from 'Source/constants';
import mapValues from 'lodash-es/mapValues';
import sum from 'lodash-es/sum';
Expand Down Expand Up @@ -101,6 +102,12 @@ export const formatDatetime = (datetime: string) => {
);
};

/** Slice text to 7 characters, mostly used for hashIds */
export const shortenId = (id: string) => id.slice(0, 7);

/** Checking if string is a proper hash */
export const isHash = (str: string) => CHECK_IF_HASH_REGEX.test(str);

/** Converts minutes integer to representative string i.e. 15 -> 15min, 120 -> 2h */
export const minutesToString = (minutes: number) =>
minutes < 60 ? `${minutes}min` : `${minutes / 60}h`;
Expand Down
51 changes: 46 additions & 5 deletions web/src/pages/AlertDetails/AlertDetailsInfo/AlertDetailsInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Linkify from 'Components/Linkify';
import { SEVERITY_COLOR_MAP } from 'Source/constants';
import { formatDatetime } from 'Helpers/utils';
import Panel from 'Components/Panel';
import { Link as RRLink } from 'react-router-dom';

interface AlertDetailsInfoProps {
alert: AlertDetails;
Expand All @@ -44,7 +45,15 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
<SimpleGrid columns={3} spacing={6}>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
ID
TITLE
</Label>
<Text size="medium" color="black">
{alert.title}
</Text>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
FULL ALERT ID
</Label>
<Text size="medium" color="black">
{alert.alertId}
Expand All @@ -61,6 +70,14 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
<Badge color="pink">DELETED</Badge>
</Flex>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
DEDUP STRING
</Label>
<Text size="medium" color="black">
{alert.dedupString}
</Text>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
CREATED AT
Expand All @@ -69,6 +86,14 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
{formatDatetime(alert.creationTime)}
</Text>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
LAST MATCHED AT
</Label>
<Text size="medium" color="black">
{formatDatetime(alert.updateTime)}
</Text>
</Box>
</SimpleGrid>
</Panel>
</Box>
Expand All @@ -80,7 +105,15 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
<SimpleGrid columns={3} spacing={6}>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
ID
TITLE
</Label>
<Text size="medium" color="black">
{alert.title}
</Text>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
FULL ALERT ID
</Label>
<Text size="medium" color="black">
{alert.alertId}
Expand All @@ -91,7 +124,7 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
RULE ORIGIN
</Label>
{rule ? (
<Link color="blue300" to={urls.logAnalysis.rules.details(rule.id)}>
<Link color="blue300" as={RRLink} to={urls.logAnalysis.rules.details(rule.id)}>
{rule.displayName || rule.id}
</Link>
) : (
Expand Down Expand Up @@ -163,6 +196,14 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
</Text>
)}
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
DEDUP STRING
</Label>
<Text size="medium" color="black">
{alert.dedupString}
</Text>
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
CREATED AT
Expand All @@ -173,10 +214,10 @@ const AlertDetailsInfo: React.FC<AlertDetailsInfoProps> = ({ alert, rule }) => {
</Box>
<Box my={1}>
<Label mb={1} as="div" size="small" color="grey300">
DEDUP STRING
LAST MATCHED AT
</Label>
<Text size="medium" color="black">
{alert.dedupString}
{formatDatetime(alert.updateTime)}
</Text>
</Box>
</SimpleGrid>
Expand Down
9 changes: 7 additions & 2 deletions web/src/pages/ListAlerts/ListAlertsTable/ListAlertsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,24 @@ import { AlertSummary } from 'Generated/schema';
import { generateEnumerationColumn } from 'Helpers/utils';
import { Table } from 'pouncejs';
import columns from 'Pages/ListAlerts/columns';
import urls from 'Source/urls';
import useRouter from 'Hooks/useRouter';

interface ListAlertsTableProps {
items?: Partial<AlertSummary>[];
items?: AlertSummary[];
enumerationStartIndex?: number;
}

const ListAlertsTable: React.FC<ListAlertsTableProps> = ({ items }) => {
const { history } = useRouter();

const enumeratedColumns = [generateEnumerationColumn(0), ...columns];
return (
<Table<Partial<AlertSummary>>
<Table<AlertSummary>
columns={enumeratedColumns}
getItemKey={alert => alert.alertId}
items={items}
onSelect={alert => history.push(urls.logAnalysis.alerts.details(alert.alertId))}
/>
);
};
Expand Down
Loading

0 comments on commit ec23c4c

Please sign in to comment.