-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EDR Workflows] The host isolation exception tab is hidden on the bas…
…ic license if no artifacts (#192562) This PR updates how the Host Isolation Exceptions tab is displayed based on the user’s permissions and license. The tab is always visible to platinum+ users. For lower-tier licenses, a check is performed: if a user has previously defined host isolation exceptions, they will see the tab and be able to view or remove existing exceptions. If they haven’t, the tab will be hidden, and the functionality will be inaccessible. Previously, even if a user didn’t have access to host isolation exceptions, they could still see and enter the Host Isolation Exceptions tab. To test locally: ESS: 1. Start ES + Kibana the regular way, with the default `trial` license. 2. Add HIE 3. Downgrade license (https://github.com/elastic/pzl-es-tools) 4. Verify that the license had been downgraded Serverless: 1. Start Serverless ES `yarn es serverless --clean --teardown --kill -E xpack.security.authc.api_key.enabled=true -E http.host=0.0.0.0 --projectType security` 2. Start Serverless Kibana `yarn serverless-security` 3. Add HIE 4. Modify `config/serverless.security.yml` to security and endpoint essential 5. Wait for Kibana to reload ESS: https://github.com/user-attachments/assets/75527af7-9d06-4da7-9e86-6ce6b22ac147 Serverless: https://github.com/user-attachments/assets/e89bd642-9e99-4a22-8b42-5997f7333ea6 --------- Co-authored-by: Ash <[email protected]> (cherry picked from commit 636baad)
- Loading branch information
1 parent
6cc4fdc
commit 77198a9
Showing
8 changed files
with
273 additions
and
74 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
..._solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { renderHook } from '@testing-library/react-hooks'; | ||
import { useHostIsolationExceptionsAccess } from './use_host_isolation_exceptions_access'; | ||
import { checkArtifactHasData } from '../../services/exceptions_list/check_artifact_has_data'; | ||
|
||
jest.mock('../../services/exceptions_list/check_artifact_has_data', () => ({ | ||
checkArtifactHasData: jest.fn(), | ||
})); | ||
|
||
const mockArtifactHasData = (hasData = true) => { | ||
(checkArtifactHasData as jest.Mock).mockResolvedValueOnce(hasData); | ||
}; | ||
|
||
describe('useHostIsolationExceptionsAccess', () => { | ||
const mockApiClient = jest.fn(); | ||
|
||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
const setupHook = (canAccess: boolean, canRead: boolean) => { | ||
return renderHook(() => useHostIsolationExceptionsAccess(canAccess, canRead, mockApiClient)); | ||
}; | ||
|
||
test('should set access to true if canAccessHostIsolationExceptions is true', async () => { | ||
const { result, waitFor } = setupHook(true, false); | ||
|
||
await waitFor(() => expect(result.current.hasAccessToHostIsolationExceptions).toBe(true)); | ||
}); | ||
|
||
test('should check for artifact data if canReadHostIsolationExceptions is true and canAccessHostIsolationExceptions is false', async () => { | ||
mockArtifactHasData(); | ||
|
||
const { result, waitFor } = setupHook(false, true); | ||
|
||
await waitFor(() => { | ||
expect(checkArtifactHasData).toHaveBeenCalledWith(mockApiClient()); | ||
expect(result.current.hasAccessToHostIsolationExceptions).toBe(true); | ||
}); | ||
}); | ||
|
||
test('should set access to false if canReadHostIsolationExceptions is true but no artifact data exists', async () => { | ||
mockArtifactHasData(false); | ||
|
||
const { result, waitFor } = setupHook(false, true); | ||
|
||
await waitFor(() => { | ||
expect(checkArtifactHasData).toHaveBeenCalledWith(mockApiClient()); | ||
expect(result.current.hasAccessToHostIsolationExceptions).toBe(false); | ||
}); | ||
}); | ||
|
||
test('should set access to false if neither canAccessHostIsolationExceptions nor canReadHostIsolationExceptions is true', async () => { | ||
const { result, waitFor } = setupHook(false, false); | ||
await waitFor(() => { | ||
expect(result.current.hasAccessToHostIsolationExceptions).toBe(false); | ||
}); | ||
}); | ||
|
||
test('should not call checkArtifactHasData if canAccessHostIsolationExceptions is true', async () => { | ||
const { result, waitFor } = setupHook(true, true); | ||
|
||
await waitFor(() => { | ||
expect(checkArtifactHasData).not.toHaveBeenCalled(); | ||
expect(result.current.hasAccessToHostIsolationExceptions).toBe(true); | ||
}); | ||
}); | ||
|
||
test('should set loading state correctly while checking access', async () => { | ||
const { result, waitFor } = setupHook(false, true); | ||
|
||
expect(result.current.isHostIsolationExceptionsAccessLoading).toBe(true); | ||
|
||
await waitFor(() => { | ||
expect(result.current.isHostIsolationExceptionsAccessLoading).toBe(false); | ||
}); | ||
}); | ||
}); |
43 changes: 43 additions & 0 deletions
43
...urity_solution/public/management/hooks/artifacts/use_host_isolation_exceptions_access.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { useEffect, useState } from 'react'; | ||
import { checkArtifactHasData } from '../../services/exceptions_list/check_artifact_has_data'; | ||
import type { ExceptionsListApiClient } from '../../services/exceptions_list/exceptions_list_api_client'; | ||
|
||
export const useHostIsolationExceptionsAccess = ( | ||
canAccessHostIsolationExceptions: boolean, | ||
canReadHostIsolationExceptions: boolean, | ||
getApiClient: () => ExceptionsListApiClient | ||
): { | ||
hasAccessToHostIsolationExceptions: boolean; | ||
isHostIsolationExceptionsAccessLoading: boolean; | ||
} => { | ||
const [hasAccess, setHasAccess] = useState<boolean | null>(null); | ||
|
||
useEffect(() => { | ||
(async () => { | ||
// Host isolation exceptions is a paid feature and therefore: | ||
// canAccessHostIsolationExceptions signifies if the user has required license to access the feature. | ||
// canReadHostIsolationExceptions, however, is a privilege that allows the user to read and delete the data even if the license is not sufficient (downgrade scenario). | ||
// In such cases, the tab should be visible only if there is existing data. | ||
if (canAccessHostIsolationExceptions) { | ||
setHasAccess(true); | ||
} else if (canReadHostIsolationExceptions) { | ||
const result = await checkArtifactHasData(getApiClient()); | ||
setHasAccess(result); | ||
} else { | ||
setHasAccess(false); | ||
} | ||
})(); | ||
}, [canAccessHostIsolationExceptions, canReadHostIsolationExceptions, getApiClient]); | ||
|
||
return { | ||
hasAccessToHostIsolationExceptions: !!hasAccess, | ||
isHostIsolationExceptionsAccessLoading: hasAccess === null, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.