diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/cluster_privileges.test.tsx.snap b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/cluster_privileges.test.tsx.snap index 457473172c2e6ce..b38b7e6634ada0b 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/cluster_privileges.test.tsx.snap +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/__snapshots__/cluster_privileges.test.tsx.snap @@ -7,10 +7,12 @@ exports[`it renders without crashing 1`] = ` > { const role: Role = { @@ -24,8 +25,37 @@ test('it renders without crashing', () => { ); expect(wrapper).toMatchSnapshot(); }); + +test('it allows for custom cluster privileges', () => { + const role: Role = { + name: '', + elasticsearch: { + cluster: ['existing-custom', 'monitor'], + indices: [], + run_as: [], + }, + kibana: [], + }; + + const onChange = jest.fn(); + const wrapper = mountWithIntl( + + ); + + const clusterPrivsSelect = wrapper.find( + 'EuiComboBox[data-test-subj="cluster-privileges-combobox"]' + ); + + (clusterPrivsSelect.props() as any).onCreateOption('custom-cluster-privilege'); + + expect(onChange).toHaveBeenCalledWith(['existing-custom', 'monitor', 'custom-cluster-privilege']); +}); diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/cluster_privileges.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/cluster_privileges.tsx index b6bd1930a1d27fb..7d9dab6bebffd5e 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/cluster_privileges.tsx +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/cluster_privileges.tsx @@ -6,18 +6,20 @@ import { EuiComboBox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { Component } from 'react'; +import _ from 'lodash'; import { Role } from '../../../../../../../common/model'; import { isReadOnlyRole } from '../../../../../../lib/role_utils'; interface Props { role: Role; - availableClusterPrivileges: string[]; + builtinClusterPrivileges: string[]; onChange: (privs: string[]) => void; } export class ClusterPrivileges extends Component { public render() { - return {this.buildComboBox(this.props.availableClusterPrivileges)}; + const availableClusterPrivileges = this.getAvailableClusterPrivileges(); + return {this.buildComboBox(availableClusterPrivileges)}; } public buildComboBox = (items: string[]) => { @@ -32,9 +34,11 @@ export class ClusterPrivileges extends Component { return ( @@ -44,4 +48,17 @@ export class ClusterPrivileges extends Component { public onClusterPrivilegesChange = (selectedPrivileges: any) => { this.props.onChange(selectedPrivileges.map((priv: any) => priv.label)); }; + + private onCreateCustomPrivilege = (customPrivilege: string) => { + this.props.onChange([...this.props.role.elasticsearch.cluster, customPrivilege]); + }; + + private getAvailableClusterPrivileges = () => { + const availableClusterPrivileges = [ + ...this.props.builtinClusterPrivileges, + ...this.props.role.elasticsearch.cluster, + ]; + + return _.uniq(availableClusterPrivileges); + }; } diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/elasticsearch_privileges.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/elasticsearch_privileges.tsx index 7540cf2cedab740..c0e6db3fef21c83 100644 --- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/elasticsearch_privileges.tsx +++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/es/elasticsearch_privileges.tsx @@ -99,7 +99,7 @@ export class ElasticsearchPrivileges extends Component {