Skip to content

Commit

Permalink
Prevent Spaces from being disabled (#115283)
Browse files Browse the repository at this point in the history
  • Loading branch information
jportner authored Oct 18, 2021
1 parent 3ab9e07 commit 0f1c7cc
Show file tree
Hide file tree
Showing 87 changed files with 362 additions and 7,682 deletions.
5 changes: 0 additions & 5 deletions docs/settings/spaces-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@

By default, spaces is enabled in {kib}. To secure spaces, <<security-settings-kb,enable security>>.

`xpack.spaces.enabled`::
deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported and it will not be possible to disable this plugin."]
To enable spaces, set to `true`.
The default is `true`.

`xpack.spaces.maxSpaces`::
The maximum number of spaces that you can use with the {kib} instance. Some {kib} operations
return all spaces using a single `_search` from {es}, so you must
Expand Down
9 changes: 2 additions & 7 deletions docs/spaces/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ image::images/spaces-configure-landing-page.png["Configure space-level landing p

[float]
[[spaces-delete-started]]
=== Disable and version updates

Spaces are automatically enabled in {kib}. If you don't want use this feature,
you can disable it. For more information, refer to <<spaces-settings-kb,Spaces settings in {kib}>>.

When you upgrade {kib}, the default space contains all of your existing saved objects.

=== Disabling spaces

Starting in {kib} 8.0, the Spaces feature cannot be disabled.
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ kibana_vars=(
xpack.securitySolution.packagerTaskInterval
xpack.securitySolution.prebuiltRulesFromFileSystem
xpack.securitySolution.prebuiltRulesFromSavedObjects
xpack.spaces.enabled
xpack.spaces.maxSpaces
xpack.task_manager.index
xpack.task_manager.max_attempts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { userAPIClientMock } from '../../users/index.mock';
import { createRawKibanaPrivileges } from '../__fixtures__/kibana_privileges';
import { indicesAPIClientMock, privilegesAPIClientMock, rolesAPIClientMock } from '../index.mock';
import { EditRolePage } from './edit_role_page';
import { SimplePrivilegeSection } from './privileges/kibana/simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './privileges/kibana/space_aware_privilege_section';
import { TransformErrorSection } from './privileges/kibana/transform_error_section';

Expand Down Expand Up @@ -132,12 +131,10 @@ function getProps({
action,
role,
canManageSpaces = true,
spacesEnabled = true,
}: {
action: 'edit' | 'clone';
role?: Role;
canManageSpaces?: boolean;
spacesEnabled?: boolean;
}) {
const rolesAPIClient = rolesAPIClientMock.create();
rolesAPIClient.getRole.mockResolvedValue(role);
Expand Down Expand Up @@ -165,12 +162,7 @@ function getProps({
const { http, docLinks, notifications } = coreMock.createStart();
http.get.mockImplementation(async (path: any) => {
if (path === '/api/spaces/space') {
if (spacesEnabled) {
return buildSpaces();
}

const notFoundError = { response: { status: 404 } };
throw notFoundError;
return buildSpaces();
}
});

Expand Down Expand Up @@ -335,152 +327,6 @@ describe('<EditRolePage />', () => {
});
});

describe('with spaces disabled', () => {
it('can render a reserved role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
name: 'superuser',
metadata: { _reserved: true },
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(1);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find('[data-test-subj="userCannotManageSpacesCallout"]')).toHaveLength(0);
expectReadOnlyFormButtons(wrapper);
});

it('can render a user defined role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(0);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find('[data-test-subj="userCannotManageSpacesCallout"]')).toHaveLength(0);
expectSaveFormButtons(wrapper);
});

it('can render when creating a new role', async () => {
const wrapper = mountWithIntl(
<EditRolePage {...getProps({ action: 'edit', spacesEnabled: false })} />
);

await waitForRender(wrapper);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('can render when cloning an existing role', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
role: {
metadata: { _reserved: false },
name: '',
elasticsearch: {
cluster: ['all', 'manage'],
indices: [
{
names: ['foo*'],
privileges: ['all'],
field_security: { except: ['f'], grant: ['b*'] },
},
],
run_as: ['elastic'],
},
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('does not care if user cannot manage spaces', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
canManageSpaces: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [{ spaces: ['*'], base: ['all'], feature: {} }],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find('[data-test-subj="reservedRoleBadgeTooltip"]')).toHaveLength(0);

expect(
wrapper.find('EuiCallOut[data-test-subj="userCannotManageSpacesCallout"]')
).toHaveLength(0);

expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expectSaveFormButtons(wrapper);
});

it('renders a partial read-only view when there is a transform error', async () => {
const wrapper = mountWithIntl(
<EditRolePage
{...getProps({
action: 'edit',
spacesEnabled: false,
canManageSpaces: false,
role: {
name: 'my custom role',
metadata: {},
elasticsearch: { cluster: ['all'], indices: [], run_as: ['*'] },
kibana: [],
_transform_error: ['kibana'],
},
})}
/>
);

await waitForRender(wrapper);

expect(wrapper.find(TransformErrorSection)).toHaveLength(1);
expectReadOnlyFormButtons(wrapper);
});
});

it('registers fatal error if features endpoint fails unexpectedly', async () => {
const error = { response: { status: 500 } };
const getFeatures = jest.fn().mockRejectedValue(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ export const EditRolePage: FunctionComponent<Props> = ({
<KibanaPrivilegesRegion
kibanaPrivileges={new KibanaPrivileges(kibanaPrivileges, features)}
spaces={spaces.list}
spacesEnabled={spaces.enabled}
uiCapabilities={uiCapabilities}
canCustomizeSubFeaturePrivileges={license.getFeatures().allowSubFeaturePrivileges}
editable={!isRoleReadOnly}
Expand Down Expand Up @@ -521,7 +520,7 @@ export const EditRolePage: FunctionComponent<Props> = ({
setFormError(null);

try {
await rolesAPIClient.saveRole({ role, spacesEnabled: spaces.enabled });
await rolesAPIClient.saveRole({ role });
} catch (error) {
notifications.toasts.addDanger(
error?.body?.message ??
Expand Down Expand Up @@ -566,24 +565,17 @@ export const EditRolePage: FunctionComponent<Props> = ({
backToRoleList();
};

const description = spaces.enabled ? (
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Kibana spaces."
/>
) : (
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to Kibana."
/>
);

return (
<div className="editRolePage">
<EuiForm {...formError}>
{getFormTitle()}
<EuiSpacer />
<EuiText size="s">{description}</EuiText>
<EuiText size="s">
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Kibana spaces."
/>
</EuiText>
{isRoleReserved && (
<Fragment>
<EuiSpacer size="s" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import type { Role } from '../../../../../../common/model';
import { KibanaPrivileges } from '../../../model';
import { RoleValidator } from '../../validate_role';
import { KibanaPrivilegesRegion } from './kibana_privileges_region';
import { SimplePrivilegeSection } from './simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './space_aware_privilege_section';
import { TransformErrorSection } from './transform_error_section';

const buildProps = (customProps = {}) => {
const buildProps = () => {
return {
role: {
name: '',
Expand All @@ -27,7 +26,6 @@ const buildProps = (customProps = {}) => {
},
kibana: [],
},
spacesEnabled: true,
spaces: [
{
id: 'default',
Expand Down Expand Up @@ -64,7 +62,6 @@ const buildProps = (customProps = {}) => {
onChange: jest.fn(),
validator: new RoleValidator(),
canCustomizeSubFeaturePrivileges: true,
...customProps,
};
};

Expand All @@ -73,26 +70,17 @@ describe('<KibanaPrivileges>', () => {
expect(shallow(<KibanaPrivilegesRegion {...buildProps()} />)).toMatchSnapshot();
});

it('renders the simple privilege form when spaces is disabled', () => {
const props = buildProps({ spacesEnabled: false });
it('renders the space-aware privilege form', () => {
const props = buildProps();
const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(1);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(0);
});

it('renders the space-aware privilege form when spaces is enabled', () => {
const props = buildProps({ spacesEnabled: true });
const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(1);
});

it('renders the transform error section when the role has a transform error', () => {
const props = buildProps({ spacesEnabled: true });
const props = buildProps();
(props.role as Role)._transform_error = ['kibana'];

const wrapper = shallow(<KibanaPrivilegesRegion {...props} />);
expect(wrapper.find(SimplePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(SpaceAwarePrivilegeSection)).toHaveLength(0);
expect(wrapper.find(TransformErrorSection)).toHaveLength(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ import type { Role } from '../../../../../../common/model';
import type { KibanaPrivileges } from '../../../model';
import { CollapsiblePanel } from '../../collapsible_panel';
import type { RoleValidator } from '../../validate_role';
import { SimplePrivilegeSection } from './simple_privilege_section';
import { SpaceAwarePrivilegeSection } from './space_aware_privilege_section';
import { TransformErrorSection } from './transform_error_section';

interface Props {
role: Role;
spacesEnabled: boolean;
canCustomizeSubFeaturePrivileges: boolean;
spaces?: Space[];
uiCapabilities: Capabilities;
Expand All @@ -44,7 +42,6 @@ export class KibanaPrivilegesRegion extends Component<Props, {}> {
const {
kibanaPrivileges,
role,
spacesEnabled,
canCustomizeSubFeaturePrivileges,
spaces = [],
uiCapabilities,
Expand All @@ -58,30 +55,18 @@ export class KibanaPrivilegesRegion extends Component<Props, {}> {
return <TransformErrorSection />;
}

if (spacesEnabled) {
return (
<SpaceAwarePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
spaces={spaces}
uiCapabilities={uiCapabilities}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
validator={validator}
spacesApiUi={spacesApiUi!}
/>
);
} else {
return (
<SimplePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
/>
);
}
return (
<SpaceAwarePrivilegeSection
kibanaPrivileges={kibanaPrivileges}
role={role}
spaces={spaces}
uiCapabilities={uiCapabilities}
onChange={onChange}
editable={editable}
canCustomizeSubFeaturePrivileges={canCustomizeSubFeaturePrivileges}
validator={validator}
spacesApiUi={spacesApiUi!}
/>
);
};
}
Loading

0 comments on commit 0f1c7cc

Please sign in to comment.