Skip to content

Commit

Permalink
CR: add immutability guard
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaliidm committed Dec 23, 2021
1 parent 6562010 commit 1a28c20
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ import { requestContextMock, serverMock, requestMock } from '../__mocks__';
import { performBulkActionRoute } from './perform_bulk_action_route';
import { getPerformBulkActionSchemaMock } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock';
import { loggingSystemMock } from 'src/core/server/mocks';
import { isElasticRule } from '../../../../usage/detections';

jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create());
jest.mock('../../../../usage/detections', () => ({ isElasticRule: jest.fn() }));

describe.each([
['Legacy', false],
['RAC', true],
])('perform_bulk_action - %s', (_, isRuleRegistryEnabled) => {
const isElasticRuleMock = isElasticRule as jest.Mock;
let server: ReturnType<typeof serverMock.create>;
let { clients, context } = requestContextMock.createTools();
let ml: ReturnType<typeof mlServicesMock.createSetupContract>;
Expand All @@ -37,7 +40,7 @@ describe.each([
logger = loggingSystemMock.createLogger();
({ clients, context } = requestContextMock.createTools());
ml = mlServicesMock.createSetupContract();

isElasticRuleMock.mockReturnValue(false);
clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled));

performBulkActionRoute(server.router, ml, logger, isRuleRegistryEnabled);
Expand Down Expand Up @@ -78,6 +81,43 @@ describe.each([
});

describe('rules execution failures', () => {
it('returns error if rule is immutable/elastic', async () => {
isElasticRuleMock.mockReturnValue(true);
clients.rulesClient.find.mockResolvedValue(
getFindResultWithMultiHits({
data: [mockRule],
total: 1,
})
);

const response = await server.inject(getBulkActionEditRequest(), context);

expect(response.status).toEqual(500);
expect(response.body).toEqual({
message: 'Bulk edit failed',
status_code: 500,
attributes: {
errors: [
{
message: 'Elastic rule can`t be edited',
status_code: 403,
rules: [
{
id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd',
name: 'Detect Root/Admin Users',
},
],
},
],
rules: {
failed: 1,
succeeded: 0,
total: 1,
},
},
});
});

it('returns error if disable rule throws error', async () => {
clients.rulesClient.disable.mockImplementation(async () => {
throw new Error('Test error');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { SetupPlugins } from '../../../../plugin';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
import { initPromisePool } from '../../../../utils/promise_pool';
import { isElasticRule } from '../../../../usage/detections';
import { buildMlAuthz } from '../../../machine_learning/authz';
import { throwHttpError } from '../../../machine_learning/validation';
import { deleteRules } from '../../rules/delete_rules';
Expand Down Expand Up @@ -221,6 +222,11 @@ export const performBulkActionRoute = (
});
case BulkAction.edit:
processingResponse = await executeBulkAction(rules.data, async (rule) => {
throwHttpError({
valid: !isElasticRule(rule.tags),
message: 'Elastic rule can`t be edited',
});

throwHttpError(await mlAuthz.validateRuleType(rule.params.type));

const editedRule = body[BulkAction.edit].reduce(
Expand Down

0 comments on commit 1a28c20

Please sign in to comment.