forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Data Usage] add error handling and tests for privilege related errors (
elastic#203006) - handling of 2 error cases to error handler - `security_exception` due to lack of privileges. Metering api will respond when one of the following isn't available as a user privilege `monitor,view_index_metadata,manage,all`. - `index_not_found_exception`. Metering api will respond with this when no indices exist for the privileges it has access to or when no indices are found. - api integration tests for data_streams route for the following cases - returns no data streams when there are none it has access to and responds with appropriate message - returns no data streams without necessary privileges and responds with appropriate message - returns data streams when user only has access to a subset of indices with necessary privileges - functional tests for same as above. these remain skipped due to not being able to create data streams picked up by metering api since we implemented filtering out zero storage size data streams, but useful for local testing with some code changes. ### `security_exception` view <img width="1555" alt="Screenshot 2024-12-04 at 1 14 10 PM" src="https://github.com/user-attachments/assets/241a2eb8-1c77-4592-ba18-b971512e712e"> ### `index_not_found_exception` view <img width="1589" alt="Screenshot 2024-12-04 at 1 13 13 PM" src="https://github.com/user-attachments/assets/12b68d66-9178-4957-b014-5765be348694"> --------- Co-authored-by: Ashokaditya <ashokaditya@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
- Loading branch information
1 parent
045ff9c
commit 008187d
Showing
12 changed files
with
345 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
/* eslint-disable max-classes-per-file */ | ||
|
||
import { DataUsageError } from './common/errors'; | ||
|
||
export class NotFoundError extends DataUsageError {} | ||
|
||
export class AutoOpsError extends DataUsageError {} | ||
|
||
export class NoPrivilegeMeteringError extends DataUsageError { | ||
constructor() { | ||
super( | ||
'You do not have the necessary privileges to access data stream statistics. Please contact your administrator.' | ||
); | ||
} | ||
} | ||
|
||
export class NoIndicesMeteringError extends DataUsageError { | ||
constructor() { | ||
super( | ||
'No data streams or indices are available for the current user. Ensure that the data streams or indices you are authorized to access have been created and contain data. If you believe this is an error, please contact your administrator.' | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
...serverless/api_integration/test_suites/common/data_usage/tests/data_streams_privileges.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* | ||
* 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 expect from '@kbn/expect'; | ||
import { DataStreamsResponseBodySchemaBody } from '@kbn/data-usage-plugin/common/rest_types'; | ||
import { DATA_USAGE_DATA_STREAMS_API_ROUTE } from '@kbn/data-usage-plugin/common'; | ||
import type { RoleCredentials } from '@kbn/ftr-common-functional-services'; | ||
import { | ||
NoIndicesMeteringError, | ||
NoPrivilegeMeteringError, | ||
} from '@kbn/data-usage-plugin/server/errors'; | ||
import { FtrProviderContext } from '../../../../ftr_provider_context'; | ||
|
||
export default function ({ getService }: FtrProviderContext) { | ||
const svlDatastreamsHelpers = getService('svlDatastreamsHelpers'); | ||
const svlCommonApi = getService('svlCommonApi'); | ||
const samlAuth = getService('samlAuth'); | ||
const supertestWithoutAuth = getService('supertestWithoutAuth'); | ||
const testDataStreamName = 'test-data-stream'; | ||
const otherTestDataStreamName = 'other-test-data-stream'; | ||
let roleAuthc: RoleCredentials; | ||
|
||
describe('privileges with custom roles', function () { | ||
// custom role testing is not supported in MKI | ||
// the metering api which this route calls requires one of: monitor,view_index_metadata,manage,all | ||
this.tags(['skipSvlOblt', 'skipMKI']); | ||
before(async () => { | ||
await svlDatastreamsHelpers.createDataStream(testDataStreamName); | ||
await svlDatastreamsHelpers.createDataStream(otherTestDataStreamName); | ||
}); | ||
after(async () => { | ||
await svlDatastreamsHelpers.deleteDataStream(testDataStreamName); | ||
await svlDatastreamsHelpers.deleteDataStream(otherTestDataStreamName); | ||
}); | ||
afterEach(async () => { | ||
await samlAuth.invalidateM2mApiKeyWithRoleScope(roleAuthc); | ||
await samlAuth.deleteCustomRole(); | ||
}); | ||
it('returns all data streams for indices with necessary privileges', async () => { | ||
await samlAuth.setCustomRole({ | ||
elasticsearch: { | ||
indices: [{ names: ['*'], privileges: ['all'] }], | ||
}, | ||
kibana: [ | ||
{ | ||
base: ['all'], | ||
feature: {}, | ||
spaces: ['*'], | ||
}, | ||
], | ||
}); | ||
roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('customRole'); | ||
const res = await supertestWithoutAuth | ||
.get(DATA_USAGE_DATA_STREAMS_API_ROUTE) | ||
.query({ includeZeroStorage: true }) | ||
.set(svlCommonApi.getInternalRequestHeader()) | ||
.set(roleAuthc.apiKeyHeader) | ||
.set('elastic-api-version', '1'); | ||
|
||
const dataStreams: DataStreamsResponseBodySchemaBody = res.body; | ||
const foundTestDataStream = dataStreams.find((stream) => stream.name === testDataStreamName); | ||
const foundTestDataStream2 = dataStreams.find( | ||
(stream) => stream.name === otherTestDataStreamName | ||
); | ||
expect(res.statusCode).to.be(200); | ||
expect(foundTestDataStream?.name).to.be(testDataStreamName); | ||
expect(foundTestDataStream2?.name).to.be(otherTestDataStreamName); | ||
}); | ||
it('returns data streams for only a subset of indices with necessary privileges', async () => { | ||
await samlAuth.setCustomRole({ | ||
elasticsearch: { | ||
indices: [{ names: ['test-data-stream*'], privileges: ['all'] }], | ||
}, | ||
kibana: [ | ||
{ | ||
base: ['all'], | ||
feature: {}, | ||
spaces: ['*'], | ||
}, | ||
], | ||
}); | ||
roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('customRole'); | ||
const res = await supertestWithoutAuth | ||
.get(DATA_USAGE_DATA_STREAMS_API_ROUTE) | ||
.query({ includeZeroStorage: true }) | ||
.set(svlCommonApi.getInternalRequestHeader()) | ||
.set(roleAuthc.apiKeyHeader) | ||
.set('elastic-api-version', '1'); | ||
|
||
const dataStreams: DataStreamsResponseBodySchemaBody = res.body; | ||
const foundTestDataStream = dataStreams.find((stream) => stream.name === testDataStreamName); | ||
const dataStreamNoPermission = dataStreams.find( | ||
(stream) => stream.name === otherTestDataStreamName | ||
); | ||
|
||
expect(res.statusCode).to.be(200); | ||
expect(foundTestDataStream?.name).to.be(testDataStreamName); | ||
expect(dataStreamNoPermission?.name).to.be(undefined); | ||
}); | ||
|
||
it('returns no data streams without necessary privileges', async () => { | ||
await samlAuth.setCustomRole({ | ||
elasticsearch: { | ||
indices: [{ names: ['*'], privileges: ['write'] }], | ||
}, | ||
kibana: [ | ||
{ | ||
base: ['all'], | ||
feature: {}, | ||
spaces: ['*'], | ||
}, | ||
], | ||
}); | ||
roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('customRole'); | ||
const res = await supertestWithoutAuth | ||
.get(DATA_USAGE_DATA_STREAMS_API_ROUTE) | ||
.query({ includeZeroStorage: true }) | ||
.set(svlCommonApi.getInternalRequestHeader()) | ||
.set(roleAuthc.apiKeyHeader) | ||
.set('elastic-api-version', '1'); | ||
|
||
expect(res.statusCode).to.be(403); | ||
expect(res.body.message).to.contain(new NoPrivilegeMeteringError().message); | ||
}); | ||
|
||
it('returns no data streams when there are none it has access to', async () => { | ||
await samlAuth.setCustomRole({ | ||
elasticsearch: { | ||
indices: [{ names: ['none*'], privileges: ['all'] }], | ||
}, | ||
kibana: [ | ||
{ | ||
base: ['all'], | ||
feature: {}, | ||
spaces: ['*'], | ||
}, | ||
], | ||
}); | ||
roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('customRole'); | ||
const res = await supertestWithoutAuth | ||
.get(DATA_USAGE_DATA_STREAMS_API_ROUTE) | ||
.query({ includeZeroStorage: true }) | ||
.set(svlCommonApi.getInternalRequestHeader()) | ||
.set(roleAuthc.apiKeyHeader) | ||
.set('elastic-api-version', '1'); | ||
|
||
expect(res.statusCode).to.be(404); | ||
expect(res.body.message).to.contain(new NoIndicesMeteringError().message); | ||
}); | ||
}); | ||
} |
Oops, something went wrong.