Skip to content

Commit

Permalink
[8.x] Assign Roles to Space from Spaces Management (elastic#191795) (e…
Browse files Browse the repository at this point in the history
…lastic#193787)

# Backport

This will backport the following commits from `main` to `8.x`:
- [Assign Roles to Space from Spaces Management
(elastic#191795)](elastic#191795)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Tim
Sullivan","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-09-23T19:13:56Z","message":"Assign
Roles to Space from Spaces Management (elastic#191795)\n\n##
Summary\r\n\r\nEpic link:
https://github.com/elastic/kibana-team/issues/785\r\n\r\nThis changes
bring a new design to the management of Spaces in Stack\r\nManagement /
Security. We have a new page to view the details of the\r\nSpace, and
new UX to assign Roles to a Space.\r\n\r\n### Release Note\r\nAdded
several UX improvements to the management of Spaces in
**Stack\r\nManagement > Spaces**, including the ability to assign Roles
to an\r\nexisting Space.\r\n\r\n### Checklist\r\n\r\nDelete any items
that are not applicable to this PR.\r\n\r\n- [x] Use flaky test runner
on changed functional
tests:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6953\r\n-
[x] Create test for the ability to change space avatar from
`initials`\r\nto `image` and vice versa\r\n- [x] Any text added follows
[EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[x] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[x] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[x] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by: Eyo
Okon Eyo <[email protected]>\r\nCo-authored-by: Elastic Machine
<[email protected]>\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"fb9700caa097dbdac310f8fd3a387b8d218a7428","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team:Security","v9.0.0","ci:cloud-deploy","v8.16.0","backport:version"],"title":"Assign
Roles to Space from Spaces
Management","number":191795,"url":"https://github.com/elastic/kibana/pull/191795","mergeCommit":{"message":"Assign
Roles to Space from Spaces Management (elastic#191795)\n\n##
Summary\r\n\r\nEpic link:
https://github.com/elastic/kibana-team/issues/785\r\n\r\nThis changes
bring a new design to the management of Spaces in Stack\r\nManagement /
Security. We have a new page to view the details of the\r\nSpace, and
new UX to assign Roles to a Space.\r\n\r\n### Release Note\r\nAdded
several UX improvements to the management of Spaces in
**Stack\r\nManagement > Spaces**, including the ability to assign Roles
to an\r\nexisting Space.\r\n\r\n### Checklist\r\n\r\nDelete any items
that are not applicable to this PR.\r\n\r\n- [x] Use flaky test runner
on changed functional
tests:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6953\r\n-
[x] Create test for the ability to change space avatar from
`initials`\r\nto `image` and vice versa\r\n- [x] Any text added follows
[EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[x] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[x] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[x] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by: Eyo
Okon Eyo <[email protected]>\r\nCo-authored-by: Elastic Machine
<[email protected]>\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"fb9700caa097dbdac310f8fd3a387b8d218a7428"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/191795","number":191795,"mergeCommit":{"message":"Assign
Roles to Space from Spaces Management (elastic#191795)\n\n##
Summary\r\n\r\nEpic link:
https://github.com/elastic/kibana-team/issues/785\r\n\r\nThis changes
bring a new design to the management of Spaces in Stack\r\nManagement /
Security. We have a new page to view the details of the\r\nSpace, and
new UX to assign Roles to a Space.\r\n\r\n### Release Note\r\nAdded
several UX improvements to the management of Spaces in
**Stack\r\nManagement > Spaces**, including the ability to assign Roles
to an\r\nexisting Space.\r\n\r\n### Checklist\r\n\r\nDelete any items
that are not applicable to this PR.\r\n\r\n- [x] Use flaky test runner
on changed functional
tests:\r\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6953\r\n-
[x] Create test for the ability to change space avatar from
`initials`\r\nto `image` and vice versa\r\n- [x] Any text added follows
[EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[x] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[x] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[x] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>\r\nCo-authored-by: Eyo
Okon Eyo <[email protected]>\r\nCo-authored-by: Elastic Machine
<[email protected]>\r\nCo-authored-by: Aleh
Zasypkin
<[email protected]>","sha":"fb9700caa097dbdac310f8fd3a387b8d218a7428"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Tim Sullivan <[email protected]>
  • Loading branch information
kibanamachine and tsullivan authored Sep 23, 2024
1 parent f83b726 commit b9c29e9
Show file tree
Hide file tree
Showing 76 changed files with 5,207 additions and 476 deletions.
7 changes: 6 additions & 1 deletion x-pack/packages/security/plugin_types_public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export type {
UserProfileSuggestParams,
UserProfileAPIClient,
} from './src/user_profile';
export type { RolePutPayload, RolesAPIClient } from './src/roles';
export type {
BulkUpdatePayload,
BulkUpdateRoleResponse,
RolePutPayload,
RolesAPIClient,
} from './src/roles';
export { PrivilegesAPIClientPublicContract } from './src/privileges';
export type { PrivilegesAPIClientGetAllArgs } from './src/privileges';
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface PrivilegesAPIClientGetAllArgs {
*/
respectLicenseLevel: boolean;
}
// TODO: Eyo include the proper return types for contract

export abstract class PrivilegesAPIClientPublicContract {
abstract getAll(args: PrivilegesAPIClientGetAllArgs): Promise<RawKibanaPrivileges>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@
* 2.0.
*/

export type { RolePutPayload, RolesAPIClient } from './roles_api_client';
export type {
BulkUpdatePayload,
BulkUpdateRoleResponse,
RolePutPayload,
RolesAPIClient,
} from './roles_api_client';
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@ export interface RolePutPayload {
createOnly?: boolean;
}

export interface BulkUpdatePayload {
rolesUpdate: Role[];
}

export interface BulkUpdateRoleResponse {
created?: string[];
updated?: string[];
errors?: Record<string, { type: string; reason: string }>;
}

export interface RolesAPIClient {
getRoles: () => Promise<Role[]>;
getRole: (roleName: string) => Promise<Role>;
deleteRole: (roleName: string) => Promise<void>;
saveRole: (payload: RolePutPayload) => Promise<void>;
bulkUpdateRoles: (payload: BulkUpdatePayload) => Promise<BulkUpdateRoleResponse>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
kibanaFeatures,
} from '@kbn/security-role-management-model/src/__fixtures__';
import { findTestSubject, mountWithIntl } from '@kbn/test-jest-helpers';
import type { Role } from '@kbn/security-plugin-types-common';

import { getDisplayedFeaturePrivileges } from './__fixtures__';
import { FeatureTable } from './feature_table';
import type { Role } from '@kbn/security-plugin-types-common';
import { PrivilegeFormCalculator } from '../privilege_form_calculator';

const createRole = (kibana: Role['kibana'] = []): Role => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ interface Props {
canCustomizeSubFeaturePrivileges: boolean;
allSpacesSelected: boolean;
disabled?: boolean;
/**
* default is true, to remain backwards compatible
*/
showTitle?: boolean;
}

interface State {
Expand All @@ -58,6 +62,7 @@ export class FeatureTable extends Component<Props, State> {
public static defaultProps = {
privilegeIndex: -1,
showLocks: true,
showTitle: true,
};

private featureCategories: Map<string, SecuredFeature[]> = new Map();
Expand Down Expand Up @@ -187,16 +192,18 @@ export class FeatureTable extends Component<Props, State> {
<div>
<EuiFlexGroup alignItems={'flexEnd'}>
<EuiFlexItem>
<EuiText size="xs">
<b>
{i18n.translate(
'xpack.security.management.editRole.featureTable.featureVisibilityTitle',
{
defaultMessage: 'Customize feature privileges',
}
)}
</b>
</EuiText>
{this.props.showTitle && (
<EuiText size="xs">
<b>
{i18n.translate(
'xpack.security.management.editRole.featureTable.featureVisibilityTitle',
{
defaultMessage: 'Customize feature privileges',
}
)}
</b>
</EuiText>
)}
</EuiFlexItem>
{!this.props.disabled && (
<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
createKibanaPrivileges,
kibanaFeatures,
} from '@kbn/security-role-management-model/src/__fixtures__';
import type { Role } from '@kbn/security-plugin-types-common';
import { findTestSubject, mountWithIntl } from '@kbn/test-jest-helpers';

import { FeatureTableExpandedRow } from './feature_table_expanded_row';
import type { Role } from '@kbn/security-plugin-types-common';
import { PrivilegeFormCalculator } from '../privilege_form_calculator';

const createRole = (kibana: Role['kibana'] = []): Role => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
createKibanaPrivileges,
kibanaFeatures,
} from '@kbn/security-role-management-model/src/__fixtures__';
import type { Role } from '@kbn/security-plugin-types-common';

import { PrivilegeFormCalculator } from './privilege_form_calculator';
import type { Role } from '@kbn/security-plugin-types-common';

const createRole = (kibana: Role['kibana'] = []): Role => {
return {
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/security/public/authentication/index.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const authorizationMock = {
getRole: jest.fn(),
deleteRole: jest.fn(),
saveRole: jest.fn(),
bulkUpdateRoles: jest.fn(),
},
privileges: {
getAll: jest.fn(),
Expand All @@ -43,6 +44,7 @@ export const authorizationMock = {
getRole: jest.fn(),
deleteRole: jest.fn(),
saveRole: jest.fn(),
bulkUpdateRoles: jest.fn(),
},
privileges: {
getAll: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class AuthorizationService {
getRole: rolesAPIClient.getRole,
deleteRole: rolesAPIClient.deleteRole,
saveRole: rolesAPIClient.saveRole,
bulkUpdateRoles: rolesAPIClient.bulkUpdateRoles,
},
privileges: {
getAll: privilegesAPIClient.getAll.bind(privilegesAPIClient),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EuiFlexItem,
EuiForm,
EuiFormRow,
EuiIconTip,
EuiPanel,
EuiSpacer,
EuiText,
Expand Down Expand Up @@ -556,52 +557,46 @@ export const EditRolePage: FunctionComponent<Props> = ({

const getElasticsearchPrivileges = () => {
return (
<div>
<EuiSpacer />
<ElasticsearchPrivileges
role={role}
editable={!isRoleReadOnly}
indicesAPIClient={indicesAPIClient}
onChange={onRoleChange}
runAsUsers={runAsUsers}
validator={validator}
indexPatterns={indexPatternsTitles}
remoteClusters={remoteClustersState.value}
builtinESPrivileges={builtInESPrivileges}
license={license}
docLinks={docLinks}
canUseRemoteIndices={
buildFlavor === 'traditional' && featureCheckState.value?.canUseRemoteIndices
}
canUseRemoteClusters={
buildFlavor === 'traditional' && featureCheckState.value?.canUseRemoteClusters
}
isDarkMode={isDarkMode}
buildFlavor={buildFlavor}
/>
</div>
<ElasticsearchPrivileges
role={role}
editable={!isRoleReadOnly}
indicesAPIClient={indicesAPIClient}
onChange={onRoleChange}
runAsUsers={runAsUsers}
validator={validator}
indexPatterns={indexPatternsTitles}
remoteClusters={remoteClustersState.value}
builtinESPrivileges={builtInESPrivileges}
license={license}
docLinks={docLinks}
canUseRemoteIndices={
buildFlavor === 'traditional' && featureCheckState.value?.canUseRemoteIndices
}
canUseRemoteClusters={
buildFlavor === 'traditional' && featureCheckState.value?.canUseRemoteClusters
}
isDarkMode={isDarkMode}
buildFlavor={buildFlavor}
/>
);
};

const onRoleChange = (newRole: Role) => setRole(newRole);

const getKibanaPrivileges = () => {
return (
<div>
<EuiSpacer />
<KibanaPrivilegesRegion
kibanaPrivileges={new KibanaPrivileges(kibanaPrivileges, features)}
spaces={spaces.list}
spacesEnabled={spaces.enabled}
uiCapabilities={uiCapabilities}
canCustomizeSubFeaturePrivileges={license.getFeatures().allowSubFeaturePrivileges}
editable={!isRoleReadOnly}
role={role}
onChange={onRoleChange}
validator={validator}
spacesApiUi={spacesApiUi}
/>
</div>
<KibanaPrivilegesRegion
kibanaPrivileges={new KibanaPrivileges(kibanaPrivileges, features)}
spaces={spaces.list}
spacesEnabled={spaces.enabled}
uiCapabilities={uiCapabilities}
canCustomizeSubFeaturePrivileges={license.getFeatures().allowSubFeaturePrivileges}
editable={!isRoleReadOnly}
role={role}
onChange={onRoleChange}
validator={validator}
spacesApiUi={spacesApiUi}
/>
);
};

Expand Down Expand Up @@ -800,44 +795,89 @@ export const EditRolePage: FunctionComponent<Props> = ({

return (
<div className="editRolePage">
<EuiForm {...formError}>
{getFormTitle()}
<EuiSpacer />
<EuiText size="s">
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Project spaces."
/>
</EuiText>
{isRoleReserved && (
<Fragment>
<EuiSpacer size="s" />
<EuiText size="s" color="subdued">
<p id="reservedRoleDescription" tabIndex={0}>
<EuiForm {...formError} fullWidth>
<EuiFlexGroup direction="column">
<EuiFlexItem>
{getFormTitle()}
<EuiSpacer />
<EuiText size="s">
<FormattedMessage
id="xpack.security.management.editRole.setPrivilegesToKibanaSpacesDescription"
defaultMessage="Set privileges on your Elasticsearch data and control access to your Project spaces."
/>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
{isRoleReserved && (
<Fragment>
<EuiText size="s" color="subdued">
<p id="reservedRoleDescription" tabIndex={0}>
<FormattedMessage
id="xpack.security.management.editRole.modifyingReversedRolesDescription"
defaultMessage="Reserved roles are built-in and cannot be removed or modified."
/>
</p>
</EuiText>
</Fragment>
)}
</EuiFlexItem>
<EuiFlexItem>
{isDeprecatedRole && (
<Fragment>
<EuiSpacer size="s" />
<EuiCallOut
title={getExtendedRoleDeprecationNotice(role)}
color="warning"
iconType="warning"
/>
</Fragment>
)}
</EuiFlexItem>
<EuiFlexItem>{getRoleNameAndDescription()}</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow
label={
<FormattedMessage
id="xpack.security.management.editRole.modifyingReversedRolesDescription"
defaultMessage="Reserved roles are built-in and cannot be removed or modified."
id="xpack.security.management.editRole.dataLayerLabel"
defaultMessage="Data Layer"
/>
</p>
</EuiText>
</Fragment>
)}
{isDeprecatedRole && (
<Fragment>
<EuiSpacer size="s" />
<EuiCallOut
title={getExtendedRoleDeprecationNotice(role)}
color="warning"
iconType="warning"
/>
</Fragment>
)}
<EuiSpacer />
{getRoleNameAndDescription()}
{getElasticsearchPrivileges()}
{getKibanaPrivileges()}
<EuiSpacer />
{getFormButtons()}
}
>
{getElasticsearchPrivileges()}
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow
label={
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
<EuiFlexItem grow={false}>
<FormattedMessage
id="xpack.security.management.editRole.appLayerLabel"
defaultMessage="Application layer"
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiIconTip
type="iInCircle"
color="subdued"
content={
<FormattedMessage
id="xpack.security.management.editRole.appLayerTooltipText"
defaultMessage="Feature access is granted on a per space basis for all features. Feature visibility is set on the space. Both must be enabled for this role to use a feature"
/>
}
/>
</EuiFlexItem>
</EuiFlexGroup>
}
>
{getKibanaPrivileges()}
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem>
<EuiFormRow fullWidth={false}>{getFormButtons()}</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiForm>
</div>
);
Expand Down
Loading

0 comments on commit b9c29e9

Please sign in to comment.