Skip to content

Commit

Permalink
[Security Solution] Install/Update Prebuilt Rules Test Implementation…
Browse files Browse the repository at this point in the history
… refactor (elastic#165488)

Fixes: elastic#148192

(Tick the two open checkboxes in that issue when merging this PR)

## Summary

This PR rewrites/refactors Cypress tests for the Installation and
Upgrade of Prebuilt Rules implemented in
elastic#161687. Most of the changes here
address feedback received in that PR - answered those comments there.

- RBAC/Authorization: adds tests scenarios for users with full
privileges (happy path)
- Gets rid of huge util helpers such as
`assertRuleAvailableForInstallAndInstallOne` and rewrites test cases in
a more descriptive way, with step by step actions.
- Gets rid of complex logic in tests and their helpers - removing
if/else logic within them and removing optional flags passed to helpers.
- Fixes `bulkCreateRuleAssets` util and uses it in other helpers to
install multiple `security-rule` assets with a single bulk request to
ES.

Additionally: checked `installation_and_upgrade.md` test plan to make
sure it matches with the test in place. Added
[link](elastic#166215) to a ticket for
a to-do task for the sections:
- Rule installation workflow: filtering, sorting, pagination
- Rule upgrade workflow: filtering, sorting, pagination

## Flaky test runner


~~https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3420~~
~~🟢~~

https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3513

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
jpdjere and kibanamachine authored Oct 17, 2023
1 parent 3164eca commit 24c008b
Show file tree
Hide file tree
Showing 17 changed files with 468 additions and 402 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ And user should see a CTA that leads to the Rule Management page

### Rule installation workflow: filtering, sorting, pagination

TODO: add scenarios
TODO: add scenarios https://github.com/elastic/kibana/issues/166215

### Rule installation workflow: misc cases

Expand Down Expand Up @@ -515,7 +515,7 @@ And user should NOT see the Rule Updates table

### Rule upgrade workflow: filtering, sorting, pagination

TODO: add scenarios
TODO: add scenarios https://github.com/elastic/kibana/issues/166215

### Rule upgrade workflow: misc cases

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const RuleName = ({ name, ruleId }: RuleNameProps) => {
onClick={() => {
openRulePreview(ruleId);
}}
data-test-subj="ruleName"
>
{name}
</EuiLink>
Expand Down Expand Up @@ -121,7 +122,14 @@ const createInstallButtonColumn = (
onClick={() => installOneRule(ruleId)}
data-test-subj={`installSinglePrebuiltRuleButton-${ruleId}`}
>
{isRuleInstalling ? <EuiLoadingSpinner size="s" /> : i18n.INSTALL_RULE_BUTTON}
{isRuleInstalling ? (
<EuiLoadingSpinner
size="s"
data-test-subj={`installSinglePrebuiltRuleButton-loadingSpinner-${ruleId}`}
/>
) : (
i18n.INSTALL_RULE_BUTTON
)}
</EuiButtonEmpty>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const RuleName = ({ name, ruleId }: RuleNameProps) => {
onClick={() => {
openRulePreview(ruleId);
}}
data-test-subj="ruleName"
>
{name}
</EuiLink>
Expand Down Expand Up @@ -120,7 +121,14 @@ const createUpgradeButtonColumn = (
onClick={() => upgradeOneRule(ruleId)}
data-test-subj={`upgradeSinglePrebuiltRuleButton-${ruleId}`}
>
{isRuleUpgrading ? <EuiLoadingSpinner size="s" /> : i18n.UPDATE_RULE_BUTTON}
{isRuleUpgrading ? (
<EuiLoadingSpinner
size="s"
data-test-subj={`upgradeSinglePrebuiltRuleButton-loadingSpinner-${ruleId}`}
/>
) : (
i18n.UPDATE_RULE_BUTTON
)}
</EuiButtonEmpty>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,30 @@ import {
import { ROLES } from '@kbn/security-solution-plugin/common/test';

import { createRuleAssetSavedObject } from '../../../helpers/rules';
import { createAndInstallMockedPrebuiltRules } from '../../../tasks/api_calls/prebuilt_rules';
import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common';
import { login } from '../../../tasks/login';
import {
createAndInstallMockedPrebuiltRules,
installPrebuiltRuleAssets,
preventPrebuiltRulesPackageInstallation,
} from '../../../tasks/api_calls/prebuilt_rules';
import { visit } from '../../../tasks/navigation';
import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management';
import {
ADD_ELASTIC_RULES_BTN,
getInstallSingleRuleButtonByRuleId,
getUpgradeSingleRuleButtonByRuleId,
GO_BACK_TO_RULES_TABLE_BUTTON,
INSTALL_ALL_RULES_BUTTON,
RULES_MANAGEMENT_TAB,
RULES_MANAGEMENT_TABLE,
RULES_UPDATES_TAB,
RULE_CHECKBOX,
UPGRADE_ALL_RULES_BUTTON,
} from '../../../screens/alerts_detection_rules';
import { cleanKibana } from '../../../tasks/common';
import { login } from '../../../tasks/login';

// Rule to test update
const RULE_1_ID = 'rule_1';
const RULE_2_ID = 'rule_2';
const OUTDATED_RULE_1 = createRuleAssetSavedObject({
name: 'Outdated rule 1',
rule_id: RULE_1_ID,
Expand All @@ -40,52 +47,44 @@ const UPDATED_RULE_1 = createRuleAssetSavedObject({
rule_id: RULE_1_ID,
version: 2,
});
const OUTDATED_RULE_2 = createRuleAssetSavedObject({
name: 'Outdated rule 2',

// Rule to test installation
const RULE_2_ID = 'rule_2';
const RULE_2 = createRuleAssetSavedObject({
name: 'Rule 2',
rule_id: RULE_2_ID,
version: 1,
});
const UPDATED_RULE_2 = createRuleAssetSavedObject({
name: 'Updated rule 2',
rule_id: RULE_2_ID,
version: 2,
});

const loadPageAsReadOnlyUser = (url: string) => {
login(ROLES.reader);
visit(url, { role: ROLES.reader });
};

const loginPageAsWriteAuthorizedUser = (url: string) => {
login(ROLES.hunter);
visit(url);
};

// TODO: https://github.com/elastic/kibana/issues/164451 We should find a way to make this spec work in Serverless
// TODO: https://github.com/elastic/kibana/issues/161540
describe(
'Detection rules, Prebuilt Rules Installation and Update - Authorization/RBAC',
{ tags: ['@ess', '@serverless', '@skipInServerless'] },
() => {
beforeEach(() => {
login();
resetRulesTableState();
deleteAlertsAndRules();
cy.task('esArchiverResetKibana');
createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
preventPrebuiltRulesPackageInstallation();
cleanKibana();
});

describe('User with read privileges on Security Solution', () => {
const RULE_1 = createRuleAssetSavedObject({
name: 'Test rule 1',
rule_id: 'rule_1',
});
const RULE_2 = createRuleAssetSavedObject({
name: 'Test rule 2',
rule_id: 'rule_2',
});
beforeEach(() => {
it('should not be able to install prebuilt rules', () => {
// Install one prebuilt rule asset to assert that user can't install it
installPrebuiltRuleAssets([RULE_2]);

// Now login with read-only user in preparation for test
createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false });
loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL);
});

it('should not be able to install prebuilt rules', () => {
// Check that Add Elastic Rules button is disabled
cy.get(ADD_ELASTIC_RULES_BTN).should('be.disabled');

Expand All @@ -94,25 +93,21 @@ describe(
// installation buttons are disabled
cy.visit(`${APP_PATH}${RULES_ADD_PATH}`);
cy.get(INSTALL_ALL_RULES_BUTTON).should('be.disabled');
cy.get(getInstallSingleRuleButtonByRuleId(RULE_1['security-rule'].rule_id)).should(
cy.get(getInstallSingleRuleButtonByRuleId(UPDATED_RULE_1['security-rule'].rule_id)).should(
'not.exist'
);
cy.get(RULE_CHECKBOX).should('not.exist');
});
});

describe('User with read privileges on Security Solution', () => {
beforeEach(() => {
/* Create a second version of the rule, making it available for update */
createAndInstallMockedPrebuiltRules({
rules: [UPDATED_RULE_1, UPDATED_RULE_2],
installToKibana: false,
});
it('should not be able to upgrade prebuilt rules', () => {
// Install one prebuilt rule asset to assert that user can't upgrade it
createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1]);
// Create a new version of the rule to make it available for upgrade
installPrebuiltRuleAssets([UPDATED_RULE_1]);

// Now login with read-only user in preparation for test
loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL);
});

it('should not be able to upgrade prebuilt rules', () => {
// Check that Rule Update tab is not shown
cy.get(RULES_UPDATES_TAB).should('not.exist');

Expand All @@ -121,11 +116,70 @@ describe(
// upgrade buttons are disabled
cy.visit(`${APP_PATH}${RULES_UPDATES}`);
cy.get(UPGRADE_ALL_RULES_BUTTON).should('be.disabled');

// Upgrade button and selection checkbox should not be visible
cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should(
'not.exist'
);
cy.get(RULE_CHECKBOX).should('not.exist');
});
});

describe('User with write privileges on Security Solution', () => {
it('should be able to install prebuilt rules', () => {
// Install one prebuilt rule asset to assert that user can install it
installPrebuiltRuleAssets([RULE_2]);
loginPageAsWriteAuthorizedUser(RULES_MANAGEMENT_URL);

// Check that Add Elastic Rules button is enabled
cy.get(ADD_ELASTIC_RULES_BTN).should('not.be.disabled');

// Navigate to Add Elastic Rules page and assert that rules can be selected
// and all installation buttons are enabled
cy.get(ADD_ELASTIC_RULES_BTN).click();
cy.get(INSTALL_ALL_RULES_BUTTON).should('not.be.disabled');
cy.get(getInstallSingleRuleButtonByRuleId(RULE_2['security-rule'].rule_id)).should('exist');
cy.get(RULE_CHECKBOX).should('exist');

// Install all available prebuilt rules
cy.get(INSTALL_ALL_RULES_BUTTON).click();

// Rule shouldn't be available for installation anymore
cy.get(getInstallSingleRuleButtonByRuleId(RULE_2['security-rule'].rule_id)).should(
'not.exist'
);

// Navigate back to rules table and assert rule is installed
cy.get(GO_BACK_TO_RULES_TABLE_BUTTON).click();
cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_2['security-rule'].name);
});

it('should be able to upgrade prebuilt rules', () => {
// Install one prebuilt rule asset to assert that user can upgrade it
createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1]);
// Create a new version of the rule to make it available for upgrade
installPrebuiltRuleAssets([UPDATED_RULE_1]);
loginPageAsWriteAuthorizedUser(RULES_MANAGEMENT_URL);

// Check that Rule Update tab is shown
cy.get(RULES_UPDATES_TAB).should('exist');

// Navigate to Rule Update tab and assert that rules can be selected
// and all upgrade buttons are enabled
cy.get(RULES_UPDATES_TAB).click();
cy.get(UPGRADE_ALL_RULES_BUTTON).should('not.be.disabled');
cy.get(RULE_CHECKBOX).should('exist');
cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should(
'exist'
);

// Upgrade the rule and assert that it's upgraded
cy.get(
getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)
).click();
cy.get(RULES_MANAGEMENT_TAB).click();
cy.get(RULES_MANAGEMENT_TABLE).contains(UPDATED_RULE_1['security-rule'].name);
});
});
}
);
Loading

0 comments on commit 24c008b

Please sign in to comment.