mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [Harden API Actions Definition standards (#193140)](https://github.com/elastic/kibana/pull/193140) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Sid","email":"siddharthmantri1@gmail.com"},"sourceCommit":{"committedDate":"2024-10-15T14:03:07Z","message":"Harden API Actions Definition standards (#193140)\n\nCloses https://github.com/elastic/kibana/issues/191716\r\n\r\n## Summary\r\n\r\nThis PR introduces a new signature for the API Actions `get` function\r\nthat validates standard API operations as part of the name of the API\r\naction.\r\n\r\n\r\n### Changes\r\n- Added a new Enum for a standard set of operations we expect all API\r\nactions to move to\r\n- Old function signature based on a single subject marked as deprecated.\r\n\r\n### Release Notes\r\nEnforce standard on API Actions definitions by separating operations and\r\nsubjects.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Elena Shostak <elena.shostak@elastic.co>","sha":"343a33a637dfc2b2f68a3e35cc69bcc4f0566ced","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team:Security","Feature:Security/Authorization","Feature:Hardening","v9.0.0","backport:prev-minor"],"number":193140,"url":"https://github.com/elastic/kibana/pull/193140","mergeCommit":{"message":"Harden API Actions Definition standards (#193140)\n\nCloses https://github.com/elastic/kibana/issues/191716\r\n\r\n## Summary\r\n\r\nThis PR introduces a new signature for the API Actions `get` function\r\nthat validates standard API operations as part of the name of the API\r\naction.\r\n\r\n\r\n### Changes\r\n- Added a new Enum for a standard set of operations we expect all API\r\nactions to move to\r\n- Old function signature based on a single subject marked as deprecated.\r\n\r\n### Release Notes\r\nEnforce standard on API Actions definitions by separating operations and\r\nsubjects.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Elena Shostak <elena.shostak@elastic.co>","sha":"343a33a637dfc2b2f68a3e35cc69bcc4f0566ced"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/193140","number":193140,"mergeCommit":{"message":"Harden API Actions Definition standards (#193140)\n\nCloses https://github.com/elastic/kibana/issues/191716\r\n\r\n## Summary\r\n\r\nThis PR introduces a new signature for the API Actions `get` function\r\nthat validates standard API operations as part of the name of the API\r\naction.\r\n\r\n\r\n### Changes\r\n- Added a new Enum for a standard set of operations we expect all API\r\nactions to move to\r\n- Old function signature based on a single subject marked as deprecated.\r\n\r\n### Release Notes\r\nEnforce standard on API Actions definitions by separating operations and\r\nsubjects.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\r\nCo-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>\r\nCo-authored-by: Elena Shostak <elena.shostak@elastic.co>","sha":"343a33a637dfc2b2f68a3e35cc69bcc4f0566ced"}}]}] BACKPORT-->
This commit is contained in:
parent
8a81c046f7
commit
f132d6bb49
10 changed files with 164 additions and 92 deletions
|
@ -14,6 +14,7 @@ import type {
|
|||
StatsGetterConfig,
|
||||
} from '@kbn/telemetry-collection-manager-plugin/server';
|
||||
import type { SecurityPluginStart } from '@kbn/security-plugin/server';
|
||||
import { ApiOperation } from '@kbn/security-plugin-types-server';
|
||||
import { RequestHandler } from '@kbn/core-http-server';
|
||||
import { FetchSnapshotTelemetry } from '../../common/routes';
|
||||
import { UsageStatsBody, v2 } from '../../common/types';
|
||||
|
@ -50,7 +51,7 @@ export function registerTelemetryUsageStatsRoutes(
|
|||
// security API directly to check privileges for this action. Note that the 'decryptedTelemetry' API privilege string is only
|
||||
// granted to users that have "Global All" or "Global Read" privileges in Kibana.
|
||||
const { checkPrivilegesWithRequest, actions } = security.authz;
|
||||
const privileges = { kibana: actions.api.get('decryptedTelemetry') };
|
||||
const privileges = { kibana: actions.api.get(ApiOperation.Read, 'decryptedTelemetry') };
|
||||
const { hasAllRequested } = await checkPrivilegesWithRequest(req).globally(privileges);
|
||||
if (!hasAllRequested) {
|
||||
return res.forbidden();
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"@kbn/analytics-collection-utils",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/core-node-server",
|
||||
"@kbn/security-plugin-types-server",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { isString } from 'lodash';
|
||||
|
||||
import type { ApiActions as ApiActionsType } from '@kbn/security-plugin-types-server';
|
||||
import { ApiOperation } from '@kbn/security-plugin-types-server';
|
||||
|
||||
export class ApiActions implements ApiActionsType {
|
||||
private readonly prefix: string;
|
||||
|
@ -16,11 +17,33 @@ export class ApiActions implements ApiActionsType {
|
|||
this.prefix = `api:`;
|
||||
}
|
||||
|
||||
public get(operation: string) {
|
||||
if (!operation || !isString(operation)) {
|
||||
throw new Error('operation is required and must be a string');
|
||||
private isValidOperation(operation: string): operation is ApiOperation {
|
||||
return Object.values(ApiOperation).includes(operation as ApiOperation);
|
||||
}
|
||||
public actionFromRouteTag(routeTag: string) {
|
||||
const [operation, subject] = routeTag.split('_');
|
||||
if (!this.isValidOperation(operation)) {
|
||||
throw new Error('operation is required and must be a valid ApiOperation');
|
||||
}
|
||||
return this.get(operation, subject);
|
||||
}
|
||||
|
||||
public get(operation: string | ApiOperation, subject?: string) {
|
||||
if (arguments.length === 1) {
|
||||
if (!isString(operation) || !operation) {
|
||||
throw new Error('operation is required and must be a string');
|
||||
}
|
||||
return `${this.prefix}${operation}`;
|
||||
}
|
||||
|
||||
return `${this.prefix}${operation}`;
|
||||
if (!isString(subject) || !subject) {
|
||||
throw new Error('subject is required and must be a string');
|
||||
}
|
||||
|
||||
if (!this.isValidOperation(operation)) {
|
||||
throw new Error('operation is required and must be a valid ApiOperation');
|
||||
}
|
||||
|
||||
return `${this.prefix}${operation}_${subject}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { KibanaFeature } from '@kbn/features-plugin/server';
|
||||
import { featuresPluginMock } from '@kbn/features-plugin/server/mocks';
|
||||
import { ApiOperation } from '@kbn/security-plugin-types-server';
|
||||
|
||||
import { getReplacedByForPrivilege, privilegesFactory } from './privileges';
|
||||
import { licenseMock } from '../__fixtures__/licensing.mock';
|
||||
|
@ -793,10 +794,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -965,10 +968,12 @@ describe('features', () => {
|
|||
|
||||
const expectedActions = [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1124,7 +1129,9 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
actions.ui.get('catalogue', 'read-catalogue-1'),
|
||||
actions.ui.get('catalogue', 'read-catalogue-2'),
|
||||
|
@ -1243,7 +1250,9 @@ describe('features', () => {
|
|||
|
||||
const expectedActions = [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
actions.ui.get('catalogue', 'read-catalogue-2'),
|
||||
actions.ui.get('management', 'read-management', 'read-management-2'),
|
||||
|
@ -1341,10 +1350,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1359,7 +1370,9 @@ describe('features', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
]);
|
||||
});
|
||||
|
@ -1410,10 +1423,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1428,7 +1443,9 @@ describe('features', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
]);
|
||||
});
|
||||
|
@ -1508,10 +1525,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1526,7 +1545,9 @@ describe('features', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
]);
|
||||
});
|
||||
|
@ -1578,10 +1599,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1596,7 +1619,9 @@ describe('features', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
]);
|
||||
});
|
||||
|
@ -1677,10 +1702,12 @@ describe('features', () => {
|
|||
const actual = privileges.get();
|
||||
expect(actual).toHaveProperty(`${group}.all`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get('manageSpaces')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Read, 'features')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'taskManager')] : []),
|
||||
...(expectGetFeatures ? [actions.api.get(ApiOperation.Manage, 'spaces')] : []),
|
||||
...(expectManageSpaces
|
||||
? [
|
||||
actions.space.manage,
|
||||
|
@ -1695,7 +1722,9 @@ describe('features', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty(`${group}.read`, [
|
||||
actions.login,
|
||||
...(expectDecryptedTelemetry ? [actions.api.get('decryptedTelemetry')] : []),
|
||||
...(expectDecryptedTelemetry
|
||||
? [actions.api.get(ApiOperation.Read, 'decryptedTelemetry')]
|
||||
: []),
|
||||
...(expectGlobalSettings ? [actions.ui.get('globalSettings', 'show')] : []),
|
||||
]);
|
||||
});
|
||||
|
@ -1945,10 +1974,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -1960,7 +1989,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.ui.get('foo', 'foo'),
|
||||
]);
|
||||
|
@ -2104,10 +2133,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -2137,7 +2166,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'bulk_get'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'get'),
|
||||
|
@ -2340,10 +2369,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -2354,7 +2383,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
]);
|
||||
|
||||
|
@ -2479,10 +2508,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -2512,7 +2541,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.ui.get('foo', 'foo'),
|
||||
]);
|
||||
|
@ -2658,10 +2687,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -2672,7 +2701,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
]);
|
||||
|
||||
|
@ -2795,10 +2824,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -2828,7 +2857,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'bulk_get'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'get'),
|
||||
|
@ -3010,10 +3039,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -3043,7 +3072,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'bulk_get'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'get'),
|
||||
|
@ -3244,10 +3273,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -3277,7 +3306,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'bulk_get'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'get'),
|
||||
|
@ -3514,10 +3543,10 @@ describe('subFeatures', () => {
|
|||
|
||||
expect(actual).toHaveProperty('global.all', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -3565,7 +3594,7 @@ describe('subFeatures', () => {
|
|||
]);
|
||||
expect(actual).toHaveProperty('global.read', [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'bulk_get'),
|
||||
actions.savedObject.get('all-sub-feature-type', 'get'),
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
isMinimalPrivilegeId,
|
||||
} from '@kbn/security-authorization-core-common';
|
||||
import type { RawKibanaPrivileges, SecurityLicense } from '@kbn/security-plugin-types-common';
|
||||
import { ApiOperation } from '@kbn/security-plugin-types-server';
|
||||
|
||||
import { featurePrivilegeBuilderFactory } from './feature_privilege_builder';
|
||||
import type { Actions } from '../actions';
|
||||
|
@ -210,10 +211,10 @@ export function privilegesFactory(
|
|||
global: {
|
||||
all: [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get('features'),
|
||||
actions.api.get('taskManager'),
|
||||
actions.api.get('manageSpaces'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'features'),
|
||||
actions.api.get(ApiOperation.Manage, 'taskManager'),
|
||||
actions.api.get(ApiOperation.Manage, 'spaces'),
|
||||
actions.space.manage,
|
||||
actions.ui.get('spaces', 'manage'),
|
||||
actions.ui.get('management', 'kibana', 'spaces'),
|
||||
|
@ -225,7 +226,7 @@ export function privilegesFactory(
|
|||
],
|
||||
read: [
|
||||
actions.login,
|
||||
actions.api.get('decryptedTelemetry'),
|
||||
actions.api.get(ApiOperation.Read, 'decryptedTelemetry'),
|
||||
actions.ui.get('globalSettings', 'show'),
|
||||
...readActions,
|
||||
],
|
||||
|
|
|
@ -88,3 +88,4 @@ export {
|
|||
getRestApiKeyWithKibanaPrivilegesSchema,
|
||||
} from './src/authentication';
|
||||
export { getKibanaRoleSchema, elasticsearchRoleSchema, GLOBAL_RESOURCE } from './src/authorization';
|
||||
export { ApiOperation } from './src/authorization';
|
||||
|
|
|
@ -6,5 +6,19 @@
|
|||
*/
|
||||
|
||||
export interface ApiActions {
|
||||
get(operation: string): string;
|
||||
get(operation: ApiOperation, subject: string): string;
|
||||
|
||||
/**
|
||||
* @deprecated use `get(operation: ApiOperation, subject: string)` instead
|
||||
*/
|
||||
get(subject: string): string;
|
||||
actionFromRouteTag(routeTag: string): string;
|
||||
}
|
||||
|
||||
export enum ApiOperation {
|
||||
Read = 'read',
|
||||
Create = 'create',
|
||||
Update = 'update',
|
||||
Delete = 'delete',
|
||||
Manage = 'manage',
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
export type { Actions } from './actions';
|
||||
export type { AlertingActions } from './alerting';
|
||||
export type { ApiActions } from './api';
|
||||
export { ApiOperation } from './api';
|
||||
export type { AppActions } from './app';
|
||||
export type { CasesActions } from './cases';
|
||||
export type { SavedObjectActions } from './saved_object';
|
||||
|
|
|
@ -15,6 +15,7 @@ export type {
|
|||
SpaceActions,
|
||||
UIActions,
|
||||
} from './actions';
|
||||
export { ApiOperation } from './actions';
|
||||
export type { AuthorizationServiceSetup } from './authorization_service';
|
||||
export type {
|
||||
CheckPrivilegesOptions,
|
||||
|
|
|
@ -22,7 +22,7 @@ export function defineRoutes({ router, featureRegistry }: RouteDefinitionParams)
|
|||
{
|
||||
path: '/api/features',
|
||||
options: {
|
||||
tags: ['access:features'],
|
||||
tags: ['access:read_features'],
|
||||
access: 'public',
|
||||
summary: `Get features`,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue