mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Security Solution][Endpoint] Require all spaces flag for sub features (#143733)
* Adds requireAllSpaces flag for subfeatures. * fixes ts errors * Adds unit test on sub features form UI * Adds unit test for validateKibanaPrivileges function with subfeatures * Fixes failing tests * Rename some vars and reorder return null. Also skip two tests that are not working as expected * Reorder if condition for performance optimisation * Fixes unit test * PR feedback - remove useMemo and use a function Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0c1ae8c1c2
commit
217d2d0c4e
17 changed files with 609 additions and 22 deletions
|
@ -16,6 +16,17 @@ export interface SubFeatureConfig {
|
|||
/** Display name for this sub-feature */
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Whether or not this privilege should only be granted to `All Spaces *`. Should be used for features that do not
|
||||
* support Spaces. Defaults to `false`.
|
||||
*/
|
||||
requireAllSpaces?: boolean;
|
||||
|
||||
/**
|
||||
* Optional message to display on the Role Management screen when configuring permissions for this feature.
|
||||
*/
|
||||
privilegesTooltip?: string;
|
||||
|
||||
/** Collection of privilege groups */
|
||||
privilegeGroups: readonly SubFeaturePrivilegeGroupConfig[];
|
||||
}
|
||||
|
@ -90,6 +101,10 @@ export class SubFeature {
|
|||
return this.config.privilegeGroups;
|
||||
}
|
||||
|
||||
public get requireAllSpaces() {
|
||||
return this.config.requireAllSpaces ?? false;
|
||||
}
|
||||
|
||||
public toRaw() {
|
||||
return { ...this.config };
|
||||
}
|
||||
|
|
|
@ -163,6 +163,8 @@ const kibanaMutuallyExclusiveSubFeaturePrivilegeSchema =
|
|||
|
||||
const kibanaSubFeatureSchema = schema.object({
|
||||
name: schema.string(),
|
||||
requireAllSpaces: schema.maybe(schema.boolean()),
|
||||
privilegesTooltip: schema.maybe(schema.string()),
|
||||
privilegeGroups: schema.maybe(
|
||||
schema.arrayOf(
|
||||
schema.oneOf([
|
||||
|
|
|
@ -226,4 +226,31 @@ export const kibanaFeatures = [
|
|||
},
|
||||
],
|
||||
}),
|
||||
createFeature({
|
||||
id: 'with_require_all_spaces_sub_features',
|
||||
name: 'Require all spaces Sub Features',
|
||||
subFeatures: [
|
||||
{
|
||||
name: 'Require all spaces Sub Feature',
|
||||
requireAllSpaces: true,
|
||||
privilegeGroups: [
|
||||
{
|
||||
groupType: 'mutually_exclusive',
|
||||
privileges: [
|
||||
{
|
||||
id: 'cool_toggle_1',
|
||||
name: 'Cool toggle 1',
|
||||
includeIn: 'read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: ['cool_toggle_1-ui'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
|
|
@ -107,6 +107,10 @@ describe('FeatureTable', () => {
|
|||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -157,6 +161,14 @@ describe('FeatureTable', () => {
|
|||
}
|
||||
: { subFeaturePrivileges: [] }),
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'all',
|
||||
...(canCustomizeSubFeaturePrivileges
|
||||
? {
|
||||
subFeaturePrivileges: ['cool_toggle_1'],
|
||||
}
|
||||
: { subFeaturePrivileges: [] }),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -208,6 +220,10 @@ describe('FeatureTable', () => {
|
|||
}
|
||||
: { subFeaturePrivileges: [] }),
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -302,6 +318,10 @@ describe('FeatureTable', () => {
|
|||
primaryFeaturePrivilege: 'read',
|
||||
subFeaturePrivileges: ['cool_all'],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -684,6 +704,10 @@ describe('FeatureTable', () => {
|
|||
'cool_all',
|
||||
],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -722,6 +746,10 @@ describe('FeatureTable', () => {
|
|||
primaryFeaturePrivilege: 'all',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -760,6 +788,10 @@ describe('FeatureTable', () => {
|
|||
primaryFeaturePrivilege: 'read',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -888,6 +920,10 @@ describe('FeatureTable', () => {
|
|||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
primaryFeaturePrivilege: 'none',
|
||||
subFeaturePrivileges: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ export class FeatureTable extends Component<Props, State> {
|
|||
selectedFeaturePrivileges={
|
||||
this.props.role.kibana[this.props.privilegeIndex].feature[feature.id] ?? []
|
||||
}
|
||||
allSpacesSelected={this.props.allSpacesSelected}
|
||||
disabled={this.props.disabled}
|
||||
licenseAllowsSubFeatPrivCustomization={
|
||||
this.props.canCustomizeSubFeaturePrivileges
|
||||
|
|
|
@ -49,6 +49,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['minimal_read']}
|
||||
onChange={jest.fn()}
|
||||
licenseAllowsSubFeatPrivCustomization={false}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -86,6 +87,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['none']}
|
||||
onChange={jest.fn()}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -118,6 +120,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['minimal_read']}
|
||||
onChange={jest.fn()}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -153,6 +156,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['read']}
|
||||
onChange={jest.fn()}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -186,6 +190,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['read']}
|
||||
onChange={jest.fn()}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -223,6 +228,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['read']}
|
||||
onChange={onChange}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -263,6 +269,7 @@ describe('FeatureTableExpandedRow', () => {
|
|||
selectedFeaturePrivileges={['minimal_read', 'cool_read', 'cool_toggle_2']}
|
||||
onChange={onChange}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -272,4 +279,76 @@ describe('FeatureTableExpandedRow', () => {
|
|||
|
||||
expect(onChange).toHaveBeenCalledWith('with_sub_features', ['read']);
|
||||
});
|
||||
|
||||
it('require all spaces enabled and allSpacesSelected is false: option is disabled', () => {
|
||||
const role = createRole([
|
||||
{
|
||||
base: [],
|
||||
feature: {
|
||||
with_require_all_spaces_sub_features: ['cool_toggle_1'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
]);
|
||||
|
||||
const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures);
|
||||
const calculator = new PrivilegeFormCalculator(kibanaPrivileges, role);
|
||||
const feature = kibanaPrivileges.getSecuredFeature('with_require_all_spaces_sub_features');
|
||||
const onChange = jest.fn();
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
<FeatureTableExpandedRow
|
||||
feature={feature}
|
||||
privilegeIndex={0}
|
||||
privilegeCalculator={calculator}
|
||||
selectedFeaturePrivileges={['minimal_all']}
|
||||
onChange={onChange}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={false}
|
||||
/>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
findTestSubject(wrapper, 'customizeSubFeaturePrivileges').simulate('click');
|
||||
});
|
||||
|
||||
const object = wrapper.find('SubFeatureForm');
|
||||
expect(object.props()).toMatchObject({ disabled: true });
|
||||
});
|
||||
|
||||
it('require all spaces enabled and allSpacesSelected is true: option is enabled', () => {
|
||||
const role = createRole([
|
||||
{
|
||||
base: [],
|
||||
feature: {
|
||||
with_require_all_spaces_sub_features: ['cool_toggle_1'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
]);
|
||||
|
||||
const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures);
|
||||
const calculator = new PrivilegeFormCalculator(kibanaPrivileges, role);
|
||||
const feature = kibanaPrivileges.getSecuredFeature('with_require_all_spaces_sub_features');
|
||||
const onChange = jest.fn();
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
<FeatureTableExpandedRow
|
||||
feature={feature}
|
||||
privilegeIndex={0}
|
||||
privilegeCalculator={calculator}
|
||||
selectedFeaturePrivileges={['minimal_all']}
|
||||
onChange={onChange}
|
||||
licenseAllowsSubFeatPrivCustomization={true}
|
||||
allSpacesSelected={true}
|
||||
/>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
findTestSubject(wrapper, 'customizeSubFeaturePrivileges').simulate('click');
|
||||
});
|
||||
|
||||
const object = wrapper.find('SubFeatureForm');
|
||||
expect(object.props()).toMatchObject({ disabled: false });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@ interface Props {
|
|||
privilegeCalculator: PrivilegeFormCalculator;
|
||||
privilegeIndex: number;
|
||||
selectedFeaturePrivileges: string[];
|
||||
allSpacesSelected: boolean;
|
||||
disabled?: boolean;
|
||||
licenseAllowsSubFeatPrivCustomization: boolean;
|
||||
onChange: (featureId: string, featurePrivileges: string[]) => void;
|
||||
|
@ -32,6 +33,7 @@ export const FeatureTableExpandedRow = ({
|
|||
privilegeIndex,
|
||||
privilegeCalculator,
|
||||
selectedFeaturePrivileges,
|
||||
allSpacesSelected,
|
||||
disabled,
|
||||
licenseAllowsSubFeatPrivCustomization,
|
||||
}: Props) => {
|
||||
|
@ -110,6 +112,8 @@ export const FeatureTableExpandedRow = ({
|
|||
</div>
|
||||
</EuiFlexItem>
|
||||
{feature.getSubFeatures().map((subFeature) => {
|
||||
const isDisabledDueToSpaceSelection = subFeature.requireAllSpaces && !allSpacesSelected;
|
||||
|
||||
return (
|
||||
<EuiFlexItem key={subFeature.name}>
|
||||
<SubFeatureForm
|
||||
|
@ -119,7 +123,7 @@ export const FeatureTableExpandedRow = ({
|
|||
subFeature={subFeature}
|
||||
onChange={(updatedPrivileges) => onChange(feature.id, updatedPrivileges)}
|
||||
selectedFeaturePrivileges={selectedFeaturePrivileges}
|
||||
disabled={disabled || !isCustomizing}
|
||||
disabled={disabled || !isCustomizing || isDisabledDueToSpaceSelection}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
|
|
@ -5,7 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiButtonGroup, EuiCheckbox, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import {
|
||||
EuiButtonGroup,
|
||||
EuiCheckbox,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIconTip,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -33,6 +40,27 @@ export const SubFeatureForm = (props: Props) => {
|
|||
.getPrivilegeGroups()
|
||||
.filter((group) => group.privileges.length > 0);
|
||||
|
||||
const getTooltip = () => {
|
||||
if (!props.subFeature.privilegesTooltip) {
|
||||
return null;
|
||||
}
|
||||
const tooltipContent = (
|
||||
<EuiText>
|
||||
<p>{props.subFeature.privilegesTooltip}</p>
|
||||
</EuiText>
|
||||
);
|
||||
return (
|
||||
<EuiIconTip
|
||||
iconProps={{
|
||||
className: 'eui-alignTop',
|
||||
}}
|
||||
type="iInCircle"
|
||||
color="subdued"
|
||||
content={tooltipContent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
if (groupsWithPrivileges.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -40,7 +68,9 @@ export const SubFeatureForm = (props: Props) => {
|
|||
return (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">{props.subFeature.name}</EuiText>
|
||||
<EuiText size="s">
|
||||
{props.subFeature.name} {getTooltip()}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>{groupsWithPrivileges.map(renderPrivilegeGroup)}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -53,6 +53,11 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -99,6 +104,13 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
}),
|
||||
subFeature: ['cool_all', 'cool_read', 'cool_toggle_1', 'cool_toggle_2'],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: expect.objectContaining({
|
||||
id: 'all',
|
||||
}),
|
||||
subFeature: ['cool_toggle_1'],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -155,6 +167,13 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
'cool_excluded_toggle',
|
||||
],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: expect.objectContaining({
|
||||
id: 'all',
|
||||
}),
|
||||
subFeature: ['cool_toggle_1'],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -214,6 +233,13 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
'cool_excluded_toggle',
|
||||
],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: expect.objectContaining({
|
||||
id: 'all',
|
||||
}),
|
||||
subFeature: ['cool_toggle_1'],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -255,6 +281,13 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
}),
|
||||
subFeature: ['cool_all', 'cool_read', 'cool_toggle_1', 'cool_toggle_2'],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: expect.objectContaining({
|
||||
id: 'all',
|
||||
}),
|
||||
subFeature: ['cool_toggle_1'],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -294,6 +327,11 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -333,6 +371,11 @@ describe('PrivilegeSummaryCalculator', () => {
|
|||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primary: undefined,
|
||||
subFeature: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -90,6 +90,15 @@ const expectNoPrivileges = (displayedPrivileges: any, expectSubFeatures: boolean
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'None',
|
||||
...maybeExpectSubFeaturePrivileges(expectSubFeatures, {
|
||||
'Require all spaces Sub Feature': [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -248,6 +257,15 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'All',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -310,6 +328,15 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'All',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -370,6 +397,15 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'All',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -432,6 +468,15 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'None',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -522,6 +567,22 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'All',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -614,6 +675,22 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -706,6 +783,22 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'None',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': [],
|
||||
}),
|
||||
},
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -800,6 +893,22 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'None',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': [],
|
||||
}),
|
||||
},
|
||||
'default, space-1': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'None',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': [],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -925,6 +1034,29 @@ describe('PrivilegeSummaryTable', () => {
|
|||
}),
|
||||
},
|
||||
},
|
||||
with_require_all_spaces_sub_features: {
|
||||
'*': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
default: {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'All',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
'space-1, space-2': {
|
||||
hasCustomizedSubFeaturePrivileges: false,
|
||||
primaryFeaturePrivilege: 'Read',
|
||||
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
|
||||
'Require all spaces Sub Feature': ['Cool toggle 1'],
|
||||
}),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -79,6 +79,10 @@ describe('PrivilegeSpaceForm', () => {
|
|||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_require_all_spaces_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
|
@ -129,6 +133,12 @@ describe('PrivilegeSpaceForm', () => {
|
|||
"primaryFeaturePrivilege": "all",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_require_all_spaces_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "all",
|
||||
"subFeaturePrivileges": Array [
|
||||
"cool_toggle_1",
|
||||
],
|
||||
},
|
||||
"with_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "all",
|
||||
"subFeaturePrivileges": Array [
|
||||
|
@ -185,6 +195,10 @@ describe('PrivilegeSpaceForm', () => {
|
|||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_require_all_spaces_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "read",
|
||||
"subFeaturePrivileges": Array [
|
||||
|
@ -286,6 +300,10 @@ describe('PrivilegeSpaceForm', () => {
|
|||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_require_all_spaces_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "none",
|
||||
"subFeaturePrivileges": Array [],
|
||||
},
|
||||
"with_sub_features": Object {
|
||||
"primaryFeaturePrivilege": "read",
|
||||
"subFeaturePrivileges": Array [
|
||||
|
@ -346,6 +364,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
with_excluded_sub_features: ['read'],
|
||||
no_sub_features: ['read'],
|
||||
with_sub_features: ['read'],
|
||||
with_require_all_spaces_sub_features: ['read'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
|
@ -451,6 +470,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
with_excluded_sub_features: ['read'],
|
||||
no_sub_features: ['read'],
|
||||
with_sub_features: ['read'],
|
||||
with_require_all_spaces_sub_features: ['read'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
|
@ -493,6 +513,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
no_sub_features: ['all'],
|
||||
no_sub_features_disabled_read: ['all'],
|
||||
with_sub_features: ['all'],
|
||||
with_require_all_spaces_sub_features: ['all'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
|
@ -569,6 +590,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
no_sub_features: ['read'],
|
||||
no_sub_features_require_all_space: ['read'],
|
||||
with_sub_features: ['read'],
|
||||
with_require_all_spaces_sub_features: ['read'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
|
@ -613,6 +635,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
with_excluded_sub_features: ['all'],
|
||||
no_sub_features: ['all'],
|
||||
with_sub_features: ['all'],
|
||||
with_require_all_spaces_sub_features: ['all'],
|
||||
},
|
||||
spaces: ['foo'],
|
||||
},
|
||||
|
@ -671,6 +694,7 @@ describe('PrivilegeSpaceForm', () => {
|
|||
no_sub_features: ['all'],
|
||||
no_sub_features_require_all_space: ['all'],
|
||||
with_sub_features: ['all'],
|
||||
with_require_all_spaces_sub_features: ['all'],
|
||||
},
|
||||
spaces: ['*'],
|
||||
},
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { remove } from 'lodash';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -472,9 +473,22 @@ export class PrivilegeSpaceForm extends Component<Props, State> {
|
|||
const primaryFeaturePrivilege = securedFeature
|
||||
?.getPrimaryFeaturePrivileges({ includeMinimalFeaturePrivileges: true })
|
||||
.find((pfp) => privileges.includes(pfp.id)) ?? { disabled: false, requireAllSpaces: false };
|
||||
|
||||
const areAllSpacesSelected = selectedSpaceIds.includes(ALL_SPACES_ID);
|
||||
if (securedFeature) {
|
||||
securedFeature.getSubFeatures().forEach((subFeature) => {
|
||||
subFeature.privileges.forEach((currentPrivilege) => {
|
||||
if (privileges.includes(currentPrivilege.id)) {
|
||||
if (subFeature.requireAllSpaces && !areAllSpacesSelected) {
|
||||
remove(privileges, (privilege) => privilege === currentPrivilege.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
const newFeaturePrivileges =
|
||||
primaryFeaturePrivilege?.disabled ||
|
||||
(primaryFeaturePrivilege?.requireAllSpaces && !selectedSpaceIds.includes(ALL_SPACES_ID))
|
||||
(primaryFeaturePrivilege?.requireAllSpaces && !areAllSpacesSelected)
|
||||
? [] // The primary feature privilege cannot be selected; remove that and any selected sub-feature privileges, too
|
||||
: privileges;
|
||||
return {
|
||||
|
@ -536,7 +550,12 @@ export class PrivilegeSpaceForm extends Component<Props, State> {
|
|||
newPrivileges = [nextFeaturePrivilege.id];
|
||||
feature.getSubFeaturePrivileges().forEach((psf) => {
|
||||
if (Array.isArray(privileges) && privileges.includes(psf.id)) {
|
||||
newPrivileges.push(psf.id);
|
||||
if (
|
||||
!psf.requireAllSpaces ||
|
||||
(psf.requireAllSpaces && this.state.selectedSpaceIds.includes(ALL_SPACES_ID))
|
||||
) {
|
||||
newPrivileges.push(psf.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { SubFeaturePrivilegeGroup } from './sub_feature_privilege_group';
|
|||
|
||||
export class SecuredSubFeature extends SubFeature {
|
||||
public readonly privileges: SubFeaturePrivilege[];
|
||||
public readonly privilegesTooltip: string;
|
||||
|
||||
constructor(
|
||||
config: SubFeatureConfig,
|
||||
|
@ -20,6 +21,8 @@ export class SecuredSubFeature extends SubFeature {
|
|||
) {
|
||||
super(config);
|
||||
|
||||
this.privilegesTooltip = config.privilegesTooltip || '';
|
||||
|
||||
this.privileges = [];
|
||||
for (const privilege of this.privilegeIterator()) {
|
||||
this.privileges.push(privilege);
|
||||
|
|
|
@ -20,4 +20,8 @@ export class SubFeaturePrivilege extends KibanaPrivilege {
|
|||
public get name() {
|
||||
return this.subPrivilegeConfig.name;
|
||||
}
|
||||
|
||||
public get requireAllSpaces() {
|
||||
return this.subPrivilegeConfig.requireAllSpaces ?? false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,6 +101,22 @@ export const validateKibanaPrivileges = (
|
|||
}
|
||||
}
|
||||
|
||||
kibanaFeature.subFeatures.forEach((subFeature) => {
|
||||
if (
|
||||
subFeature.requireAllSpaces &&
|
||||
!forAllSpaces &&
|
||||
subFeature.privilegeGroups.some((group) =>
|
||||
group.privileges.some((privilege) => feature.includes(privilege.id))
|
||||
)
|
||||
) {
|
||||
errors.push(
|
||||
`Sub-feature privilege [${kibanaFeature.name} - ${
|
||||
subFeature.name
|
||||
}] requires all spaces to be selected but received [${priv.spaces.join(',')}]`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return errors;
|
||||
});
|
||||
});
|
||||
|
|
|
@ -466,4 +466,86 @@ describe('validateKibanaPrivileges', () => {
|
|||
`Feature [foo] does not support privilege [read].`,
|
||||
]);
|
||||
});
|
||||
|
||||
const fooSubFeature = new KibanaFeature({
|
||||
id: 'foo',
|
||||
name: 'Foo',
|
||||
privileges: {
|
||||
all: {
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
},
|
||||
read: {
|
||||
disabled: true,
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
},
|
||||
},
|
||||
subFeatures: [
|
||||
{
|
||||
name: 'Require All Spaces Enabled',
|
||||
requireAllSpaces: true,
|
||||
privilegeGroups: [
|
||||
{
|
||||
groupType: 'mutually_exclusive',
|
||||
privileges: [
|
||||
{
|
||||
id: 'test',
|
||||
name: 'foo',
|
||||
includeIn: 'none',
|
||||
ui: ['test-ui'],
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
app: [],
|
||||
category: { id: 'foo', label: 'foo' },
|
||||
});
|
||||
|
||||
test('returns no error when subfeature requireAllSpaces enabled and all spaces selected', () => {
|
||||
expect(
|
||||
validateKibanaPrivileges(
|
||||
[fooSubFeature],
|
||||
[
|
||||
{
|
||||
spaces: ['*'],
|
||||
base: [],
|
||||
feature: {
|
||||
foo: ['all', 'test'],
|
||||
},
|
||||
},
|
||||
]
|
||||
).validationErrors
|
||||
).toEqual([]);
|
||||
});
|
||||
test('returns error when subfeature requireAllSpaces enabled but not all spaces selected', () => {
|
||||
expect(
|
||||
validateKibanaPrivileges(
|
||||
[fooSubFeature],
|
||||
[
|
||||
{
|
||||
spaces: ['foo-space'],
|
||||
base: [],
|
||||
feature: {
|
||||
foo: ['all', 'test'],
|
||||
},
|
||||
},
|
||||
]
|
||||
).validationErrors
|
||||
).toEqual([
|
||||
'Sub-feature privilege [Foo - Require All Spaces Enabled] requires all spaces to be selected but received [foo-space]',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -185,6 +185,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
subFeatures: experimentalFeatures.endpointRbacEnabled
|
||||
? [
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.endpointList.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Endpoint List access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.endpointList', {
|
||||
defaultMessage: 'Endpoint List',
|
||||
}),
|
||||
|
@ -195,7 +202,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeEndpointList`, `${APP_ID}-readEndpointList`],
|
||||
id: 'endpoint_list_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -206,7 +213,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readEndpointList`],
|
||||
id: 'endpoint_list_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -219,6 +226,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.trustedApplications.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Trusted Applications access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.trustedApplications',
|
||||
{
|
||||
|
@ -232,7 +246,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeTrustedApplications`, `${APP_ID}-readTrustedApplications`],
|
||||
id: 'trusted_applications_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -243,7 +257,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readTrustedApplications`],
|
||||
id: 'trusted_applications_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -256,6 +270,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Host Isolation Exceptions access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.hostIsolationExceptions',
|
||||
{
|
||||
|
@ -272,7 +293,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
`${APP_ID}-readHostIsolationExceptions`,
|
||||
],
|
||||
id: 'host_isolation_exceptions_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -283,7 +304,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readHostIsolationExceptions`],
|
||||
id: 'host_isolation_exceptions_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -296,6 +317,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.blockList.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Blocklist access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.blockList', {
|
||||
defaultMessage: 'Blocklist',
|
||||
}),
|
||||
|
@ -306,7 +334,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeBlocklist`, `${APP_ID}-readBlocklist`],
|
||||
id: 'blocklist_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -317,7 +345,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readBlocklist`],
|
||||
id: 'blocklist_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -330,6 +358,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.eventFilters.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Event Filters access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.eventFilters', {
|
||||
defaultMessage: 'Event Filters',
|
||||
}),
|
||||
|
@ -340,7 +375,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeEventFilters`, `${APP_ID}-readEventFilters`],
|
||||
id: 'event_filters_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -351,7 +386,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readEventFilters`],
|
||||
id: 'event_filters_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -364,6 +399,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.policyManagement.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Policy Management access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.policyManagement',
|
||||
{
|
||||
|
@ -377,7 +419,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writePolicyManagement`, `${APP_ID}-readPolicyManagement`],
|
||||
id: 'policy_management_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -388,7 +430,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readPolicyManagement`],
|
||||
id: 'policy_management_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -401,6 +443,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.actionsLogManagement.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Actions Log Management access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.actionsLogManagement',
|
||||
{
|
||||
|
@ -417,7 +466,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
`${APP_ID}-readActionsLogManagement`,
|
||||
],
|
||||
id: 'actions_log_management_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -428,7 +477,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-readActionsLogManagement`],
|
||||
id: 'actions_log_management_read',
|
||||
includeIn: 'read',
|
||||
includeIn: 'none',
|
||||
name: 'Read',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -441,6 +490,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.hostIsolation.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Host Isolation access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate('xpack.securitySolution.featureRegistry.subFeatures.hostIsolation', {
|
||||
defaultMessage: 'Host Isolation',
|
||||
}),
|
||||
|
@ -451,7 +507,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeHostIsolation`],
|
||||
id: 'host_isolation_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -464,6 +520,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.processOperations.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for Process Operations access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.processOperations',
|
||||
{
|
||||
|
@ -477,7 +540,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeProcessOperations`],
|
||||
id: 'process_operations_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
@ -490,6 +553,13 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
],
|
||||
},
|
||||
{
|
||||
requireAllSpaces: true,
|
||||
privilegesTooltip: i18n.translate(
|
||||
'xpack.securitySolution.featureRegistry.subFeatures.fileOperations.privilegesTooltip',
|
||||
{
|
||||
defaultMessage: 'All Spaces is required for File Operations access.',
|
||||
}
|
||||
),
|
||||
name: i18n.translate('xpack.securitySolution.featureRegistr.subFeatures.fileOperations', {
|
||||
defaultMessage: 'File Operations',
|
||||
}),
|
||||
|
@ -500,7 +570,7 @@ export const getKibanaPrivilegesFeaturePrivileges = (
|
|||
{
|
||||
api: [`${APP_ID}-writeFileOperations`],
|
||||
id: 'file_operations_all',
|
||||
includeIn: 'all',
|
||||
includeIn: 'none',
|
||||
name: 'All',
|
||||
savedObject: {
|
||||
all: [],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue