[Security Solution][Endpoint] Correctly show Host Isolation page for Platinum+ users (#143366)

This commit is contained in:
Ashokaditya 2022-10-14 22:35:38 +02:00 committed by GitHub
parent d9d10f2cbb
commit 90b9c4483c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 22 deletions

View file

@ -60,7 +60,7 @@ describe('links', () => {
} as unknown as StartPlugins);
});
it('it returns all links without filtering when having isolate permissions', async () => {
it('it returns all links without filtering when having isolate permission', async () => {
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true);
fakeHttpServices.get.mockResolvedValue({ total: 0 });
const filteredLinks = await getManagementFilteredLinks(
@ -70,30 +70,67 @@ describe('links', () => {
expect(filteredLinks).toEqual(links);
});
it('it returns all links without filtering when not having isolation permissions but has at least one host isolation exceptions entry', async () => {
it('it returns all but response actions history link when NO isolation permission but HAS at least one host isolation exceptions entry', async () => {
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
fakeHttpServices.get.mockResolvedValue({ total: 1 });
const filteredLinks = await getManagementFilteredLinks(
coreMockStarted,
getPlugins(['superuser'])
);
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
expect(filteredLinks).toEqual(links);
});
it('it returns all but response actions history when no access privilege to either response actions history or HIE but have at least one HIE entry', async () => {
fakeHttpServices.get.mockResolvedValue({ total: 1 });
const filteredLinks = await getManagementFilteredLinks(
coreMockStarted,
getPlugins(['superuser'])
);
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
expect(filteredLinks).toEqual({
...links,
links: links.links?.filter((link) => link.id !== SecurityPageName.responseActionsHistory),
});
});
it('it returns filtered links when not having isolation permissions and no host isolation exceptions entry', async () => {
it('it returns all but response actions history when NO access to either response actions history or HIE but have at least one HIE entry', async () => {
fakeHttpServices.get.mockResolvedValue({ total: 1 });
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
const filteredLinks = await getManagementFilteredLinks(
coreMockStarted,
getPlugins(['superuser'])
);
expect(filteredLinks).toEqual({
...links,
links: links.links?.filter((link) => link.id !== SecurityPageName.responseActionsHistory),
});
});
it('it returns all but response actions history when NO enterprise license and can not isolate but HAS an HIE entry', async () => {
(licenseService.isEnterprise as jest.Mock).mockReturnValue(false);
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
fakeHttpServices.get.mockResolvedValue({ total: 1 });
const filteredLinks = await getManagementFilteredLinks(
coreMockStarted,
getPlugins(['superuser'])
);
expect(filteredLinks).toEqual({
...links,
links: links.links?.filter((link) => link.id !== SecurityPageName.responseActionsHistory),
});
});
it('it returns all but response actions history and HIE links when NO enterprise license and no HIE entry', async () => {
(licenseService.isEnterprise as jest.Mock).mockReturnValue(false);
fakeHttpServices.get.mockResolvedValue({ total: 0 });
const filteredLinks = await getManagementFilteredLinks(
coreMockStarted,
getPlugins(['superuser'])
);
expect(filteredLinks).toEqual({
...links,
links: links.links?.filter(
(link) =>
link.id !== SecurityPageName.hostIsolationExceptions &&
link.id !== SecurityPageName.responseActionsHistory
),
});
});
it('it returns filtered links when not having NO isolation permission and NO host isolation exceptions entry', async () => {
fakeHttpServices.get.mockResolvedValue({ total: 0 });
(licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false);
const filteredLinks = await getManagementFilteredLinks(coreMockStarted, getPlugins([]));

View file

@ -232,6 +232,13 @@ const excludeLinks = (linkIds: SecurityPageName[]) => ({
links: links.links?.filter((link) => !linkIds.includes(link.id)),
});
const getHostIsolationExceptionTotal = async (http: CoreStart['http']) => {
const hostIsolationExceptionsApiClientInstance =
HostIsolationExceptionsApiClient.getInstance(http);
const summaryResponse = await hostIsolationExceptionsApiClientInstance.summary();
return summaryResponse.total;
};
export const getManagementFilteredLinks = async (
core: CoreStart,
plugins: StartPlugins
@ -242,7 +249,7 @@ export const getManagementFilteredLinks = async (
try {
const currentUserResponse = await plugins.security.authc.getCurrentUser();
const privileges = fleetAuthz
const { canAccessEndpointManagement, canIsolateHost, canReadActionsLogManagement } = fleetAuthz
? calculateEndpointAuthz(
licenseService,
fleetAuthz,
@ -251,18 +258,28 @@ export const getManagementFilteredLinks = async (
endpointPermissions
)
: getEndpointAuthzInitialState();
if (!privileges.canAccessEndpointManagement) {
if (!canAccessEndpointManagement) {
return excludeLinks([
SecurityPageName.hostIsolationExceptions,
SecurityPageName.responseActionsHistory,
]);
}
if (!privileges.canIsolateHost || !privileges.canReadActionsLogManagement) {
const hostIsolationExceptionsApiClientInstance = HostIsolationExceptionsApiClient.getInstance(
core.http
);
const summaryResponse = await hostIsolationExceptionsApiClientInstance.summary();
if (!summaryResponse.total) {
if (!canReadActionsLogManagement) {
// <= enterprise license
const hostExceptionCount = await getHostIsolationExceptionTotal(core.http);
if (!canIsolateHost && !hostExceptionCount) {
return excludeLinks([
SecurityPageName.hostIsolationExceptions,
SecurityPageName.responseActionsHistory,
]);
}
return excludeLinks([SecurityPageName.responseActionsHistory]);
} else if (!canIsolateHost) {
const hostExceptionCount = await getHostIsolationExceptionTotal(core.http);
if (!hostExceptionCount) {
// <= platinum so exclude also links that require enterprise
return excludeLinks([
SecurityPageName.hostIsolationExceptions,
SecurityPageName.responseActionsHistory,