diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts index cf80692a3cb16..1041cc13ba6d5 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/create.test.ts @@ -735,7 +735,7 @@ describe('create()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt, }, references: [], @@ -746,7 +746,7 @@ describe('create()', () => { expect(taskManager.schedule).not.toHaveBeenCalled(); expect(unsecuredSavedObjectsClient.create).toHaveBeenCalledTimes(2); expect(unsecuredSavedObjectsClient.create.mock.calls[1][1]).toStrictEqual({ - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt, }); }); diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/delete.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/delete.test.ts index 358510a774770..1a56e96c2a140 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/delete.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/delete.test.ts @@ -97,7 +97,7 @@ describe('delete()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -121,7 +121,7 @@ describe('delete()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -156,7 +156,7 @@ describe('delete()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -180,7 +180,7 @@ describe('delete()', () => { 'api_key_pending_invalidation' ); expect(alertsClientParams.logger.error).toHaveBeenCalledWith( - 'Failed to mark for API key [id="123"] for invalidation: Fail' + 'Failed to mark for API key [id="MTIzOmFiYw=="] for invalidation: Fail' ); }); @@ -189,7 +189,7 @@ describe('delete()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/disable.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/disable.test.ts index b68eb24be4414..f20c49992b521 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/disable.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/disable.test.ts @@ -112,7 +112,7 @@ describe('disable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -156,7 +156,7 @@ describe('disable()', () => { expect(taskManager.remove).toHaveBeenCalledWith('task-123'); expect( (unsecuredSavedObjectsClient.create.mock.calls[0][1] as InvalidatePendingApiKey).apiKeyId - ).toBe('123'); + ).toBe('MTIz'); }); test('falls back when getDecryptedAsInternalUser throws an error', async () => { @@ -165,7 +165,7 @@ describe('disable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -225,7 +225,7 @@ describe('disable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -242,7 +242,7 @@ describe('disable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -258,7 +258,7 @@ describe('disable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -286,7 +286,7 @@ describe('disable()', () => { unsecuredSavedObjectsClient.create.mockRejectedValueOnce(new Error('Fail')); await alertsClient.disable({ id: '1' }); expect(alertsClientParams.logger.error).toHaveBeenCalledWith( - 'Failed to mark for API key [id="123"] for invalidation: Fail' + 'Failed to mark for API key [id="MTIzOmFiYw=="] for invalidation: Fail' ); }); diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/enable.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/enable.test.ts index 16e83c42d8930..6e9275c8c503a 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/enable.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/enable.test.ts @@ -162,7 +162,7 @@ describe('enable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt, }, references: [], @@ -239,7 +239,7 @@ describe('enable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt, }, references: [], @@ -252,7 +252,7 @@ describe('enable()', () => { }); expect( (unsecuredSavedObjectsClient.create.mock.calls[0][1] as InvalidatePendingApiKey).apiKeyId - ).toBe('123'); + ).toBe('MTIz'); }); test(`doesn't enable already enabled alerts`, async () => { @@ -345,7 +345,7 @@ describe('enable()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt, }, references: [], @@ -358,7 +358,7 @@ describe('enable()', () => { expect(alertsClientParams.createAPIKey).toHaveBeenCalled(); expect( (unsecuredSavedObjectsClient.create.mock.calls[0][1] as InvalidatePendingApiKey).apiKeyId - ).toBe('123'); + ).toBe('MTIz'); expect(unsecuredSavedObjectsClient.update).toHaveBeenCalledTimes(1); expect(taskManager.schedule).not.toHaveBeenCalled(); }); diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/update.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/update.test.ts index 9de47dde0fad5..4fe3b7a9f58e9 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/update.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/update.test.ts @@ -164,7 +164,7 @@ describe('update()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -388,7 +388,7 @@ describe('update()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -397,7 +397,7 @@ describe('update()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -560,7 +560,7 @@ describe('update()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -832,7 +832,7 @@ describe('update()', () => { }, }); expect(alertsClientParams.logger.error).toHaveBeenCalledWith( - 'Failed to mark for API key [id="123"] for invalidation: Fail' + 'Failed to mark for API key [id="MTIzOmFiYw=="] for invalidation: Fail' ); }); @@ -1002,7 +1002,7 @@ describe('update()', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); expect( (unsecuredSavedObjectsClient.create.mock.calls[1][1] as InvalidatePendingApiKey).apiKeyId - ).toBe('234'); + ).toBe('MjM0'); }); describe('updating an alert schedule', () => { diff --git a/x-pack/plugins/alerts/server/alerts_client/tests/update_api_key.test.ts b/x-pack/plugins/alerts/server/alerts_client/tests/update_api_key.test.ts index cd6d63d4d8662..365a8526f3198 100644 --- a/x-pack/plugins/alerts/server/alerts_client/tests/update_api_key.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client/tests/update_api_key.test.ts @@ -84,7 +84,7 @@ describe('updateApiKey()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -141,7 +141,7 @@ describe('updateApiKey()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '123', + apiKeyId: 'MTIz', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -199,7 +199,7 @@ describe('updateApiKey()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: 'test', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -223,7 +223,7 @@ describe('updateApiKey()', () => { id: '1', type: 'api_key_pending_invalidation', attributes: { - apiKeyId: '234', + apiKeyId: 'MjM0', createdAt: '2019-02-12T21:01:22.479Z', }, references: [], @@ -234,7 +234,7 @@ describe('updateApiKey()', () => { ); expect( (unsecuredSavedObjectsClient.create.mock.calls[0][1] as InvalidatePendingApiKey).apiKeyId - ).toBe('234'); + ).toBe('MjM0'); }); describe('authorization', () => { diff --git a/x-pack/plugins/alerts/server/invalidate_pending_api_keys/mark_api_key_for_invalidation.ts b/x-pack/plugins/alerts/server/invalidate_pending_api_keys/mark_api_key_for_invalidation.ts index ee4fd38086396..d145e8e33fa3d 100644 --- a/x-pack/plugins/alerts/server/invalidate_pending_api_keys/mark_api_key_for_invalidation.ts +++ b/x-pack/plugins/alerts/server/invalidate_pending_api_keys/mark_api_key_for_invalidation.ts @@ -8,18 +8,20 @@ import { Logger, SavedObjectsClientContract } from 'src/core/server'; export const markApiKeyForInvalidation = async ( { apiKey }: { apiKey: string | null }, logger: Logger, - internalSavedObjectsRepository: SavedObjectsClientContract + savedObjectsClient: SavedObjectsClientContract ): Promise => { if (!apiKey) { return; } - const apiKeyId = Buffer.from(apiKey, 'base64').toString().split(':')[0]; try { - await internalSavedObjectsRepository.create('api_key_pending_invalidation', { + const apiKeyId = Buffer.from(Buffer.from(apiKey, 'base64').toString().split(':')[0]).toString( + 'base64' + ); + await savedObjectsClient.create('api_key_pending_invalidation', { apiKeyId, createdAt: new Date().toISOString(), }); } catch (e) { - logger.error(`Failed to mark for API key [id="${apiKeyId}"] for invalidation: ${e.message}`); + logger.error(`Failed to mark for API key [id="${apiKey}"] for invalidation: ${e.message}`); } }; diff --git a/x-pack/plugins/alerts/server/invalidate_pending_api_keys/task.ts b/x-pack/plugins/alerts/server/invalidate_pending_api_keys/task.ts index 60b4aec36e3eb..dd2f9684dccbf 100644 --- a/x-pack/plugins/alerts/server/invalidate_pending_api_keys/task.ts +++ b/x-pack/plugins/alerts/server/invalidate_pending_api_keys/task.ts @@ -8,7 +8,8 @@ import { Logger, CoreStart, SavedObjectsFindResponse, - ISavedObjectsRepository, + KibanaRequest, + SavedObjectsClientContract, } from 'kibana/server'; import { InvalidateAPIKeyParams, SecurityPluginSetup } from '../../../security/server'; import { @@ -97,6 +98,24 @@ function registerApiKeyInvalitorTaskDefinition( }); } +function getFakeKibanaRequest(basePath: string) { + const requestHeaders: Record = {}; + return ({ + headers: requestHeaders, + getBasePath: () => basePath, + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + } as unknown) as KibanaRequest; +} + function taskRunner( logger: Logger, coreStartServices: Promise<[CoreStart, AlertingPluginsStart, unknown]>, @@ -110,17 +129,22 @@ function taskRunner( let totalInvalidated = 0; const configResult = await config; try { - const [{ savedObjects }] = await coreStartServices; - const repository = savedObjects.createInternalRepository([ - 'api_key_pending_invalidation', - ]); + const [{ savedObjects, http }] = await coreStartServices; + const savedObjectsClient = savedObjects.getScopedClient( + getFakeKibanaRequest(http.basePath.serverBasePath), + { + includedHiddenTypes: ['api_key_pending_invalidation'], + excludedWrappers: ['security'], + } + ); + const configuredDelay = configResult.invalidateApiKeysTask.removalDelay; const delay = timePeriodBeforeDate(new Date(), configuredDelay).toISOString(); let hasApiKeysPendingInvalidation = true; const PAGE_SIZE = 100; do { - const apiKeysToInvalidate = await repository.find({ + const apiKeysToInvalidate = await savedObjectsClient.find({ type: 'api_key_pending_invalidation', filter: `api_key_pending_invalidation.attributes.createdAt <= "${delay}"`, page: 1, @@ -130,7 +154,7 @@ function taskRunner( }); totalInvalidated += await invalidateApiKeys( logger, - repository, + savedObjectsClient, apiKeysToInvalidate, securityPluginSetup ); @@ -166,22 +190,21 @@ function taskRunner( async function invalidateApiKeys( logger: Logger, - repository: ISavedObjectsRepository, + savedObjectsClient: SavedObjectsClientContract, apiKeysToInvalidate: SavedObjectsFindResponse, securityPluginSetup?: SecurityPluginSetup ) { let totalInvalidated = 0; await Promise.all( apiKeysToInvalidate.saved_objects.map(async (apiKeyObj) => { - const response = await invalidateAPIKey( - { id: apiKeyObj.attributes.apiKeyId }, - securityPluginSetup - ); + const apiKeyId = Buffer.from(apiKeyObj.attributes.apiKeyId, 'base64').toString(); + + const response = await invalidateAPIKey({ id: apiKeyId }, securityPluginSetup); if (response.apiKeysEnabled === true && response.result.error_count > 0) { logger.error(`Failed to invalidate API Key [id="${apiKeyObj.attributes.apiKeyId}"]`); } else { try { - await repository.delete('api_key_pending_invalidation', apiKeyObj.id); + await savedObjectsClient.delete('api_key_pending_invalidation', apiKeyObj.id); totalInvalidated++; } catch (err) { logger.error( diff --git a/x-pack/plugins/alerts/server/saved_objects/index.ts b/x-pack/plugins/alerts/server/saved_objects/index.ts index 0be5c1d47ed12..bbdc121f8f855 100644 --- a/x-pack/plugins/alerts/server/saved_objects/index.ts +++ b/x-pack/plugins/alerts/server/saved_objects/index.ts @@ -45,7 +45,7 @@ export function setupSavedObjects( savedObjects.registerType({ name: 'api_key_pending_invalidation', hidden: true, - namespaceType: 'single', + namespaceType: 'agnostic', mappings: { properties: { apiKeyId: {