mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
* 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
150 lines
6.3 KiB
TypeScript
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`
|
|
);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|