mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution] Cypress tests for Artifact Tabs in Policy Details page RBAC (#149324)
## Summary Adds Cypress tests for RBAC functionality on Artifact Tabs in the Policy Details page.  --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
4e6c3f6540
commit
fc4d90dd21
10 changed files with 566 additions and 115 deletions
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* 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 { getEndpointSecurityPolicyManager } from '../../../../scripts/endpoint/common/roles_users/endpoint_security_policy_manager';
|
||||
import { getArtifactsListTestsData } from '../fixtures/artifacts_page';
|
||||
import {
|
||||
createPerPolicyArtifact,
|
||||
createArtifactList,
|
||||
removeAllArtifacts,
|
||||
removeExceptionsList,
|
||||
yieldFirstPolicyID,
|
||||
} from '../tasks/artifacts';
|
||||
import { loadEndpointDataForEventFiltersIfNeeded } from '../tasks/load_endpoint_data';
|
||||
import { login, loginWithCustomRole, loginWithRole, ROLE } from '../tasks/login';
|
||||
import { performUserActions } from '../tasks/perform_user_actions';
|
||||
|
||||
const loginWithPrivilegeAll = () => {
|
||||
loginWithRole(ROLE.endpoint_security_policy_manager);
|
||||
};
|
||||
|
||||
const loginWithPrivilegeRead = (privilegePrefix: string) => {
|
||||
const roleWithArtifactReadPrivilege = getRoleWithArtifactReadPrivilege(privilegePrefix);
|
||||
loginWithCustomRole('roleWithArtifactReadPrivilege', roleWithArtifactReadPrivilege);
|
||||
};
|
||||
|
||||
const loginWithPrivilegeNone = (privilegePrefix: string) => {
|
||||
const roleWithoutArtifactPrivilege = getRoleWithoutArtifactPrivilege(privilegePrefix);
|
||||
loginWithCustomRole('roleWithoutArtifactPrivilege', roleWithoutArtifactPrivilege);
|
||||
};
|
||||
|
||||
const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => {
|
||||
const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager();
|
||||
|
||||
return {
|
||||
...endpointSecurityPolicyManagerRole,
|
||||
kibana: [
|
||||
{
|
||||
...endpointSecurityPolicyManagerRole.kibana[0],
|
||||
feature: {
|
||||
...endpointSecurityPolicyManagerRole.kibana[0].feature,
|
||||
siem: [
|
||||
...endpointSecurityPolicyManagerRole.kibana[0].feature.siem.filter(
|
||||
(privilege) => privilege !== `${privilegePrefix}all`
|
||||
),
|
||||
`${privilegePrefix}read`,
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const getRoleWithoutArtifactPrivilege = (privilegePrefix: string) => {
|
||||
const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager();
|
||||
|
||||
return {
|
||||
...endpointSecurityPolicyManagerRole,
|
||||
kibana: [
|
||||
{
|
||||
...endpointSecurityPolicyManagerRole.kibana[0],
|
||||
feature: {
|
||||
...endpointSecurityPolicyManagerRole.kibana[0].feature,
|
||||
siem: endpointSecurityPolicyManagerRole.kibana[0].feature.siem.filter(
|
||||
(privilege) => privilege !== `${privilegePrefix}all`
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const visitArtifactTab = (tabId: string) => {
|
||||
visitPolicyDetailsPage();
|
||||
cy.get(`#${tabId}`).click();
|
||||
};
|
||||
|
||||
const visitPolicyDetailsPage = () => {
|
||||
cy.visit('/app/security/administration/policy');
|
||||
cy.getBySel('policyNameCellLink').eq(0).click({ force: true });
|
||||
cy.getBySel('policyDetailsPage').should('exist');
|
||||
cy.get('#settings').should('exist'); // waiting for Policy Settings tab
|
||||
};
|
||||
|
||||
describe('Artifact tabs in Policy Details page', () => {
|
||||
before(() => {
|
||||
login();
|
||||
loadEndpointDataForEventFiltersIfNeeded();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
login();
|
||||
removeAllArtifacts();
|
||||
});
|
||||
|
||||
for (const testData of getArtifactsListTestsData()) {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
removeExceptionsList(testData.createRequestBody.list_id);
|
||||
});
|
||||
|
||||
describe(`${testData.title} tab`, () => {
|
||||
it(`[NONE] User cannot see the tab for ${testData.title}`, () => {
|
||||
loginWithPrivilegeNone(testData.privilegePrefix);
|
||||
visitPolicyDetailsPage();
|
||||
|
||||
cy.get(`#${testData.tabId}`).should('not.exist');
|
||||
});
|
||||
|
||||
context(`Given there are no ${testData.title} entries`, () => {
|
||||
it(`[READ] User CANNOT add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getBySel('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
cy.getBySel('unexisting-manage-artifacts-button').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getBySel('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
cy.getBySel('unexisting-manage-artifacts-button').should('exist').click();
|
||||
|
||||
const { formActions, checkResults } = testData.create;
|
||||
|
||||
performUserActions(formActions);
|
||||
|
||||
// Add a per policy artifact - but not assign it to any policy
|
||||
cy.get('[data-test-subj$="-perPolicy"]').click(); // test-subjects are generated in different formats, but all ends with -perPolicy
|
||||
cy.getBySel(`${testData.pagePrefix}-flyout-submitButton`).click();
|
||||
|
||||
// Check new artifact is in the list
|
||||
for (const checkResult of checkResults) {
|
||||
cy.getBySel(checkResult.selector).should('have.text', checkResult.value);
|
||||
}
|
||||
|
||||
cy.getBySel('policyDetailsPage').should('not.exist');
|
||||
cy.getBySel('backToOrigin').contains(/^Back to .+ policy$/);
|
||||
|
||||
cy.getBySel('backToOrigin').click();
|
||||
cy.getBySel('policyDetailsPage').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
context(`Given there are no assigned ${testData.title} entries`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody);
|
||||
});
|
||||
|
||||
it(`[READ] User CANNOT Manage or Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getBySel('policy-artifacts-empty-unassigned').should('exist');
|
||||
|
||||
cy.getBySel('unassigned-manage-artifacts-button').should('not.exist');
|
||||
cy.getBySel('unassigned-assign-artifacts-button').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can Manage and Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getBySel('policy-artifacts-empty-unassigned').should('exist');
|
||||
|
||||
// Manage artifacts
|
||||
cy.getBySel('unassigned-manage-artifacts-button').should('exist').click();
|
||||
cy.location('pathname').should(
|
||||
'equal',
|
||||
`/app/security/administration/${testData.urlPath}`
|
||||
);
|
||||
cy.getBySel('backToOrigin').click();
|
||||
|
||||
// Assign artifacts
|
||||
cy.getBySel('unassigned-assign-artifacts-button').should('exist').click();
|
||||
|
||||
cy.getBySel('artifacts-assign-flyout').should('exist');
|
||||
cy.getBySel('artifacts-assign-confirm-button').should('be.disabled');
|
||||
|
||||
cy.getBySel(`${testData.artifactName}_checkbox`).click();
|
||||
cy.getBySel('artifacts-assign-confirm-button').click();
|
||||
});
|
||||
});
|
||||
|
||||
context(`Given there are assigned ${testData.title} entries`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
yieldFirstPolicyID().then((policyID) => {
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody, policyID);
|
||||
});
|
||||
});
|
||||
|
||||
it(`[READ] User can see ${testData.title} artifacts but CANNOT assign or remove from policy`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
// List of artifacts
|
||||
cy.getBySel('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getBySel('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
|
||||
// Cannot assign artifacts
|
||||
cy.getBySel('artifacts-assign-button').should('not.exist');
|
||||
|
||||
// Cannot remove from policy
|
||||
cy.getBySel('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getBySel('remove-from-policy-action').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can see ${testData.title} artifacts and can assign or remove artifacts from policy`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
// List of artifacts
|
||||
cy.getBySel('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getBySel('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
|
||||
// Assign artifacts
|
||||
cy.getBySel('artifacts-assign-button').should('exist').click();
|
||||
cy.getBySel('artifacts-assign-flyout').should('exist');
|
||||
cy.getBySel('artifacts-assign-cancel-button').click();
|
||||
|
||||
// Remove from policy
|
||||
cy.getBySel('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getBySel('remove-from-policy-action').click();
|
||||
cy.getBySel('confirmModalConfirmButton').click();
|
||||
|
||||
cy.contains('Successfully removed');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -5,27 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isEmpty } from 'lodash';
|
||||
import {
|
||||
ENDPOINT_ARTIFACT_LIST_IDS,
|
||||
EXCEPTION_LIST_URL,
|
||||
} from '@kbn/securitysolution-list-constants';
|
||||
import { BASE_ENDPOINT_ROUTE } from '../../../../common/endpoint/constants';
|
||||
import { login, loginWithRole, ROLE } from '../tasks/login';
|
||||
|
||||
import { type FormAction, getArtifactsListTestsData } from '../fixtures/artifacts_page';
|
||||
import { runEndpointLoaderScript } from '../tasks/run_endpoint_loader';
|
||||
|
||||
const removeAllArtifacts = () => {
|
||||
for (const listId of ENDPOINT_ARTIFACT_LIST_IDS) {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `${EXCEPTION_LIST_URL}?list_id=${listId}&namespace_type=agnostic`,
|
||||
headers: { 'kbn-xsrf': 'kibana' },
|
||||
failOnStatusCode: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
import { getArtifactsListTestsData } from '../fixtures/artifacts_page';
|
||||
import { removeAllArtifacts } from '../tasks/artifacts';
|
||||
import { performUserActions } from '../tasks/perform_user_actions';
|
||||
import { loadEndpointDataForEventFiltersIfNeeded } from '../tasks/load_endpoint_data';
|
||||
|
||||
const loginWithWriteAccess = (url: string) => {
|
||||
loginWithRole(ROLE.analyst_hunter);
|
||||
|
@ -42,41 +27,6 @@ const loginWithoutAccess = (url: string) => {
|
|||
cy.visit(url);
|
||||
};
|
||||
|
||||
// Checks for Endpoint data and creates it if needed
|
||||
const loadEndpointDataForEventFiltersIfNeeded = () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `${BASE_ENDPOINT_ROUTE}/suggestions/eventFilters`,
|
||||
body: {
|
||||
field: 'agent.type',
|
||||
query: '',
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'kibana' },
|
||||
failOnStatusCode: false,
|
||||
}).then(({ body }) => {
|
||||
if (isEmpty(body)) {
|
||||
runEndpointLoaderScript();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const runAction = (action: FormAction) => {
|
||||
let element;
|
||||
if (action.customSelector) {
|
||||
element = cy.get(action.customSelector);
|
||||
} else {
|
||||
element = cy.getBySel(action.selector || '');
|
||||
}
|
||||
|
||||
if (action.type === 'click') {
|
||||
element.click();
|
||||
} else if (action.type === 'input') {
|
||||
element.type(action.value || '');
|
||||
} else if (action.type === 'clear') {
|
||||
element.clear();
|
||||
}
|
||||
};
|
||||
|
||||
describe('Artifacts pages', () => {
|
||||
before(() => {
|
||||
login();
|
||||
|
@ -117,9 +67,7 @@ describe('Artifacts pages', () => {
|
|||
// Opens add flyout
|
||||
cy.getBySel(`${testData.pagePrefix}-emptyState-addButton`).click();
|
||||
|
||||
for (const formAction of testData.create.formActions) {
|
||||
runAction(formAction);
|
||||
}
|
||||
performUserActions(testData.create.formActions);
|
||||
|
||||
// Submit create artifact form
|
||||
cy.getBySel(`${testData.pagePrefix}-flyout-submitButton`).click();
|
||||
|
@ -153,9 +101,7 @@ describe('Artifacts pages', () => {
|
|||
cy.getBySel(`${testData.pagePrefix}-card-header-actions-button`).click();
|
||||
cy.getBySel(`${testData.pagePrefix}-card-cardEditAction`).click();
|
||||
|
||||
for (const formAction of testData.update.formActions) {
|
||||
runAction(formAction);
|
||||
}
|
||||
performUserActions(testData.update.formActions);
|
||||
|
||||
// Submit edit artifact form
|
||||
cy.getBySel(`${testData.pagePrefix}-flyout-submitButton`).click();
|
||||
|
|
|
@ -5,31 +5,49 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ArtifactElasticsearchProperties } from '@kbn/fleet-plugin/server/services';
|
||||
import type { TranslatedExceptionListItem } from '../../../../server/endpoint/schemas';
|
||||
import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants';
|
||||
import type { FormAction } from '../tasks/perform_user_actions';
|
||||
|
||||
export interface ArtifactResponseType {
|
||||
_index: string;
|
||||
_id: string;
|
||||
_score: number;
|
||||
_source: ArtifactElasticsearchProperties;
|
||||
interface FormEditingDescription {
|
||||
formActions: FormAction[];
|
||||
|
||||
checkResults: Array<{
|
||||
selector: string;
|
||||
value: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface ArtifactBodyType {
|
||||
entries: TranslatedExceptionListItem[];
|
||||
interface ArtifactsFixtureType {
|
||||
title: string;
|
||||
pagePrefix: string;
|
||||
tabId: string;
|
||||
artifactName: string;
|
||||
privilegePrefix: string;
|
||||
urlPath: string;
|
||||
emptyState: string;
|
||||
|
||||
create: FormEditingDescription;
|
||||
update: FormEditingDescription;
|
||||
|
||||
delete: {
|
||||
confirmSelector: string;
|
||||
card: string;
|
||||
};
|
||||
|
||||
createRequestBody: {
|
||||
list_id: string;
|
||||
entries: object[];
|
||||
os_types: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface FormAction {
|
||||
type: string;
|
||||
selector?: string;
|
||||
customSelector?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const getArtifactsListTestsData = () => [
|
||||
export const getArtifactsListTestsData = (): ArtifactsFixtureType[] => [
|
||||
{
|
||||
title: 'Trusted applications',
|
||||
pagePrefix: 'trustedAppsListPage',
|
||||
tabId: 'trustedApps',
|
||||
artifactName: 'Trusted application name',
|
||||
privilegePrefix: 'trusted_applications_',
|
||||
create: {
|
||||
formActions: [
|
||||
{
|
||||
|
@ -122,13 +140,40 @@ export const getArtifactsListTestsData = () => [
|
|||
confirmSelector: 'trustedAppsListPage-deleteModal-submitButton',
|
||||
card: 'trustedAppsListPage-card',
|
||||
},
|
||||
pageObject: 'trustedApplications',
|
||||
urlPath: 'trusted_apps',
|
||||
emptyState: 'trustedAppsListPage-emptyState',
|
||||
|
||||
createRequestBody: {
|
||||
list_id: ENDPOINT_ARTIFACT_LISTS.trustedApps.id,
|
||||
entries: [
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
field: 'trusted',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'true',
|
||||
},
|
||||
{
|
||||
field: 'subject_name',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'abcd',
|
||||
},
|
||||
],
|
||||
field: 'process.Ext.code_signature',
|
||||
type: 'nested',
|
||||
},
|
||||
],
|
||||
os_types: ['windows'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Event Filters',
|
||||
pagePrefix: 'EventFiltersListPage',
|
||||
tabId: 'eventFilters',
|
||||
artifactName: 'Event filter name',
|
||||
privilegePrefix: 'event_filters_',
|
||||
create: {
|
||||
formActions: [
|
||||
{
|
||||
|
@ -222,13 +267,28 @@ export const getArtifactsListTestsData = () => [
|
|||
confirmSelector: 'EventFiltersListPage-deleteModal-submitButton',
|
||||
card: 'EventFiltersListPage-card',
|
||||
},
|
||||
pageObject: 'eventFilters',
|
||||
urlPath: 'event_filters',
|
||||
emptyState: 'EventFiltersListPage-emptyState',
|
||||
|
||||
createRequestBody: {
|
||||
list_id: ENDPOINT_ARTIFACT_LISTS.eventFilters.id,
|
||||
entries: [
|
||||
{
|
||||
field: 'destination.ip',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: '1.2.3.4',
|
||||
},
|
||||
],
|
||||
os_types: ['windows'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Blocklist',
|
||||
pagePrefix: 'blocklistPage',
|
||||
tabId: 'blocklists',
|
||||
artifactName: 'Blocklist name',
|
||||
privilegePrefix: 'blocklist_',
|
||||
create: {
|
||||
formActions: [
|
||||
{
|
||||
|
@ -330,13 +390,34 @@ export const getArtifactsListTestsData = () => [
|
|||
confirmSelector: 'blocklistDeletionConfirm',
|
||||
card: 'blocklistCard',
|
||||
},
|
||||
pageObject: 'blocklist',
|
||||
urlPath: 'blocklist',
|
||||
emptyState: 'blocklistPage-emptyState',
|
||||
|
||||
createRequestBody: {
|
||||
list_id: ENDPOINT_ARTIFACT_LISTS.blocklists.id,
|
||||
entries: [
|
||||
{
|
||||
field: 'file.Ext.code_signature',
|
||||
entries: [
|
||||
{
|
||||
field: 'subject_name',
|
||||
value: ['wegwergwegw'],
|
||||
type: 'match_any',
|
||||
operator: 'included',
|
||||
},
|
||||
],
|
||||
type: 'nested',
|
||||
},
|
||||
],
|
||||
os_types: ['windows'],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Host isolation exceptions',
|
||||
pagePrefix: 'hostIsolationExceptionsListPage',
|
||||
tabId: 'hostIsolationExceptions',
|
||||
artifactName: 'Host Isolation exception name',
|
||||
privilegePrefix: 'host_isolation_exceptions_',
|
||||
create: {
|
||||
formActions: [
|
||||
{
|
||||
|
@ -411,8 +492,20 @@ export const getArtifactsListTestsData = () => [
|
|||
confirmSelector: 'hostIsolationExceptionsDeletionConfirm',
|
||||
card: 'hostIsolationExceptionsCard',
|
||||
},
|
||||
pageObject: 'hostIsolationExceptions',
|
||||
urlPath: 'host_isolation_exceptions',
|
||||
emptyState: 'hostIsolationExceptionsListPage-emptyState',
|
||||
|
||||
createRequestBody: {
|
||||
list_id: ENDPOINT_ARTIFACT_LISTS.hostIsolationExceptions.id,
|
||||
entries: [
|
||||
{
|
||||
field: 'destination.ip',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: '1.2.3.4',
|
||||
},
|
||||
],
|
||||
os_types: ['windows', 'linux', 'macos'],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 { PACKAGE_POLICY_API_ROOT } from '@kbn/fleet-plugin/common';
|
||||
import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
|
||||
import {
|
||||
ENDPOINT_ARTIFACT_LISTS,
|
||||
ENDPOINT_ARTIFACT_LIST_IDS,
|
||||
EXCEPTION_LIST_ITEM_URL,
|
||||
EXCEPTION_LIST_URL,
|
||||
} from '@kbn/securitysolution-list-constants';
|
||||
|
||||
const API_HEADER = { 'kbn-xsrf': 'kibana' };
|
||||
|
||||
export const removeAllArtifacts = () => {
|
||||
for (const listId of ENDPOINT_ARTIFACT_LIST_IDS) {
|
||||
removeExceptionsList(listId);
|
||||
}
|
||||
};
|
||||
|
||||
export const removeExceptionsList = (listId: string) => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `${EXCEPTION_LIST_URL}?list_id=${listId}&namespace_type=agnostic`,
|
||||
headers: API_HEADER,
|
||||
failOnStatusCode: false,
|
||||
}).then(({ status }) => {
|
||||
expect(status).to.be.oneOf([200, 404]); // should either be success or not found
|
||||
});
|
||||
};
|
||||
|
||||
const ENDPOINT_ARTIFACT_LIST_TYPES = {
|
||||
[ENDPOINT_ARTIFACT_LISTS.trustedApps.id]: ExceptionListTypeEnum.ENDPOINT,
|
||||
[ENDPOINT_ARTIFACT_LISTS.eventFilters.id]: ExceptionListTypeEnum.ENDPOINT_EVENTS,
|
||||
[ENDPOINT_ARTIFACT_LISTS.hostIsolationExceptions.id]:
|
||||
ExceptionListTypeEnum.ENDPOINT_HOST_ISOLATION_EXCEPTIONS,
|
||||
[ENDPOINT_ARTIFACT_LISTS.blocklists.id]: ExceptionListTypeEnum.ENDPOINT_BLOCKLISTS,
|
||||
};
|
||||
|
||||
export const createArtifactList = (listId: string) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: EXCEPTION_LIST_URL,
|
||||
headers: API_HEADER,
|
||||
body: {
|
||||
name: listId,
|
||||
description: 'This is a test list',
|
||||
list_id: listId,
|
||||
type: ENDPOINT_ARTIFACT_LIST_TYPES[listId],
|
||||
namespace_type: 'agnostic',
|
||||
},
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eql(200);
|
||||
expect(response.body.list_id).to.eql(listId);
|
||||
expect(response.body.type).to.eql(ENDPOINT_ARTIFACT_LIST_TYPES[listId]);
|
||||
});
|
||||
};
|
||||
|
||||
export const createPerPolicyArtifact = (name: string, body: object, policyId?: 'all' | string) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: EXCEPTION_LIST_ITEM_URL,
|
||||
|
||||
headers: API_HEADER,
|
||||
body: {
|
||||
name,
|
||||
description: '',
|
||||
type: 'simple',
|
||||
namespace_type: 'agnostic',
|
||||
...body,
|
||||
...(policyId ? { tags: [`policy:${policyId}`] } : {}),
|
||||
},
|
||||
}).then((response) => {
|
||||
expect(response.status).to.eql(200);
|
||||
expect(response.body.name).to.eql(name);
|
||||
});
|
||||
};
|
||||
|
||||
export const yieldFirstPolicyID = () => {
|
||||
return cy
|
||||
.request({
|
||||
method: 'GET',
|
||||
url: `${PACKAGE_POLICY_API_ROOT}?page=1&perPage=1&kuery=ingest-package-policies.package.name: endpoint`,
|
||||
})
|
||||
.then(({ body }) => {
|
||||
expect(body.items.length).to.be.least(1);
|
||||
return body.items[0].id;
|
||||
});
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 { isEmpty } from 'lodash';
|
||||
import { BASE_ENDPOINT_ROUTE } from '../../../../common/endpoint/constants';
|
||||
import { runEndpointLoaderScript } from './run_endpoint_loader';
|
||||
|
||||
// Checks for Endpoint data and creates it if needed
|
||||
export const loadEndpointDataForEventFiltersIfNeeded = () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `${BASE_ENDPOINT_ROUTE}/suggestions/eventFilters`,
|
||||
body: {
|
||||
field: 'agent.type',
|
||||
query: '',
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'kibana' },
|
||||
failOnStatusCode: false,
|
||||
}).then(({ body }) => {
|
||||
if (isEmpty(body)) {
|
||||
runEndpointLoaderScript();
|
||||
}
|
||||
});
|
||||
};
|
|
@ -19,6 +19,7 @@ import { getSocManager } from '../../../../scripts/endpoint/common/roles_users/s
|
|||
import { getPlatformEngineer } from '../../../../scripts/endpoint/common/roles_users/platform_engineer';
|
||||
import { getEndpointOperationsAnalyst } from '../../../../scripts/endpoint/common/roles_users/endpoint_operations_analyst';
|
||||
import { getEndpointSecurityPolicyManager } from '../../../../scripts/endpoint/common/roles_users/endpoint_security_policy_manager';
|
||||
import { getDetectionsEngineer } from '../../../../scripts/endpoint/common/roles_users/detections_engineer';
|
||||
|
||||
export enum ROLE {
|
||||
t1_analyst = 't1Analyst',
|
||||
|
@ -32,7 +33,7 @@ export enum ROLE {
|
|||
endpoint_security_policy_manager = 'endpointSecurityPolicyManager',
|
||||
}
|
||||
|
||||
export const rolesMapping: { [id: string]: Omit<Role, 'name'> } = {
|
||||
export const rolesMapping: { [key in ROLE]: Omit<Role, 'name'> } = {
|
||||
t1Analyst: getT1Analyst(),
|
||||
t2Analyst: getT2Analyst(),
|
||||
hunter: getHunter(),
|
||||
|
@ -41,6 +42,7 @@ export const rolesMapping: { [id: string]: Omit<Role, 'name'> } = {
|
|||
platformEngineer: getPlatformEngineer(),
|
||||
endpointOperationsAnalyst: getEndpointOperationsAnalyst(),
|
||||
endpointSecurityPolicyManager: getEndpointSecurityPolicyManager(),
|
||||
detectionsEngineer: getDetectionsEngineer(),
|
||||
};
|
||||
/**
|
||||
* Credentials in the `kibana.dev.yml` config file will be used to authenticate
|
||||
|
@ -77,6 +79,13 @@ const ELASTICSEARCH_PASSWORD = 'ELASTICSEARCH_PASSWORD';
|
|||
*/
|
||||
const LOGIN_API_ENDPOINT = '/internal/security/login';
|
||||
|
||||
const API_AUTH = {
|
||||
user: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
pass: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
};
|
||||
|
||||
const API_HEADERS = { 'kbn-xsrf': 'cypress' };
|
||||
|
||||
/**
|
||||
* cy.visit will default to the baseUrl which uses the default kibana test user
|
||||
* This function will override that functionality in cy.visit by building the baseUrl
|
||||
|
@ -85,7 +94,7 @@ const LOGIN_API_ENDPOINT = '/internal/security/login';
|
|||
* @param role string role/user to log in with
|
||||
* @param route string route to visit
|
||||
*/
|
||||
export const getUrlWithRoute = (role: ROLE, route: string) => {
|
||||
export const getUrlWithRoute = (role: string, route: string) => {
|
||||
const url = Cypress.config().baseUrl;
|
||||
const kibana = new URL(String(url));
|
||||
const theUrl = `${Url.format({
|
||||
|
@ -138,38 +147,32 @@ export const getCurlScriptEnvVars = () => ({
|
|||
});
|
||||
|
||||
export const createRoleAndUser = (role: ROLE) => {
|
||||
createCustomRoleAndUser(role, rolesMapping[role]);
|
||||
};
|
||||
|
||||
export const createCustomRoleAndUser = (role: string, rolePrivileges: Omit<Role, 'name'>) => {
|
||||
const env = getCurlScriptEnvVars();
|
||||
|
||||
// post the role
|
||||
cy.request({
|
||||
method: 'PUT',
|
||||
url: `${env.KIBANA_URL}/api/security/role/${role}`,
|
||||
body: rolesMapping[role],
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress',
|
||||
},
|
||||
auth: {
|
||||
user: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
pass: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
},
|
||||
body: rolePrivileges,
|
||||
headers: API_HEADERS,
|
||||
auth: API_AUTH,
|
||||
});
|
||||
|
||||
// post the user associated with the role to elasticsearch
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `${env.KIBANA_URL}/internal/security/users/${role}`,
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress',
|
||||
},
|
||||
headers: API_HEADERS,
|
||||
body: {
|
||||
username: role,
|
||||
password: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
roles: [role],
|
||||
},
|
||||
auth: {
|
||||
user: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
pass: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
},
|
||||
auth: API_AUTH,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -178,24 +181,14 @@ export const deleteRoleAndUser = (role: ROLE) => {
|
|||
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
auth: {
|
||||
user: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
pass: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress',
|
||||
},
|
||||
auth: API_AUTH,
|
||||
headers: API_HEADERS,
|
||||
url: `${env.KIBANA_URL}/internal/security/users/${role}`,
|
||||
});
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
auth: {
|
||||
user: Cypress.env(ELASTICSEARCH_USERNAME),
|
||||
pass: Cypress.env(ELASTICSEARCH_PASSWORD),
|
||||
},
|
||||
headers: {
|
||||
'kbn-xsrf': 'cypress',
|
||||
},
|
||||
auth: API_AUTH,
|
||||
headers: API_HEADERS,
|
||||
url: `${env.KIBANA_URL}/api/security/role/${role}`,
|
||||
});
|
||||
};
|
||||
|
@ -220,7 +213,11 @@ export const loginWithUser = (user: User) => {
|
|||
};
|
||||
|
||||
export const loginWithRole = async (role: ROLE) => {
|
||||
createRoleAndUser(role);
|
||||
loginWithCustomRole(role, rolesMapping[role]);
|
||||
};
|
||||
|
||||
export const loginWithCustomRole = async (role: string, rolePrivileges: Omit<Role, 'name'>) => {
|
||||
createCustomRoleAndUser(role, rolePrivileges);
|
||||
const theUrl = Url.format({
|
||||
auth: `${role}:changeme`,
|
||||
username: role,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export type ActionTypes = 'click' | 'input' | 'clear';
|
||||
|
||||
export interface FormAction {
|
||||
type: ActionTypes;
|
||||
selector?: string;
|
||||
customSelector?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export const performUserActions = (actions: FormAction[]) => {
|
||||
for (const action of actions) {
|
||||
performAction(action);
|
||||
}
|
||||
};
|
||||
|
||||
const performAction = (action: FormAction) => {
|
||||
let element;
|
||||
if (action.customSelector) {
|
||||
element = cy.get(action.customSelector);
|
||||
} else {
|
||||
element = cy.getBySel(action.selector || '');
|
||||
}
|
||||
|
||||
if (action.type === 'click') {
|
||||
element.click();
|
||||
} else if (action.type === 'input') {
|
||||
element.type(action.value || '');
|
||||
} else if (action.type === 'clear') {
|
||||
element.clear();
|
||||
}
|
||||
};
|
|
@ -24,6 +24,7 @@
|
|||
},
|
||||
"@kbn/security-plugin",
|
||||
"@kbn/securitysolution-list-constants",
|
||||
"@kbn/fleet-plugin"
|
||||
"@kbn/fleet-plugin",
|
||||
"@kbn/securitysolution-io-ts-list-types",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -540,6 +540,7 @@ export const BlockListForm = memo<ArtifactFormComponentProps>(
|
|||
onChange={handleOnPolicyChange}
|
||||
isLoading={policiesIsLoading}
|
||||
description={POLICY_SELECT_DESCRIPTION}
|
||||
data-test-subj={getTestId('effectedPolicies')}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</>
|
||||
|
|
|
@ -17,7 +17,15 @@ export const getEndpointSecurityPolicyManager: () => Omit<Role, 'name'> = () =>
|
|||
...noResponseActionsRole.kibana[0],
|
||||
feature: {
|
||||
...noResponseActionsRole.kibana[0].feature,
|
||||
siem: ['minimal_all'],
|
||||
siem: [
|
||||
'blocklist_all',
|
||||
'endpoint_list_all',
|
||||
'event_filters_all',
|
||||
'host_isolation_exceptions_all',
|
||||
'minimal_all',
|
||||
'policy_management_all',
|
||||
'trusted_applications_all',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue