Skip to content

Commit

Permalink
Make updateAPIKey only load SOC where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
mikecote committed Feb 6, 2020
1 parent 672f559 commit 867d099
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 17 deletions.
30 changes: 27 additions & 3 deletions x-pack/legacy/plugins/alerting/server/alerts_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2445,7 +2445,7 @@ describe('updateApiKey()', () => {
const existingEncryptedAlert = {
...existingAlert,
attributes: {
...existingAlert,
...existingAlert.attributes,
apiKey: Buffer.from('123:abc').toString('base64'),
},
};
Expand All @@ -2462,7 +2462,7 @@ describe('updateApiKey()', () => {

test('updates the API key for the alert', async () => {
await alertsClient.updateApiKey({ id: '1' });
expect(savedObjectsClient.get).toHaveBeenCalledWith('alert', '1');
expect(savedObjectsClient.get).not.toHaveBeenCalled();
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith('alert', '1', {
namespace: 'default',
});
Expand All @@ -2482,6 +2482,30 @@ describe('updateApiKey()', () => {
expect(alertsClientParams.invalidateAPIKey).toHaveBeenCalledWith({ id: '123' });
});

test('falls back to SOC when getDecryptedAsInternalUser throws an error', async () => {
encryptedSavedObjects.getDecryptedAsInternalUser.mockRejectedValueOnce(new Error('Fail'));

await alertsClient.updateApiKey({ id: '1' });
expect(savedObjectsClient.get).toHaveBeenCalledWith('alert', '1');
expect(encryptedSavedObjects.getDecryptedAsInternalUser).toHaveBeenCalledWith('alert', '1', {
namespace: 'default',
});
expect(savedObjectsClient.update).toHaveBeenCalledWith(
'alert',
'1',
{
schedule: { interval: '10s' },
alertTypeId: '2',
enabled: true,
apiKey: Buffer.from('234:abc').toString('base64'),
apiKeyOwner: 'elastic',
updatedBy: 'elastic',
},
{ version: '123' }
);
expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalled();
});

test('swallows error when invalidate API key throws', async () => {
alertsClientParams.invalidateAPIKey.mockRejectedValue(new Error('Fail'));

Expand All @@ -2497,7 +2521,7 @@ describe('updateApiKey()', () => {

await alertsClient.updateApiKey({ id: '1' });
expect(alertsClientParams.logger.error).toHaveBeenCalledWith(
'updateApiKey(): Failed to load API key to invalidate: Fail'
'updateApiKey(): Failed to load API key to invalidate on alert 1: Fail'
);
expect(savedObjectsClient.update).toHaveBeenCalled();
expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalled();
Expand Down
35 changes: 21 additions & 14 deletions x-pack/legacy/plugins/alerting/server/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,20 +332,27 @@ export class AlertsClient {
}

public async updateApiKey({ id }: { id: string }) {
const [{ attributes, version }, apiKeyToInvalidate] = await Promise.all<
SavedObject<RawAlert>,
string | null | void
>([
this.savedObjectsClient.get<RawAlert>('alert', id),
// We'll try and load the decrypted saved object but if this fails we'll only log
// and skip invalidating the API key.
this.encryptedSavedObjectsPlugin
.getDecryptedAsInternalUser<RawAlert>('alert', id, { namespace: this.namespace })
.then(result => result.attributes.apiKey)
.catch(e =>
this.logger.error(`updateApiKey(): Failed to load API key to invalidate: ${e.message}`)
),
]);
let apiKeyToInvalidate: string | null = null;
let attributes: RawAlert;
let version: string | undefined;

try {
const decryptedAlert = await this.encryptedSavedObjectsPlugin.getDecryptedAsInternalUser<
RawAlert
>('alert', id, { namespace: this.namespace });
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
attributes = decryptedAlert.attributes;
version = decryptedAlert.version;
} catch (e) {
// We'll skip invalidating the API key since we failed to load the decrypted saved object
this.logger.error(
`updateApiKey(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the attributes and version using SOC
const alert = await this.savedObjectsClient.get<RawAlert>('alert', id);
attributes = alert.attributes;
version = alert.version;
}

const username = await this.getUserName();
await this.savedObjectsClient.update(
Expand Down

0 comments on commit 867d099

Please sign in to comment.