Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,34 @@ export const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d"';
export enum SecurityPageName {
administration = 'administration',
alerts = 'alerts',
authentications = 'authentications',
case = 'case',
caseConfigure = 'case-configure',
caseCreate = 'case-create',
detections = 'detections',
endpoints = 'endpoints',
eventFilters = 'event_filters',
events = 'events',
exceptions = 'exceptions',
explore = 'explore',
hosts = 'hosts',
hostsAnomalies = 'hosts-anomalies',
hostsExternalAlerts = 'hosts-external_alerts',
investigate = 'investigate',
network = 'network',
networkAnomalies = 'network-anomalies',
networkDns = 'network-dns',
networkExternalAlerts = 'network-external_alerts',
networkHttp = 'network-http',
networkTls = 'network-tls',
timelines = 'timelines',
timelinesTemplates = 'timelines-templates',
overview = 'overview',
policies = 'policies',
rules = 'rules',
timelines = 'timelines',
trustedApps = 'trusted_apps',
ueba = 'ueba',
uncommonProcesses = 'uncommon_processes',
}

export const TIMELINES_PATH = '/timelines';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,106 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { getDeepLinks } from '.';
import { Capabilities } from '../../../../../../src/core/public';
import { getDeepLinks, PREMIUM_DEEP_LINK_IDS } from '.';
import { AppDeepLink, Capabilities } from '../../../../../../src/core/public';
import { SecurityPageName } from '../types';
import { mockGlobalState } from '../../common/mock';

describe('public search functions', () => {
it('returns a subset of links for basic license, full set for platinum', () => {
const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null =>
deepLinks.reduce((deepLinkFound: AppDeepLink | null, deepLink) => {
if (deepLinkFound !== null) {
return deepLinkFound;
}
if (deepLink.id === id) {
return deepLink;
}
if (deepLink.deepLinks) {
return findDeepLink(id, deepLink.deepLinks);
}
return null;
}, null);

describe('deepLinks', () => {
it('should return a subset of links for basic license and the full set for platinum', () => {
const basicLicense = 'basic';
const platinumLicense = 'platinum';
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense);
const platinumLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense);

basicLinks.forEach((basicLink, index) => {
const platinumLink = platinumLinks[index];
expect(basicLink.id).toEqual(platinumLink.id);
const platinumDeepLinksCount = platinumLink.deepLinks?.length || 0;
const basicDeepLinksCount = basicLink.deepLinks?.length || 0;
expect(platinumDeepLinksCount).toBeGreaterThanOrEqual(basicDeepLinksCount);
const testAllBasicInPlatinum = (
basicDeepLinks: AppDeepLink[],
platinumDeepLinks: AppDeepLink[]
) => {
basicDeepLinks.forEach((basicDeepLink) => {
const platinumDeepLink = platinumDeepLinks.find(({ id }) => id === basicDeepLink.id);
expect(platinumDeepLink).toBeTruthy();

if (platinumDeepLink && basicDeepLink.deepLinks) {
expect(platinumDeepLink.deepLinks).toBeTruthy();

if (platinumDeepLink.deepLinks) {
testAllBasicInPlatinum(basicDeepLink.deepLinks, platinumDeepLink.deepLinks);
}
}
});
};
testAllBasicInPlatinum(basicLinks, platinumLinks);

PREMIUM_DEEP_LINK_IDS.forEach((premiumDeepLinkId) => {
expect(findDeepLink(premiumDeepLinkId, platinumLinks)).toBeTruthy();
expect(findDeepLink(premiumDeepLinkId, basicLinks)).toBeFalsy();
});
});

it('returns case links for basic license with only read_cases capabilities', () => {
it('should return case links for basic license with only read_cases capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
siem: { read_cases: true, crud_cases: false },
} as unknown as Capabilities);

expect(basicLinks.some((l) => l.id === SecurityPageName.case)).toBeTruthy();
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy();
});

it('returns case links with NO deepLinks for basic license with only read_cases capabilities', () => {
it('should return case links with NO deepLinks for basic license with only read_cases capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
siem: { read_cases: true, crud_cases: false },
} as unknown as Capabilities);

expect(
basicLinks.find((l) => l.id === SecurityPageName.case)?.deepLinks?.length === 0
).toBeTruthy();
expect(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length === 0).toBeTruthy();
});

it('returns case links with deepLinks for basic license with crud_cases capabilities', () => {
it('should return case links with deepLinks for basic license with crud_cases capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
siem: { read_cases: true, crud_cases: true },
} as unknown as Capabilities);

expect(
(basicLinks.find((l) => l.id === SecurityPageName.case)?.deepLinks?.length ?? 0) > 0
(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length ?? 0) > 0
).toBeTruthy();
});

it('returns NO case links for basic license with NO read_cases capabilities', () => {
it('should return NO case links for basic license with NO read_cases capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, {
siem: { read_cases: false, crud_cases: false },
} as unknown as Capabilities);

expect(basicLinks.some((l) => l.id === SecurityPageName.case)).toBeFalsy();
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeFalsy();
});

it('returns case links for basic license with undefined capabilities', () => {
it('should return case links for basic license with undefined capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(
mockGlobalState.app.enableExperimental,
basicLicense,
undefined
);

expect(basicLinks.some((l) => l.id === SecurityPageName.case)).toBeTruthy();
expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy();
});

it('returns case deepLinks for basic license with undefined capabilities', () => {
it('should return case deepLinks for basic license with undefined capabilities', () => {
const basicLicense = 'basic';
const basicLinks = getDeepLinks(
mockGlobalState.app.enableExperimental,
Expand All @@ -85,20 +112,20 @@ describe('public search functions', () => {
);

expect(
(basicLinks.find((l) => l.id === SecurityPageName.case)?.deepLinks?.length ?? 0) > 0
(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length ?? 0) > 0
).toBeTruthy();
});

it('returns NO ueba link when enableExperimental.uebaEnabled === false', () => {
it('should return NO ueba link when enableExperimental.uebaEnabled === false', () => {
const deepLinks = getDeepLinks(mockGlobalState.app.enableExperimental);
expect(deepLinks.some((l) => l.id === SecurityPageName.ueba)).toBeFalsy();
expect(findDeepLink(SecurityPageName.ueba, deepLinks)).toBeFalsy();
});

it('returns ueba link when enableExperimental.uebaEnabled === true', () => {
it('should return ueba link when enableExperimental.uebaEnabled === true', () => {
const deepLinks = getDeepLinks({
...mockGlobalState.app.enableExperimental,
uebaEnabled: true,
});
expect(deepLinks.some((l) => l.id === SecurityPageName.ueba)).toBeTruthy();
expect(findDeepLink(SecurityPageName.ueba, deepLinks)).toBeTruthy();
});
});
Loading