mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ResponseOps][Rules] Version update api key rule route (#188722)
## Summary Parent Issue: #187572 Versions the `POST /rule/{id}/_update_api_key` endpoint. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
4180aa4967
commit
317154df43
20 changed files with 192 additions and 73 deletions
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { updateApiKeyParamsSchema } from './schemas/latest';
|
||||
export type { UpdateApiKeyParams } from './types/latest';
|
||||
|
||||
export { updateApiKeyParamsSchema as updateApiKeyParamsSchemaV1 } from './schemas/v1';
|
||||
export type { UpdateApiKeyParams as UpdateApiKeyParamsV1 } from './types/v1';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 * from './v1';
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
|
||||
export const updateApiKeyParamsSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 * from './v1';
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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 type { TypeOf } from '@kbn/config-schema';
|
||||
import { updateApiKeyParamsSchemaV1 } from '..';
|
||||
|
||||
export type UpdateApiKeyParams = TypeOf<typeof updateApiKeyParamsSchemaV1>;
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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 { updateApiKeyParamsSchema } from './schemas';
|
||||
export type { UpdateApiKeyParams } from './types';
|
||||
|
||||
export { updateRuleApiKey } from './update_rule_api_key';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 * from './update_rule_api_key_schemas';
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
|
||||
export const updateApiKeyParamsSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 * from './update_rule_api_key_types';
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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 { TypeOf } from '@kbn/config-schema';
|
||||
import { updateApiKeyParamsSchema } from '../schemas';
|
||||
|
||||
export type UpdateApiKeyParams = TypeOf<typeof updateApiKeyParamsSchema>;
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { RulesClient, ConstructorOptions } from '../rules_client';
|
||||
import { RulesClient, ConstructorOptions } from '../../../../rules_client/rules_client';
|
||||
import {
|
||||
savedObjectsClientMock,
|
||||
loggingSystemMock,
|
||||
|
@ -13,20 +13,20 @@ import {
|
|||
uiSettingsServiceMock,
|
||||
} from '@kbn/core/server/mocks';
|
||||
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
|
||||
import { ruleTypeRegistryMock } from '../../rule_type_registry.mock';
|
||||
import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock';
|
||||
import { ruleTypeRegistryMock } from '../../../../rule_type_registry.mock';
|
||||
import { alertingAuthorizationMock } from '../../../../authorization/alerting_authorization.mock';
|
||||
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
|
||||
import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks';
|
||||
import { AlertingAuthorization } from '../../authorization/alerting_authorization';
|
||||
import { AlertingAuthorization } from '../../../../authorization/alerting_authorization';
|
||||
import { ActionsAuthorization } from '@kbn/actions-plugin/server';
|
||||
import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks';
|
||||
import { getBeforeSetup, setGlobalDate } from './lib';
|
||||
import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation';
|
||||
import { ConnectorAdapterRegistry } from '../../connector_adapters/connector_adapter_registry';
|
||||
import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects';
|
||||
import { backfillClientMock } from '../../backfill_client/backfill_client.mock';
|
||||
import { getBeforeSetup, setGlobalDate } from '../../../../rules_client/tests/lib';
|
||||
import { bulkMarkApiKeysForInvalidation } from '../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation';
|
||||
import { ConnectorAdapterRegistry } from '../../../../connector_adapters/connector_adapter_registry';
|
||||
import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects';
|
||||
import { backfillClientMock } from '../../../../backfill_client/backfill_client.mock';
|
||||
|
||||
jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({
|
||||
jest.mock('../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({
|
||||
bulkMarkApiKeysForInvalidation: jest.fn(),
|
||||
}));
|
||||
|
||||
|
@ -77,7 +77,7 @@ beforeEach(() => {
|
|||
|
||||
setGlobalDate();
|
||||
|
||||
describe('updateApiKey()', () => {
|
||||
describe('updateRuleApiKey()', () => {
|
||||
let rulesClient: RulesClient;
|
||||
const existingAlert = {
|
||||
id: '1',
|
||||
|
@ -123,7 +123,7 @@ describe('updateApiKey()', () => {
|
|||
apiKeysEnabled: true,
|
||||
result: { id: '234', name: '123', api_key: 'abc' },
|
||||
});
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled();
|
||||
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
RULE_SAVED_OBJECT_TYPE,
|
||||
|
@ -184,7 +184,7 @@ describe('updateApiKey()', () => {
|
|||
apiKeysEnabled: true,
|
||||
result: { id: '234', name: '123', api_key: 'abc' },
|
||||
});
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled();
|
||||
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
RULE_SAVED_OBJECT_TYPE,
|
||||
|
@ -240,7 +240,7 @@ describe('updateApiKey()', () => {
|
|||
apiKeysEnabled: true,
|
||||
result: { id: '234', name: '123', api_key: 'abc' },
|
||||
});
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled();
|
||||
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
RULE_SAVED_OBJECT_TYPE,
|
||||
|
@ -288,12 +288,21 @@ describe('updateApiKey()', () => {
|
|||
throw new Error('no');
|
||||
});
|
||||
await expect(
|
||||
async () => await rulesClient.updateApiKey({ id: '1' })
|
||||
async () => await rulesClient.updateRuleApiKey({ id: '1' })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Error updating API key for rule: could not create API key - no"`
|
||||
);
|
||||
});
|
||||
|
||||
test('throws an error if API params do not match the schema', async () => {
|
||||
await expect(
|
||||
// @ts-ignore: this is what we are testing
|
||||
async () => await rulesClient.updateRuleApiKey({ id: 1 })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Error validating update api key parameters - [id]: expected value of type [string] but got [number]"`
|
||||
);
|
||||
});
|
||||
|
||||
test('falls back to SOC when getDecryptedAsInternalUser throws an error', async () => {
|
||||
rulesClientParams.createAPIKey.mockResolvedValueOnce({
|
||||
apiKeysEnabled: true,
|
||||
|
@ -301,7 +310,7 @@ describe('updateApiKey()', () => {
|
|||
});
|
||||
encryptedSavedObjects.getDecryptedAsInternalUser.mockRejectedValueOnce(new Error('Fail'));
|
||||
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledWith(RULE_SAVED_OBJECT_TYPE, '1');
|
||||
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith(
|
||||
RULE_SAVED_OBJECT_TYPE,
|
||||
|
@ -346,7 +355,7 @@ describe('updateApiKey()', () => {
|
|||
test('swallows error when invalidate API key throws', async () => {
|
||||
bulkMarkApiKeysForInvalidationMock.mockImplementationOnce(() => new Error('Fail'));
|
||||
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(unsecuredSavedObjectsClient.update).toHaveBeenCalled();
|
||||
expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledTimes(1);
|
||||
expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledWith(
|
||||
|
@ -359,7 +368,7 @@ describe('updateApiKey()', () => {
|
|||
test('swallows error when getting decrypted object throws', async () => {
|
||||
encryptedSavedObjects.getDecryptedAsInternalUser.mockRejectedValueOnce(new Error('Fail'));
|
||||
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
expect(rulesClientParams.logger.error).toHaveBeenCalledWith(
|
||||
'updateApiKey(): Failed to load API key to invalidate on alert 1: Fail'
|
||||
);
|
||||
|
@ -373,9 +382,9 @@ describe('updateApiKey()', () => {
|
|||
});
|
||||
unsecuredSavedObjectsClient.update.mockRejectedValueOnce(new Error('Fail'));
|
||||
|
||||
await expect(rulesClient.updateApiKey({ id: '1' })).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Fail"`
|
||||
);
|
||||
await expect(
|
||||
rulesClient.updateRuleApiKey({ id: '1' })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`);
|
||||
expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledTimes(1);
|
||||
expect(bulkMarkApiKeysForInvalidation).toHaveBeenCalledWith(
|
||||
{ apiKeys: ['MjM0OmFiYw=='] },
|
||||
|
@ -385,8 +394,8 @@ describe('updateApiKey()', () => {
|
|||
});
|
||||
|
||||
describe('authorization', () => {
|
||||
test('ensures user is authorised to updateApiKey this type of alert under the consumer', async () => {
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
test('ensures user is authorised to updateRuleApiKey this type of alert under the consumer', async () => {
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
|
||||
expect(actionsAuthorization.ensureAuthorized).toHaveBeenCalledWith({ operation: 'execute' });
|
||||
expect(authorization.ensureAuthorized).toHaveBeenCalledWith({
|
||||
|
@ -397,13 +406,13 @@ describe('updateApiKey()', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('throws when user is not authorised to updateApiKey this type of alert', async () => {
|
||||
test('throws when user is not authorised to updateRuleApiKey this type of alert', async () => {
|
||||
authorization.ensureAuthorized.mockRejectedValue(
|
||||
new Error(`Unauthorized to updateApiKey a "myType" alert for "myApp"`)
|
||||
new Error(`Unauthorized to updateRuleApiKey a "myType" alert for "myApp"`)
|
||||
);
|
||||
|
||||
await expect(rulesClient.updateApiKey({ id: '1' })).rejects.toMatchInlineSnapshot(
|
||||
`[Error: Unauthorized to updateApiKey a "myType" alert for "myApp"]`
|
||||
await expect(rulesClient.updateRuleApiKey({ id: '1' })).rejects.toMatchInlineSnapshot(
|
||||
`[Error: Unauthorized to updateRuleApiKey a "myType" alert for "myApp"]`
|
||||
);
|
||||
|
||||
expect(authorization.ensureAuthorized).toHaveBeenCalledWith({
|
||||
|
@ -417,7 +426,7 @@ describe('updateApiKey()', () => {
|
|||
|
||||
describe('auditLogger', () => {
|
||||
test('logs audit event when updating the API key of a rule', async () => {
|
||||
await rulesClient.updateApiKey({ id: '1' });
|
||||
await rulesClient.updateRuleApiKey({ id: '1' });
|
||||
|
||||
expect(auditLogger.log).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
|
@ -433,7 +442,7 @@ describe('updateApiKey()', () => {
|
|||
test('logs audit event when not authorised to update the API key of a rule', async () => {
|
||||
authorization.ensureAuthorized.mockRejectedValue(new Error('Unauthorized'));
|
||||
|
||||
await expect(rulesClient.updateApiKey({ id: '1' })).rejects.toThrow();
|
||||
await expect(rulesClient.updateRuleApiKey({ id: '1' })).rejects.toThrow();
|
||||
expect(auditLogger.log).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
event: expect.objectContaining({
|
|
@ -5,32 +5,41 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { RawRule } from '../../types';
|
||||
import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization';
|
||||
import { retryIfConflicts } from '../../lib/retry_if_conflicts';
|
||||
import { bulkMarkApiKeysForInvalidation } from '../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation';
|
||||
import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events';
|
||||
import { createNewAPIKeySet, updateMeta } from '../lib';
|
||||
import { RulesClientContext } from '../types';
|
||||
import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects';
|
||||
import Boom from '@hapi/boom';
|
||||
import { RawRule } from '../../../../types';
|
||||
import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization';
|
||||
import { retryIfConflicts } from '../../../../lib/retry_if_conflicts';
|
||||
import { bulkMarkApiKeysForInvalidation } from '../../../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation';
|
||||
import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events';
|
||||
import { createNewAPIKeySet, updateMeta } from '../../../../rules_client/lib';
|
||||
import { RulesClientContext } from '../../../../rules_client/types';
|
||||
import { RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects';
|
||||
import { UpdateApiKeyParams } from './types';
|
||||
import { updateApiKeyParamsSchema } from './schemas';
|
||||
|
||||
export async function updateApiKey(
|
||||
export async function updateRuleApiKey(
|
||||
context: RulesClientContext,
|
||||
{ id }: { id: string }
|
||||
{ id }: UpdateApiKeyParams
|
||||
): Promise<void> {
|
||||
return await retryIfConflicts(
|
||||
context.logger,
|
||||
`rulesClient.updateApiKey('${id}')`,
|
||||
`rulesClient.updateRuleApiKey('${id}')`,
|
||||
async () => await updateApiKeyWithOCC(context, { id })
|
||||
);
|
||||
}
|
||||
|
||||
async function updateApiKeyWithOCC(context: RulesClientContext, { id }: { id: string }) {
|
||||
async function updateApiKeyWithOCC(context: RulesClientContext, { id }: UpdateApiKeyParams) {
|
||||
let oldApiKeyToInvalidate: string | null = null;
|
||||
let oldApiKeyCreatedByUser: boolean | undefined | null = false;
|
||||
let attributes: RawRule;
|
||||
let version: string | undefined;
|
||||
|
||||
try {
|
||||
updateApiKeyParamsSchema.validate({ id });
|
||||
} catch (error) {
|
||||
throw Boom.badRequest(`Error validating update api key parameters - ${error.message}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const decryptedAlert =
|
||||
await context.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>(
|
|
@ -35,7 +35,7 @@ import { muteAllRuleRoute } from './mute_all_rule';
|
|||
import { muteAlertRoute } from './rule/apis/mute_alert/mute_alert';
|
||||
import { unmuteAllRuleRoute } from './unmute_all_rule';
|
||||
import { unmuteAlertRoute } from './unmute_alert';
|
||||
import { updateRuleApiKeyRoute } from './update_rule_api_key';
|
||||
import { updateRuleApiKeyRoute } from './rule/apis/update_api_key/update_rule_api_key_route';
|
||||
import { bulkEditInternalRulesRoute } from './rule/apis/bulk_edit/bulk_edit_rules_route';
|
||||
import { snoozeRuleRoute } from './rule/apis/snooze';
|
||||
import { unsnoozeRuleRoute } from './rule/apis/unsnooze';
|
||||
|
|
|
@ -38,7 +38,7 @@ describe('updateApiKeyRoute', () => {
|
|||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/alerts/alert/{id}/_update_api_key"`);
|
||||
|
||||
rulesClient.updateApiKey.mockResolvedValueOnce();
|
||||
rulesClient.updateRuleApiKey.mockResolvedValueOnce();
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ rulesClient },
|
||||
|
@ -52,8 +52,8 @@ describe('updateApiKeyRoute', () => {
|
|||
|
||||
expect(await handler(context, req, res)).toEqual(undefined);
|
||||
|
||||
expect(rulesClient.updateApiKey).toHaveBeenCalledTimes(1);
|
||||
expect(rulesClient.updateApiKey.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
expect(rulesClient.updateRuleApiKey).toHaveBeenCalledTimes(1);
|
||||
expect(rulesClient.updateRuleApiKey.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
|
@ -72,7 +72,7 @@ describe('updateApiKeyRoute', () => {
|
|||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
rulesClient.updateApiKey.mockRejectedValue(
|
||||
rulesClient.updateRuleApiKey.mockRejectedValue(
|
||||
new RuleTypeDisabledError('Fail', 'license_invalid')
|
||||
);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ export const updateApiKeyRoute = (
|
|||
const rulesClient = (await context.alerting).getRulesClient();
|
||||
const { id } = req.params;
|
||||
try {
|
||||
await rulesClient.updateApiKey({ id });
|
||||
await rulesClient.updateRuleApiKey({ id });
|
||||
return res.noContent();
|
||||
} catch (e) {
|
||||
if (e instanceof RuleTypeDisabledError) {
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { updateRuleApiKeyRoute } from './update_rule_api_key';
|
||||
import { updateRuleApiKeyRoute } from './update_rule_api_key_route';
|
||||
import { httpServiceMock } from '@kbn/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { rulesClientMock } from '../rules_client.mock';
|
||||
import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled';
|
||||
import { licenseStateMock } from '../../../../lib/license_state.mock';
|
||||
import { mockHandlerArguments } from '../../../_mock_handler_arguments';
|
||||
import { rulesClientMock } from '../../../../rules_client.mock';
|
||||
import { RuleTypeDisabledError } from '../../../../lib/errors/rule_type_disabled';
|
||||
|
||||
const rulesClient = rulesClientMock.create();
|
||||
jest.mock('../lib/license_api_access', () => ({
|
||||
jest.mock('../../../../lib/license_api_access', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
||||
|
@ -32,7 +32,7 @@ describe('updateRuleApiKeyRoute', () => {
|
|||
|
||||
expect(config.path).toMatchInlineSnapshot(`"/api/alerting/rule/{id}/_update_api_key"`);
|
||||
|
||||
rulesClient.updateApiKey.mockResolvedValueOnce();
|
||||
rulesClient.updateRuleApiKey.mockResolvedValueOnce();
|
||||
|
||||
const [context, req, res] = mockHandlerArguments(
|
||||
{ rulesClient },
|
||||
|
@ -46,8 +46,8 @@ describe('updateRuleApiKeyRoute', () => {
|
|||
|
||||
expect(await handler(context, req, res)).toEqual(undefined);
|
||||
|
||||
expect(rulesClient.updateApiKey).toHaveBeenCalledTimes(1);
|
||||
expect(rulesClient.updateApiKey.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
expect(rulesClient.updateRuleApiKey).toHaveBeenCalledTimes(1);
|
||||
expect(rulesClient.updateRuleApiKey.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
|
@ -66,7 +66,7 @@ describe('updateRuleApiKeyRoute', () => {
|
|||
|
||||
const [, handler] = router.post.mock.calls[0];
|
||||
|
||||
rulesClient.updateApiKey.mockRejectedValue(
|
||||
rulesClient.updateRuleApiKey.mockRejectedValue(
|
||||
new RuleTypeDisabledError('Fail', 'license_invalid')
|
||||
);
|
||||
|
|
@ -6,14 +6,13 @@
|
|||
*/
|
||||
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { ILicenseState, RuleTypeDisabledError } from '../lib';
|
||||
import { verifyAccessAndContext } from './lib';
|
||||
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../types';
|
||||
|
||||
const paramSchema = schema.object({
|
||||
id: schema.string(),
|
||||
});
|
||||
import {
|
||||
UpdateApiKeyParamsV1,
|
||||
updateApiKeyParamsSchemaV1,
|
||||
} from '../../../../../common/routes/rule/apis/update_api_key';
|
||||
import { ILicenseState, RuleTypeDisabledError } from '../../../../lib';
|
||||
import { verifyAccessAndContext } from '../../../lib';
|
||||
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
|
||||
|
||||
export const updateRuleApiKeyRoute = (
|
||||
router: IRouter<AlertingRequestHandlerContext>,
|
||||
|
@ -24,18 +23,19 @@ export const updateRuleApiKeyRoute = (
|
|||
path: `${BASE_ALERTING_API_PATH}/rule/{id}/_update_api_key`,
|
||||
options: {
|
||||
access: 'public',
|
||||
summary: `Update the API key for a rule`,
|
||||
summary: 'Update the API key for a rule',
|
||||
},
|
||||
validate: {
|
||||
params: paramSchema,
|
||||
params: updateApiKeyParamsSchemaV1,
|
||||
},
|
||||
},
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const rulesClient = (await context.alerting).getRulesClient();
|
||||
const { id } = req.params;
|
||||
const { id }: UpdateApiKeyParamsV1 = req.params;
|
||||
|
||||
try {
|
||||
await rulesClient.updateApiKey({ id });
|
||||
await rulesClient.updateRuleApiKey({ id });
|
||||
return res.noContent();
|
||||
} catch (e) {
|
||||
if (e instanceof RuleTypeDisabledError) {
|
|
@ -23,7 +23,7 @@ const createRulesClientMock = () => {
|
|||
update: jest.fn(),
|
||||
enable: jest.fn(),
|
||||
disable: jest.fn(),
|
||||
updateApiKey: jest.fn(),
|
||||
updateRuleApiKey: jest.fn(),
|
||||
muteAll: jest.fn(),
|
||||
unmuteAll: jest.fn(),
|
||||
muteInstance: jest.fn(),
|
||||
|
|
|
@ -53,7 +53,7 @@ import {
|
|||
BulkEditOptions,
|
||||
} from '../application/rule/methods/bulk_edit/bulk_edit_rules';
|
||||
import { bulkEnableRules, BulkEnableRulesParams } from '../application/rule/methods/bulk_enable';
|
||||
import { updateApiKey } from './methods/update_api_key';
|
||||
import { updateRuleApiKey } from '../application/rule/methods/update_api_key/update_rule_api_key';
|
||||
import { enable } from './methods/enable';
|
||||
import { disable } from './methods/disable';
|
||||
import { clearExpiredSnoozes } from './methods/clear_expired_snoozes';
|
||||
|
@ -164,7 +164,7 @@ export class RulesClient {
|
|||
public bulkDisableRules = (options: BulkDisableRulesRequestBody) =>
|
||||
bulkDisableRules(this.context, options);
|
||||
|
||||
public updateApiKey = (options: { id: string }) => updateApiKey(this.context, options);
|
||||
public updateRuleApiKey = (params: { id: string }) => updateRuleApiKey(this.context, params);
|
||||
|
||||
public enable = (options: { id: string }) => enable(this.context, options);
|
||||
public disable = (options: { id: string; untrack?: boolean }) => disable(this.context, options);
|
||||
|
|
|
@ -149,7 +149,7 @@ async function update(success: boolean) {
|
|||
|
||||
async function updateApiKey(success: boolean) {
|
||||
try {
|
||||
await rulesClient.updateApiKey({ id: MockRuleId });
|
||||
await rulesClient.updateRuleApiKey({ id: MockRuleId });
|
||||
} catch (err) {
|
||||
return expectConflict(success, err);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue