Skip to content

Commit

Permalink
Fixed due to comments. Changed api key invalidation task to use Saved…
Browse files Browse the repository at this point in the history
…ObjectClient
  • Loading branch information
YulNaumenko committed Nov 16, 2020
1 parent 871d2ef commit 4092f13
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ describe('create()', () => {
id: '1',
type: 'api_key_pending_invalidation',
attributes: {
apiKeyId: 'test',
apiKeyId: 'MTIz',
createdAt,
},
references: [],
Expand All @@ -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,
});
});
Expand Down
10 changes: 5 additions & 5 deletions x-pack/plugins/alerts/server/alerts_client/tests/delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
Expand All @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand All @@ -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'
);
});

Expand All @@ -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: [],
Expand Down
14 changes: 7 additions & 7 deletions x-pack/plugins/alerts/server/alerts_client/tests/disable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
Expand Down Expand Up @@ -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 () => {
Expand All @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand All @@ -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: [],
Expand All @@ -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: [],
Expand Down Expand Up @@ -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'
);
});

Expand Down
10 changes: 5 additions & 5 deletions x-pack/plugins/alerts/server/alerts_client/tests/enable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ describe('enable()', () => {
id: '1',
type: 'api_key_pending_invalidation',
attributes: {
apiKeyId: '123',
apiKeyId: 'MTIz',
createdAt,
},
references: [],
Expand Down Expand Up @@ -239,7 +239,7 @@ describe('enable()', () => {
id: '1',
type: 'api_key_pending_invalidation',
attributes: {
apiKeyId: '123',
apiKeyId: 'MTIz',
createdAt,
},
references: [],
Expand All @@ -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 () => {
Expand Down Expand Up @@ -345,7 +345,7 @@ describe('enable()', () => {
id: '1',
type: 'api_key_pending_invalidation',
attributes: {
apiKeyId: '123',
apiKeyId: 'MTIz',
createdAt,
},
references: [],
Expand All @@ -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();
});
Expand Down
12 changes: 6 additions & 6 deletions x-pack/plugins/alerts/server/alerts_client/tests/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand All @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand Down Expand Up @@ -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'
);
});

Expand Down Expand Up @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand Down Expand Up @@ -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: [],
Expand All @@ -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: [],
Expand All @@ -234,7 +234,7 @@ describe('updateApiKey()', () => {
);
expect(
(unsecuredSavedObjectsClient.create.mock.calls[0][1] as InvalidatePendingApiKey).apiKeyId
).toBe('234');
).toBe('MjM0');
});

describe('authorization', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> => {
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}`);
}
};
49 changes: 36 additions & 13 deletions x-pack/plugins/alerts/server/invalidate_pending_api_keys/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
Logger,
CoreStart,
SavedObjectsFindResponse,
ISavedObjectsRepository,
KibanaRequest,
SavedObjectsClientContract,
} from 'kibana/server';
import { InvalidateAPIKeyParams, SecurityPluginSetup } from '../../../security/server';
import {
Expand Down Expand Up @@ -97,6 +98,24 @@ function registerApiKeyInvalitorTaskDefinition(
});
}

function getFakeKibanaRequest(basePath: string) {
const requestHeaders: Record<string, string> = {};
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]>,
Expand All @@ -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<InvalidatePendingApiKey>({
const apiKeysToInvalidate = await savedObjectsClient.find<InvalidatePendingApiKey>({
type: 'api_key_pending_invalidation',
filter: `api_key_pending_invalidation.attributes.createdAt <= "${delay}"`,
page: 1,
Expand All @@ -130,7 +154,7 @@ function taskRunner(
});
totalInvalidated += await invalidateApiKeys(
logger,
repository,
savedObjectsClient,
apiKeysToInvalidate,
securityPluginSetup
);
Expand Down Expand Up @@ -166,22 +190,21 @@ function taskRunner(

async function invalidateApiKeys(
logger: Logger,
repository: ISavedObjectsRepository,
savedObjectsClient: SavedObjectsClientContract,
apiKeysToInvalidate: SavedObjectsFindResponse<InvalidatePendingApiKey>,
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(
Expand Down
Loading

0 comments on commit 4092f13

Please sign in to comment.