kibana/x-pack/test/api_integration/apis/security/privileges.ts
Pierre Gayvallet d4b2a5145a
SavedObjects tagging MVP (#79096)
* create xpack plugin skeleton, start to implement management section

* add tag creation modal

* first implementation of the tags table

* use InMemoryTable

* add edit modal and delete action

* update plugin list

* add tag list, fix types

* add capabilities check on client-side

* add tag combo box component

* add missing i18n keys

* fix privilege FTR tests

* add base structure for FTR tests

* fix feature ftr test

* use string literals for i18n

* create savedObjectsTaggingOss plugin, move API types to oss plugin, start to wire to SO management page.

* update plugin list

* fix types

* allow to use `_find` with multiple references

* add FTR test for _find API on references fields

* add _find integration tests

* update generated doc

* start to implement tag filtering on SO management section

* update generated docs

* wire tagging API to dashboard listing page

* fix i18n namespace

* fix type & tests

* update dashboard listing snapshots

* adapt FTR listingTable service to search for parsable queries

* wite tagging API to visualize listing

* update tagging plugin limits

* add server-side and client-side validation for tag create/edit

* rename title field to name

* fix types

* fix types bis

* add removeReferencesTo API to SOR/SOC

* update generated doc

* add server-side unit test for `savedObjectsTagging` plugin

* move tagging API types to its own file

* add savedObjectsTaggingOss mock

* add tags_cache tests

* add tests for client-side tag client

* extract uiApi to distinct files

* various API improvements

* add more tests

* add link between tag and so management sections + add connection counts

* add base functional test suite for tagging

* add more FTR tests

* improve feature control func test

* update codeowners

* update generated doc

* fix access to proxy modal

* adapt SO save modal to allow to add tag field

* add SO decorator registry and tag implementation

* add unit tests for SO tag decorator

* add functional tests for visualize integration

* add tag SO read permission for vis/dash feature

* add RBAC api integ tests

* add API integration tests

* add test for getTagConnectionsUrl

* add SOM test suite

* add dashboard integration suite

* remove test line

* add missing unit tests

* improve API types doc

* fix create modal save button label

* remove console.log

* improve doc

* self review

* add refresh interval for tag cache

* improve page object doc

* minor cleanup

* address review comments

* small layout fixes

* add initial focus

* use lazy accessor for tag request handler context

* adapt SOM export and export route to handle references

* remove icon from feature config due to master changes

* fix SO table tests

* update generated docs

* sort tags by name in filter dropdown and listing component

* wire SO tagging to dashboard save modal

* fix types

* - add 'create tag' action in tag selector
- add notifications on update/create/delete from management
- delete modal wording

* add description max length validation

* remove real-time validation

* fix i18n bundle id

* update expected size of savedObjectsTagging plugin

* use own useIfMounted

* update limit again, contract components cannot be lazy loaded atm.

* math is hard

* remove single usage of lodash for bundle size

* add async imports for create/edit modal

* add FTR test for 'create tag' action from tag selector

* allow 'create new' option to prepopulate name field

* extract savedObjectToTag

* add advancedSettings read user for security api_integ suite

* add audit login for security client wrapper

* use import type when possible

* wire SO tagging to lens visualization

* fix lens jest test

* Fix `create tag` option being selected when closing the selector dropdown

* add sorting to tag column from getTableColumnDef

* address some of restrry comments

* rename tag selector's setSelected option to onTagsSelected

* fix audit logging even type for saved_object_remove_references

* update plugin size limit to current size

* adapt maxlength validation wording

* remove selection column until we have batch action menu

* remove connections link when user lack read privilege to savedObjectManagement

* forbid registering multiple SO decorators with the same priority

* add so decorator test

* extract getTagFindReferences and create API mock

* update audit-logging ascidoc

* doc nit

* throw conflict error if update returns any failure

* use refresh=true as default

* wording nits

* export: rename `references` to `hasReference`

* update generated doc

* set description max length to 100

* do not initialize tag cache on anonymous pages

* split fetchObjectsToExport into two distinct functions

* change tag client `delete` call order

* tsdoc nits

* more nits

* add README for oss plugin

* add oss plugin start tests

* SavedObject.find: rename `references` to `hasReference`

* change section description label

* remove url prefix constants

* last nits and comments

* update generated doc
2020-11-03 10:33:18 +01:00

150 lines
6.3 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import util from 'util';
import { isEqual, isEqualWith } from 'lodash';
import expect from '@kbn/expect/expect.js';
import { RawKibanaPrivileges } from '../../../../plugins/security/common/model';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
describe('Privileges', () => {
describe('GET /api/security/privileges', () => {
it('should return a privilege map with all known privileges, without actions', async () => {
// If you're adding a privilege to the following, that's great!
// If you're removing a privilege, this breaks backwards compatibility
// Roles are associated with these privileges, and we shouldn't be removing them in a minor version.
const expected = {
features: {
discover: ['all', 'read', 'minimal_all', 'minimal_read', 'url_create'],
visualize: ['all', 'read', 'minimal_all', 'minimal_read', 'url_create'],
dashboard: ['all', 'read', 'minimal_all', 'minimal_read', 'url_create'],
dev_tools: ['all', 'read'],
advancedSettings: ['all', 'read'],
indexPatterns: ['all', 'read'],
savedObjectsManagement: ['all', 'read'],
savedObjectsTagging: ['all', 'read'],
timelion: ['all', 'read'],
graph: ['all', 'read'],
maps: ['all', 'read'],
canvas: ['all', 'read'],
infrastructure: ['all', 'read'],
logs: ['all', 'read'],
uptime: ['all', 'read'],
apm: ['all', 'read'],
ml: ['all', 'read'],
siem: ['all', 'read'],
ingestManager: ['all', 'read'],
stackAlerts: ['all', 'read'],
actions: ['all', 'read'],
},
global: ['all', 'read'],
space: ['all', 'read'],
reserved: ['ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'],
};
await supertest
.get('/api/security/privileges')
.set('kbn-xsrf', 'xxx')
.send()
.expect(200)
.expect((res: any) => {
// when comparing privileges, the order of the features doesn't matter (but the order of the privileges does)
// supertest uses assert.deepStrictEqual.
// expect.js doesn't help us here.
// and lodash's isEqual doesn't know how to compare Sets.
const success = isEqualWith(res.body, expected, (value, other, key) => {
if (Array.isArray(value) && Array.isArray(other)) {
if (key === 'reserved') {
// order does not matter for the reserved privilege set.
return isEqual(value.sort(), other.sort());
}
// order matters for the rest, as the UI assumes they are returned in a descending order of permissiveness.
return isEqual(value, other);
}
// Lodash types aren't correct, `undefined` should be supported as a return value here and it
// has special meaning.
return undefined as any;
});
if (!success) {
throw new Error(
`Expected ${util.inspect(res.body)} to equal ${util.inspect(expected)}`
);
}
})
.expect(200);
});
});
describe('GET /api/security/privileges?includeActions=true', () => {
// The UI assumes that no wildcards are present when calculating the effective set of privileges.
// If this changes, then the "privilege calculators" will need revisiting to account for these wildcards.
it('should return a privilege map with actions which do not include wildcards', async () => {
await supertest
.get('/api/security/privileges?includeActions=true')
.set('kbn-xsrf', 'xxx')
.send()
.expect(200)
.expect((res: any) => {
const { features, global, space, reserved } = res.body as RawKibanaPrivileges;
expect(features).to.be.an('object');
expect(global).to.be.an('object');
expect(space).to.be.an('object');
expect(reserved).to.be.an('object');
Object.entries(features).forEach(([featureId, featurePrivs]) => {
Object.values(featurePrivs).forEach((actions) => {
expect(actions).to.be.an('array');
actions.forEach((action) => {
expect(action).to.be.a('string');
expect(action.indexOf('*')).to.eql(
-1,
`Feature ${featureId} with action ${action} cannot contain a wildcard`
);
});
});
});
Object.entries(global).forEach(([privilegeId, actions]) => {
expect(actions).to.be.an('array');
actions.forEach((action) => {
expect(action).to.be.a('string');
expect(action.indexOf('*')).to.eql(
-1,
`Global privilege ${privilegeId} with action ${action} cannot contain a wildcard`
);
});
});
Object.entries(space).forEach(([privilegeId, actions]) => {
expect(actions).to.be.an('array');
actions.forEach((action) => {
expect(action).to.be.a('string');
expect(action.indexOf('*')).to.eql(
-1,
`Space privilege ${privilegeId} with action ${action} cannot contain a wildcard`
);
});
});
Object.entries(reserved).forEach(([privilegeId, actions]) => {
expect(actions).to.be.an('array');
actions.forEach((action) => {
expect(action).to.be.a('string');
expect(action.indexOf('*')).to.eql(
-1,
`Reserved privilege ${privilegeId} with action ${action} cannot contain a wildcard`
);
});
});
});
});
});
});
}