Skip to content

Commit

Permalink
[Security Solution][Endpoint] Updated Response Console display of Tec…
Browse files Browse the repository at this point in the history
…h. Preview badge (#193182)

## Summary

PR updates the Response Console and Isolate/Release flyouts with:

- Removes the "Technical Preview" badge from the page/flyout title
- Adds [EUI's Beta
badge](https://eui.elastic.co/#/display/badge#beta-badge-type) to the
Agent Type Integration with labels of "Technical Preview"

___________

#### Response Console

|Display|Hover on icon|
|------|------|
|<img width="716" alt="image"
src="https://github.com/user-attachments/assets/838a7609-aaa2-439b-98d6-09cce2d1c4b4">|<img
width="835" alt="image"
src="https://github.com/user-attachments/assets/948a0516-31dd-456b-8025-3a5a79dd7815">|




#### Isolate/Release Flyout

|Display|Hover on icon|
|------|------|
|<img width="800" alt="image"
src="https://github.com/user-attachments/assets/01767b5d-4e4c-403b-a31b-ae7c960a5288">|<img
width="799" alt="image"
src="https://github.com/user-attachments/assets/577b0513-6a5d-486c-bcd3-38541022a818">|



#### Elastic Defend (no tech preview badge)


|Responder|Isolation panel from alerts|
|------|------|
|<img width="757" alt="image"
src="https://github.com/user-attachments/assets/a5de5be5-2e04-4d8c-8c32-139b155fba22">|<img
width="812" alt="image"
src="https://github.com/user-attachments/assets/3ea854a3-f44e-4b76-ac9b-91862c0ae964">|



___________





### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
paul-tavares authored Sep 17, 2024
1 parent 45c71c5 commit 090d9a2
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,19 @@ describe('AgentTypeIntegration component', () => {

expect(getByTestId('test-tooltipAnchor'));
});

if (agentType === 'sentinel_one' || agentType === 'crowdstrike') {
it('should display tech preview badge', () => {
const { getByTestId } = render();

expect(getByTestId('test-betaBadge')).not.toBeNull();
});
} else {
it('should NOT display tech preview badge', () => {
const { queryByTestId } = render();

expect(queryByTestId('test-betaBadge')).toBeNull();
});
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
* 2.0.
*/

import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import type { EuiTextProps } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText } from '@elastic/eui';
import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { useTestIdGenerator } from '../../../../../management/hooks/use_test_id_generator';
import { AgentTypeVendorLogo } from '../agent_type_vendor_logo';
import { getAgentTypeName } from '../../../../translations';
import {
getAgentTypeName,
TECHNICAL_PREVIEW,
TECHNICAL_PREVIEW_TOOLTIP,
} from '../../../../translations';
import type { ResponseActionAgentType } from '../../../../../../common/endpoint/service/response_actions/constants';

export const INTEGRATION_SECTION_LABEL = i18n.translate(
Expand All @@ -38,6 +42,10 @@ export const AgentTypeIntegration = memo<AgentTypeIntegrationProps>(
({ agentType, textSize = 's', layout = 'vertical', 'data-test-subj': dataTestSubj }) => {
const testId = useTestIdGenerator(dataTestSubj);

const isTechPreview = useMemo(() => {
return agentType === 'sentinel_one' || agentType === 'crowdstrike';
}, [agentType]);

return (
<EuiFlexGroup
direction={layout === 'horizontal' ? 'row' : 'column'}
Expand Down Expand Up @@ -69,6 +77,17 @@ export const AgentTypeIntegration = memo<AgentTypeIntegrationProps>(
{getAgentTypeName(agentType)}
</EuiText>
</EuiFlexItem>
{isTechPreview && (
<EuiFlexItem grow={false}>
<EuiBetaBadge
label={TECHNICAL_PREVIEW}
tooltipContent={TECHNICAL_PREVIEW_TOOLTIP}
iconType="beaker"
size="s"
data-test-subj={testId('betaBadge')}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { createAppRootMockRenderer, endpointAlertDataMock } from '../../../commo
import type { ResponseActionAgentType } from '../../../../common/endpoint/service/response_actions/constants';
import { RESPONSE_ACTION_AGENT_TYPE } from '../../../../common/endpoint/service/response_actions/constants';
import { ISOLATE_HOST, UNISOLATE_HOST } from '../../../common/components/endpoint/host_isolation';
import { TECHNICAL_PREVIEW } from '../../../common/translations';

jest.mock('./context');

Expand Down Expand Up @@ -58,8 +57,6 @@ describe('Isolation Flyout PanelHeader', () => {
action: IsolateHostPanelContext['isolateAction'];
agentType: ResponseActionAgentType;
title: string;
// if `expectedBadgeText` is `undefined`, then it validates that the badge is not displayed
expectedBadgeText: string | undefined;
}> = [];

for (const agentType of RESPONSE_ACTION_AGENT_TYPE) {
Expand All @@ -69,33 +66,22 @@ describe('Isolation Flyout PanelHeader', () => {
action,
agentType,
title: action === 'isolateHost' ? ISOLATE_HOST : UNISOLATE_HOST,
expectedBadgeText:
agentType === 'crowdstrike' || agentType === 'sentinel_one'
? TECHNICAL_PREVIEW
: undefined,
});
}
);
}

it.each(testConditions)(
'should display correct flyout header title for $action on agentType $agentType',
({ action, agentType, title, expectedBadgeText }) => {
({ action, agentType, title }) => {
setUseIsolateHostPanelContext({
isolateAction: action,
dataFormattedForFieldBrowser:
endpointAlertDataMock.generateAlertDetailsItemDataForAgentType(agentType),
});
const { getByTestId, queryByTestId } = render();
const { getByTestId } = render();

expect(getByTestId('flyoutHostIsolationHeaderTitle')).toHaveTextContent(title);

if (expectedBadgeText) {
expect(getByTestId('flyoutHostIsolationHeaderBadge')).toHaveTextContent(expectedBadgeText);
} else {
expect(queryByTestId('flyoutHostIsolationHeaderBadge')).toBeNull();
}

expect(getByTestId('flyoutHostIsolationHeaderIntegration'));
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
* 2.0.
*/

import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
import type { FC } from 'react';
import React, { useMemo } from 'react';
import React from 'react';
import { FlyoutHeader } from '@kbn/security-solution-common';
import { AgentTypeIntegration } from '../../../common/components/endpoint/agents/agent_type_integration';
import { useAlertResponseActionsSupport } from '../../../common/hooks/endpoint/use_alert_response_actions_support';
import { TECHNICAL_PREVIEW, TECHNICAL_PREVIEW_TOOLTIP } from '../../../common/translations';
import { useIsolateHostPanelContext } from './context';
import { FLYOUT_HEADER_TITLE_TEST_ID } from './test_ids';
import { ISOLATE_HOST, UNISOLATE_HOST } from '../../../common/components/endpoint';
Expand All @@ -22,14 +21,9 @@ import { ISOLATE_HOST, UNISOLATE_HOST } from '../../../common/components/endpoin
export const PanelHeader: FC = () => {
const { isolateAction, dataFormattedForFieldBrowser: data } = useIsolateHostPanelContext();
const {
isSupported: supportsResponseActions,
details: { agentType },
} = useAlertResponseActionsSupport(data);

const showTechPreviewBadge: boolean = useMemo(() => {
return supportsResponseActions && (agentType === 'sentinel_one' || agentType === 'crowdstrike');
}, [agentType, supportsResponseActions]);

const title = (
<EuiFlexGroup responsive gutterSize="s">
<EuiFlexItem grow={false} data-test-subj="flyoutHostIsolationHeaderTitle">
Expand All @@ -41,15 +35,6 @@ export const PanelHeader: FC = () => {
data-test-subj="flyoutHostIsolationHeaderIntegration"
/>
</EuiFlexItem>
{showTechPreviewBadge && (
<EuiFlexItem grow={false}>
<EuiBetaBadge
data-test-subj="flyoutHostIsolationHeaderBadge"
label={TECHNICAL_PREVIEW}
tooltipContent={TECHNICAL_PREVIEW_TOOLTIP}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
*/

import React, { useCallback } from 'react';
import { EuiBetaBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { TECHNICAL_PREVIEW, TECHNICAL_PREVIEW_TOOLTIP } from '../../common/translations';
import { useLicense } from '../../common/hooks/use_license';
import type { MaybeImmutable } from '../../../common/endpoint/types';
import type { EndpointCapabilities } from '../../../common/endpoint/service/response_actions/constants';
Expand All @@ -23,7 +21,6 @@ import {
import { useConsoleManager } from '../components/console';
import { MissingEncryptionKeyCallout } from '../components/missing_encryption_key_callout';
import { RESPONDER_PAGE_TITLE } from './translations';
import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features';

type ShowResponseActionsConsole = (props: ResponderInfoProps) => void;

Expand All @@ -47,19 +44,10 @@ export const useWithShowResponder = (): ShowResponseActionsConsole => {
const consoleManager = useConsoleManager();
const endpointPrivileges = useUserPrivileges().endpointPrivileges;
const isEnterpriseLicense = useLicense().isEnterprise();
const isSentinelOneV1Enabled = useIsExperimentalFeatureEnabled(
'responseActionsSentinelOneV1Enabled'
);
const responseActionsCrowdstrikeManualHostIsolationEnabled = useIsExperimentalFeatureEnabled(
'responseActionsCrowdstrikeManualHostIsolationEnabled'
);

return useCallback(
(props: ResponderInfoProps) => {
const { agentId, agentType, capabilities, hostName, platform } = props;
const isExternalEdr =
(isSentinelOneV1Enabled && agentType === 'sentinel_one') ||
(responseActionsCrowdstrikeManualHostIsolationEnabled && agentType === 'crowdstrike');

// If no authz, just exit and log something to the console
if (agentType === 'endpoint' && !endpointPrivileges.canAccessResponseConsole) {
Expand Down Expand Up @@ -109,19 +97,6 @@ export const useWithShowResponder = (): ShowResponseActionsConsole => {
},
consoleProps,
PageTitleComponent: () => {
if (isExternalEdr) {
return (
<EuiFlexGroup>
<EuiFlexItem>{RESPONDER_PAGE_TITLE}</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiBetaBadge
label={TECHNICAL_PREVIEW}
tooltipContent={TECHNICAL_PREVIEW_TOOLTIP}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
}
return <>{RESPONDER_PAGE_TITLE}</>;
},
ActionComponents: endpointPrivileges.canReadActionsLogManagement
Expand All @@ -141,12 +116,6 @@ export const useWithShowResponder = (): ShowResponseActionsConsole => {
.show();
}
},
[
isSentinelOneV1Enabled,
responseActionsCrowdstrikeManualHostIsolationEnabled,
endpointPrivileges,
isEnterpriseLicense,
consoleManager,
]
[endpointPrivileges, isEnterpriseLicense, consoleManager]
);
};

0 comments on commit 090d9a2

Please sign in to comment.