From b6d9ec2c8e056e088b0457e09b7900f2f6e564e1 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Fri, 20 Jul 2018 12:15:36 -0400 Subject: [PATCH] [Spaces] - Update Roles screen to use public API (#21031) This PR updates the new Role Management screen to use the public role API introduced as part of https://github.com/elastic/kibana/pull/20732. Additionally, this updates the breadcrumb nav for Spaces and Role management screens to be consistent with the nav introduced in https://github.com/elastic/kibana/pull/20739. There are a couple of visual glitches in this PR which are a result of current defects on master, so they can be safely ignored for the time being. --- x-pack/plugins/security/public/lib/api.js | 2 +- .../security/public/objects/lib/roles.js | 6 +- .../__snapshots__/page_header.test.js.snap | 15 ---- .../edit_role/components/edit_role_page.js | 8 +- .../edit_role/components/page_header.js | 35 --------- .../edit_role/components/page_header.test.js | 32 -------- .../elasticsearch_privileges.test.js.snap | 16 ++-- .../privileges/cluster_privileges.js | 4 +- .../privileges/cluster_privileges.test.js | 4 +- .../privileges/elasticsearch_privileges.js | 19 +++-- .../elasticsearch_privileges.test.js | 26 ++++--- .../components/privileges/index_privileges.js | 25 ++++-- .../privileges/index_privileges.test.js | 32 ++++---- .../privileges/kibana_privileges.js | 14 ++-- .../views/management/edit_role/edit_role.html | 4 +- .../views/management/edit_role/index.js | 66 +++++++--------- .../__snapshots__/validate_role.test.js.snap | 2 +- .../lib/get_application_privileges.js | 38 +++++++--- .../management/edit_role/lib/validate_role.js | 6 +- .../edit_role/lib/validate_role.test.js | 26 ++++--- .../__snapshots__/page_header.test.js.snap | 15 ---- .../views/management/components/index.js | 1 - .../management/components/page_header.js | 35 --------- .../management/components/page_header.test.js | 33 -------- .../edit_space/manage_space_page.js | 4 +- .../public/views/management/page_routes.js | 76 +++++++++---------- .../spaces_grid/spaces_grid_page.js | 4 +- .../public/views/management/template.html | 4 +- 28 files changed, 213 insertions(+), 339 deletions(-) delete mode 100644 x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/page_header.test.js.snap delete mode 100644 x-pack/plugins/security/public/views/management/edit_role/components/page_header.js delete mode 100644 x-pack/plugins/security/public/views/management/edit_role/components/page_header.test.js delete mode 100644 x-pack/plugins/spaces/public/views/management/components/__snapshots__/page_header.test.js.snap delete mode 100644 x-pack/plugins/spaces/public/views/management/components/page_header.js delete mode 100644 x-pack/plugins/spaces/public/views/management/components/page_header.test.js diff --git a/x-pack/plugins/security/public/lib/api.js b/x-pack/plugins/security/public/lib/api.js index 908a0ceaf3103..a41afcc0d4a3f 100644 --- a/x-pack/plugins/security/public/lib/api.js +++ b/x-pack/plugins/security/public/lib/api.js @@ -6,7 +6,7 @@ import chrome from 'ui/chrome'; const usersUrl = chrome.addBasePath('/api/security/v1/users'); -const rolesUrl = chrome.addBasePath('/api/security/v1/roles'); +const rolesUrl = chrome.addBasePath('/api/security/role'); export const createApiClient = (httpClient) => { return { diff --git a/x-pack/plugins/security/public/objects/lib/roles.js b/x-pack/plugins/security/public/objects/lib/roles.js index 5fdd95a7ccb64..7f0bbdbb30dc5 100644 --- a/x-pack/plugins/security/public/objects/lib/roles.js +++ b/x-pack/plugins/security/public/objects/lib/roles.js @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ import chrome from 'ui/chrome'; +import { omit } from 'lodash'; -const apiBase = chrome.addBasePath(`/api/security/v1/roles`); +const apiBase = chrome.addBasePath(`/api/security/role`); export async function saveRole($http, role) { - return await $http.post(`${apiBase}/${role.name}`, role); + const data = omit(role, 'name', 'transient_metadata', '_unrecognized_applications'); + return await $http.put(`${apiBase}/${role.name}`, data); } export async function deleteRole($http, name) { diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/page_header.test.js.snap b/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/page_header.test.js.snap deleted file mode 100644 index 628a5c068f83a..0000000000000 --- a/x-pack/plugins/security/public/views/management/edit_role/components/__snapshots__/page_header.test.js.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it renders without crashing 1`] = ` -
- - -
-`; diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.js b/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.js index 13cd7a4f1823b..6beb467f06f5c 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/edit_role_page.js @@ -20,7 +20,6 @@ import { EuiFlexItem, EuiButton, } from '@elastic/eui'; -import { PageHeader } from './page_header'; import { saveRole, deleteRole } from '../../../../objects'; import { isReservedRole } from '../../../../lib/role'; import { RoleValidator } from '../lib/validate_role'; @@ -36,7 +35,6 @@ export class EditRolePage extends Component { indexPatterns: PropTypes.array.isRequired, httpClient: PropTypes.func.isRequired, rbacEnabled: PropTypes.bool.isRequired, - rbacApplication: PropTypes.string, allowDocumentLevelSecurity: PropTypes.bool.isRequired, allowFieldLevelSecurity: PropTypes.bool.isRequired, kibanaAppPrivileges: PropTypes.array.isRequired, @@ -55,7 +53,6 @@ export class EditRolePage extends Component { render() { return ( - {this.getFormTitle()} @@ -172,7 +169,6 @@ export class EditRolePage extends Component { @@ -237,8 +233,8 @@ export class EditRolePage extends Component { ...this.state.role }; - role.indices = role.indices.filter(i => !this.isPlaceholderPrivilege(i)); - role.indices.forEach((index) => index.query || delete index.query); + role.elasticsearch.indices = role.elasticsearch.indices.filter(i => !this.isPlaceholderPrivilege(i)); + role.elasticsearch.indices.forEach((index) => index.query || delete index.query); saveRole(httpClient, role) .then(() => { diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/page_header.js b/x-pack/plugins/security/public/views/management/edit_role/components/page_header.js deleted file mode 100644 index 87aac82490817..0000000000000 --- a/x-pack/plugins/security/public/views/management/edit_role/components/page_header.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -import { - EuiBreadcrumbs, - EuiSpacer, -} from '@elastic/eui'; - -export class PageHeader extends Component { - render() { - return ( -
- - -
- ); - } - - buildBreadcrumb = (breadcrumb) => { - return { - text: breadcrumb.display, - href: breadcrumb.href, - }; - } -} - -PageHeader.propTypes = { - breadcrumbs: PropTypes.array.isRequired -}; diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/page_header.test.js b/x-pack/plugins/security/public/views/management/edit_role/components/page_header.test.js deleted file mode 100644 index 99f6994ea9898..0000000000000 --- a/x-pack/plugins/security/public/views/management/edit_role/components/page_header.test.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 React from 'react'; -import { shallow, mount } from 'enzyme'; -import { PageHeader } from './page_header'; -import { EuiBreadcrumbs } from '@elastic/eui'; - -test('it renders without crashing', () => { - const wrapper = shallow(); - expect(wrapper.find(EuiBreadcrumbs)).toHaveLength(1); - expect(wrapper).toMatchSnapshot(); -}); - -test('it renders breadcrumbs', () => { - const breadcrumbs = [{ - display: 'item-1', - href: '#item-1', - }, { - display: 'item-2', - href: '#item-2', - }, { - display: 'item-3', - href: '#item-3', - }]; - - const wrapper = mount(); - expect(wrapper.find(EuiBreadcrumbs)).toHaveLength(1); -}); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/__snapshots__/elasticsearch_privileges.test.js.snap b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/__snapshots__/elasticsearch_privileges.test.js.snap index dfc6b43dff636..cfb36fa958090 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/__snapshots__/elasticsearch_privileges.test.js.snap +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/__snapshots__/elasticsearch_privileges.test.js.snap @@ -39,9 +39,11 @@ exports[`it renders without crashing 1`] = ` onChange={[Function]} role={ Object { - "cluster": Array [], - "indices": Array [], - "run_as": Array [], + "elasticsearch": Object { + "cluster": Array [], + "indices": Array [], + "run_as": Array [], + }, } } /> @@ -129,9 +131,11 @@ exports[`it renders without crashing 1`] = ` onChange={[MockFunction]} role={ Object { - "cluster": Array [], - "indices": Array [], - "run_as": Array [], + "elasticsearch": Object { + "cluster": Array [], + "indices": Array [], + "run_as": Array [], + }, } } validator={ diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.js index e67ddd16a7fb3..400e674f3ca7a 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.js @@ -41,7 +41,7 @@ export class ClusterPrivileges extends Component { label: i })); - const selectionMap = (role.cluster || []) + const selectionMap = (role.elasticsearch.cluster || []) .map(k => ({ [k]: true })) .reduce((acc, o) => ({ ...acc, ...o }), {}); @@ -58,7 +58,7 @@ export class ClusterPrivileges extends Component { }; onClusterPrivilegesChange = (privilege) => { - const { cluster } = this.props.role; + const { cluster } = this.props.role.elasticsearch; const indexOfExistingPrivilege = cluster.indexOf(privilege); const shouldRemove = indexOfExistingPrivilege >= 0; diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.test.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.test.js index f75cf0ade71a9..20bb0846e5b1c 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.test.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/cluster_privileges.test.js @@ -10,11 +10,11 @@ import { ClusterPrivileges } from './cluster_privileges'; import { EuiCheckboxGroup } from '@elastic/eui'; test('it renders without crashing', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); test('it renders 2 checkbox groups of privileges', () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.find(EuiCheckboxGroup)).toHaveLength(2); }); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.js index a0c6eca6f0c6e..2a71803a7a214 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.js @@ -94,7 +94,7 @@ export class ElasticsearchPrivileges extends Component { ({ id: username, label: username }))} - selectedOptions={this.props.role.run_as.map(u => ({ label: u }))} + selectedOptions={this.props.role.elasticsearch.run_as.map(u => ({ label: u }))} onChange={this.onRunAsUserChange} isDisabled={!this.props.editable} /> @@ -129,7 +129,7 @@ export class ElasticsearchPrivileges extends Component { addIndexPrivilege = () => { const { role } = this.props; - const newIndices = [...role.indices, { + const newIndices = [...role.elasticsearch.indices, { names: [], privileges: [], field_security: { @@ -139,14 +139,20 @@ export class ElasticsearchPrivileges extends Component { this.props.onChange({ ...this.props.role, - indices: newIndices + elasticsearch: { + ...this.props.role.elasticsearch, + indices: newIndices + } }); }; onClusterPrivilegesChange = (cluster) => { const role = { ...this.props.role, - cluster + elasticsearch: { + ...this.props.role.elasticsearch, + cluster, + }, }; this.props.onChange(role); @@ -155,7 +161,10 @@ export class ElasticsearchPrivileges extends Component { onRunAsUserChange = (users) => { const role = { ...this.props.role, - run_as: users.map(u => u.label) + elasticsearch: { + ...this.props.role.elasticsearch, + run_as: users.map(u => u.label), + }, }; this.props.onChange(role); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.test.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.test.js index 7a2af5723e543..fdcec4223e708 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.test.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/elasticsearch_privileges.test.js @@ -14,9 +14,11 @@ import { RoleValidator } from '../../lib/validate_role'; test('it renders without crashing', () => { const props = { role: { - cluster: [], - indices: [], - run_as: [] + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, }, editable: true, httpClient: jest.fn(), @@ -34,9 +36,11 @@ test('it renders without crashing', () => { test('it renders ClusterPrivileges', () => { const props = { role: { - cluster: [], - indices: [], - run_as: [] + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, }, editable: true, httpClient: jest.fn(), @@ -54,9 +58,11 @@ test('it renders ClusterPrivileges', () => { test('it renders IndexPrivileges', () => { const props = { role: { - cluster: [], - indices: [], - run_as: [] + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, }, editable: true, httpClient: jest.fn(), @@ -69,4 +75,4 @@ test('it renders IndexPrivileges', () => { }; const wrapper = mount(); expect(wrapper.find(IndexPrivileges)).toHaveLength(1); -}); \ No newline at end of file +}); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.js index cb72ecd7aa4bf..601c855c76076 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.js @@ -26,11 +26,11 @@ export class IndexPrivileges extends Component { } componentDidMount() { - this.loadAvailableFields(this.props.role.indices); + this.loadAvailableFields(this.props.role.elasticsearch.indices); } render() { - const { indices = [] } = this.props.role; + const { indices = [] } = this.props.role.elasticsearch; const { indexPatterns, @@ -67,7 +67,7 @@ export class IndexPrivileges extends Component { addIndexPrivilege = () => { const { role } = this.props; - const newIndices = [...role.indices, { + const newIndices = [...role.elasticsearch.indices, { names: [], privileges: [], field_security: { @@ -77,21 +77,27 @@ export class IndexPrivileges extends Component { this.props.onChange({ ...this.props.role, - indices: newIndices + elasticsearch: { + ...this.props.role.elasticsearch, + indices: newIndices, + }, }); }; onIndexPrivilegeChange = (privilegeIndex) => { return (updatedPrivilege) => { const { role } = this.props; - const { indices } = role; + const { indices } = role.elasticsearch; const newIndices = [...indices]; newIndices[privilegeIndex] = updatedPrivilege; this.props.onChange({ ...this.props.role, - indices: newIndices + elasticsearch: { + ...this.props.role.elasticsearch, + indices: newIndices, + }, }); this.loadAvailableFields(newIndices); @@ -102,12 +108,15 @@ export class IndexPrivileges extends Component { return () => { const { role } = this.props; - const newIndices = [...role.indices]; + const newIndices = [...role.elasticsearch.indices]; newIndices.splice(privilegeIndex, 1); this.props.onChange({ ...this.props.role, - indices: newIndices + elasticsearch: { + ...this.props.role.elasticsearch, + indices: newIndices + }, }); }; } diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.test.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.test.js index 221d301ceef0f..3a4fb950e555d 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.test.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/index_privileges.test.js @@ -13,9 +13,11 @@ import { RoleValidator } from '../../lib/validate_role'; test('it renders without crashing', () => { const props = { role: { - cluster: [], - indices: [], - run_as: [] + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, }, httpClient: jest.fn(), onChange: jest.fn(), @@ -31,16 +33,18 @@ test('it renders without crashing', () => { test('it renders a IndexPrivilegeForm for each privilege on the role', () => { const props = { role: { - cluster: [], - indices: [{ - names: ['foo*'], - privileges: ['all'], - query: '*', - field_security: { - grant: ['some_field'] - } - }], - run_as: [] + elasticsearch: { + cluster: [], + indices: [{ + names: ['foo*'], + privileges: ['all'], + query: '*', + field_security: { + grant: ['some_field'] + } + }], + run_as: [], + }, }, httpClient: jest.fn(), onChange: jest.fn(), @@ -51,4 +55,4 @@ test('it renders a IndexPrivilegeForm for each privilege on the role', () => { }; const wrapper = mount(); expect(wrapper.find(IndexPrivilegeForm)).toHaveLength(1); -}); \ No newline at end of file +}); diff --git a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana_privileges.js b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana_privileges.js index a8c2a2c52cbe0..e5e9ddb2bff47 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana_privileges.js +++ b/x-pack/plugins/security/public/views/management/edit_role/components/privileges/kibana_privileges.js @@ -7,8 +7,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { isReservedRole } from '../../../../../lib/role'; -import { getKibanaPrivileges } from '../../lib/get_application_privileges'; -import { setApplicationPrivileges } from '../../lib/set_application_privileges'; +import { getKibanaPrivilegesViewModel, getKibanaPrivileges } from '../../lib/get_application_privileges'; import { CollapsiblePanel } from '../collapsible_panel'; import { @@ -27,7 +26,7 @@ export class KibanaPrivileges extends Component { onChange: PropTypes.func.isRequired, }; - idPrefix = () => `${this.props.rbacApplication}_`; + idPrefix = () => `id_`; privilegeToId = (privilege) => `${this.idPrefix()}${privilege}`; @@ -45,10 +44,9 @@ export class KibanaPrivileges extends Component { const { kibanaAppPrivileges, role, - rbacApplication } = this.props; - const kibanaPrivileges = getKibanaPrivileges(kibanaAppPrivileges, role, rbacApplication); + const kibanaPrivileges = getKibanaPrivilegesViewModel(kibanaAppPrivileges, role.kibana); const options = [ { value: noPrivilegeValue, text: 'none' }, @@ -80,7 +78,7 @@ export class KibanaPrivileges extends Component { onKibanaPrivilegesChange = (e) => { const role = { ...this.props.role, - applications: [...this.props.role.applications] + kibana: [...this.props.role.kibana] }; const privilege = e.target.value; @@ -88,12 +86,12 @@ export class KibanaPrivileges extends Component { if (privilege === noPrivilegeValue) { // unsetting all privileges -- only necessary until RBAC Phase 3 const noPrivileges = {}; - setApplicationPrivileges(noPrivileges, role, this.props.rbacApplication); + role.kibana = getKibanaPrivileges(noPrivileges); } else { const newPrivileges = { [privilege]: true }; - setApplicationPrivileges(newPrivileges, role, this.props.rbacApplication); + role.kibana = getKibanaPrivileges(newPrivileges); } this.props.onChange(role); diff --git a/x-pack/plugins/security/public/views/management/edit_role/edit_role.html b/x-pack/plugins/security/public/views/management/edit_role/edit_role.html index 5539f0521dd79..292b1e517a69a 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/edit_role.html +++ b/x-pack/plugins/security/public/views/management/edit_role/edit_role.html @@ -1 +1,3 @@ -
+ +
+ diff --git a/x-pack/plugins/security/public/views/management/edit_role/index.js b/x-pack/plugins/security/public/views/management/edit_role/index.js index bd166e16a658e..45b124167815c 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/index.js +++ b/x-pack/plugins/security/public/views/management/edit_role/index.js @@ -51,10 +51,13 @@ routes.when(`${EDIT_ROLES_PATH}/:name?`, { } else { role = Promise.resolve(new ShieldRole({ - cluster: [], - indices: [], - run_as: [], - applications: [] + elasticsearch: { + cluster: [], + indices: [], + run_as: [], + }, + kibana: [], + _unrecognized_applications: [], })); } @@ -91,46 +94,31 @@ routes.when(`${EDIT_ROLES_PATH}/:name?`, { const allowFieldLevelSecurity = xpackInfo.get('features.security.allowRoleFieldLevelSecurity'); const rbacApplication = chrome.getInjected('rbacApplication'); - const domNode = document.getElementById('editRoleReactRoot'); - const { users, indexPatterns, } = $route.current.locals; - const routeBreadcrumbs = routes.getBreadcrumbs(); - - render(, domNode); - - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); + $scope.$$postDigest(() => { + const domNode = document.getElementById('editRoleReactRoot'); + + render(, domNode); + + // unmount react on controller destroy + $scope.$on('$destroy', () => { + unmountComponentAtNode(domNode); + }); }); } }); - -function transformBreadcrumbs(routeBreadcrumbs) { - const indexOfEdit = routeBreadcrumbs.findIndex(b => b.id === 'edit'); - - const hasEntryAfterEdit = indexOfEdit >= 0 && indexOfEdit < (routeBreadcrumbs.length - 1); - - if (hasEntryAfterEdit) { - // The entry after 'edit' is the name of the role being edited (if any). We don't want to use the "humanized" version of the role name here - const roleName = routeBreadcrumbs[indexOfEdit + 1]; - roleName.display = roleName.id; - } - - return routeBreadcrumbs.filter(b => b.id !== 'edit'); -} diff --git a/x-pack/plugins/security/public/views/management/edit_role/lib/__snapshots__/validate_role.test.js.snap b/x-pack/plugins/security/public/views/management/edit_role/lib/__snapshots__/validate_role.test.js.snap index 20b4280b7f493..1f4837b07d0b9 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/lib/__snapshots__/validate_role.test.js.snap +++ b/x-pack/plugins/security/public/views/management/edit_role/lib/__snapshots__/validate_role.test.js.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`validateIndexPrivileges it throws when indices is not an array 1`] = `"Expected role.indices to be an array"`; +exports[`validateIndexPrivileges it throws when indices is not an array 1`] = `"Expected role.elasticsearch.indices to be an array"`; diff --git a/x-pack/plugins/security/public/views/management/edit_role/lib/get_application_privileges.js b/x-pack/plugins/security/public/views/management/edit_role/lib/get_application_privileges.js index 1ee8d201806b6..078dfc1dae0ea 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/lib/get_application_privileges.js +++ b/x-pack/plugins/security/public/views/management/edit_role/lib/get_application_privileges.js @@ -5,22 +5,38 @@ */ import _ from 'lodash'; -export function getKibanaPrivileges(kibanaApplicationPrivilege, role, application) { - const kibanaPrivileges = kibanaApplicationPrivilege.reduce((acc, p) => { - acc[p.name] = false; +export function getKibanaPrivilegesViewModel(applicationPrivileges, roleKibanaPrivileges) { + const viewModel = applicationPrivileges.reduce((acc, applicationPrivilege) => { + acc[applicationPrivilege.name] = false; return acc; }, {}); - if (!role.applications || role.applications.length === 0) { - return kibanaPrivileges; + if (!roleKibanaPrivileges || roleKibanaPrivileges.length === 0) { + return viewModel; } - const applications = role.applications.filter(x => x.application === application); - - const assigned = _.uniq(_.flatten(_.pluck(applications, 'privileges'))); - assigned.forEach(a => { - kibanaPrivileges[a] = true; + const assignedPrivileges = _.uniq(_.flatten(_.pluck(roleKibanaPrivileges, 'privileges'))); + assignedPrivileges.forEach(assignedPrivilege => { + // we don't want to display privileges that aren't in our expected list of privileges + if (assignedPrivilege in viewModel) { + viewModel[assignedPrivilege] = true; + } }); - return kibanaPrivileges; + return viewModel; +} + +export function getKibanaPrivileges(kibanaPrivilegesViewModel) { + const selectedPrivileges = Object.keys(kibanaPrivilegesViewModel).filter(key => kibanaPrivilegesViewModel[key]); + + // if we have any selected privileges, add a single application entry + if (selectedPrivileges.length > 0) { + return [ + { + privileges: selectedPrivileges + } + ]; + } + + return []; } diff --git a/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.js b/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.js index 3fc638a83782c..29160173363b4 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.js +++ b/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.js @@ -35,11 +35,11 @@ export class RoleValidator { validateIndexPrivileges(role) { if (!this._shouldValidate) return valid(); - if (!Array.isArray(role.indices)) { - throw new TypeError(`Expected role.indices to be an array`); + if (!Array.isArray(role.elasticsearch.indices)) { + throw new TypeError(`Expected role.elasticsearch.indices to be an array`); } - const areIndicesValid = role.indices + const areIndicesValid = role.elasticsearch.indices .map(this.validateIndexPrivilege.bind(this)) .find((result) => result.isInvalid) == null; diff --git a/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.test.js b/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.test.js index 47d2bfe59a37e..75fc8341fc639 100644 --- a/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.test.js +++ b/x-pack/plugins/security/public/views/management/edit_role/lib/validate_role.test.js @@ -60,10 +60,13 @@ describe('validateIndexPrivileges', () => { test('it ignores privilegs with no indices defined', () => { const role = { - indices: [{ - names: [], - privileges: [] - }] + elasticsearch: { + indices: [{ + names: [], + privileges: [] + }] + } + }; expect(validator.validateIndexPrivileges(role)).toEqual({ @@ -73,10 +76,13 @@ describe('validateIndexPrivileges', () => { test('it requires privilges when an index is defined', () => { const role = { - indices: [{ - names: ['index-*'], - privileges: [] - }] + elasticsearch: { + indices: [{ + names: ['index-*'], + privileges: [] + }] + } + }; expect(validator.validateIndexPrivileges(role)).toEqual({ @@ -86,7 +92,9 @@ describe('validateIndexPrivileges', () => { test('it throws when indices is not an array', () => { const role = { - indices: null + elasticsearch: { + indices: null + } }; expect(() => validator.validateIndexPrivileges(role)).toThrowErrorMatchingSnapshot(); diff --git a/x-pack/plugins/spaces/public/views/management/components/__snapshots__/page_header.test.js.snap b/x-pack/plugins/spaces/public/views/management/components/__snapshots__/page_header.test.js.snap deleted file mode 100644 index 628a5c068f83a..0000000000000 --- a/x-pack/plugins/spaces/public/views/management/components/__snapshots__/page_header.test.js.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`it renders without crashing 1`] = ` -
- - -
-`; diff --git a/x-pack/plugins/spaces/public/views/management/components/index.js b/x-pack/plugins/spaces/public/views/management/components/index.js index 1d158d623b503..e134461ee43a6 100644 --- a/x-pack/plugins/spaces/public/views/management/components/index.js +++ b/x-pack/plugins/spaces/public/views/management/components/index.js @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PageHeader } from './page_header'; export { DeleteSpacesButton } from './delete_spaces_button'; diff --git a/x-pack/plugins/spaces/public/views/management/components/page_header.js b/x-pack/plugins/spaces/public/views/management/components/page_header.js deleted file mode 100644 index ff81942abb49c..0000000000000 --- a/x-pack/plugins/spaces/public/views/management/components/page_header.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -import { - EuiBreadcrumbs, - EuiSpacer, -} from '@elastic/eui'; - -export class PageHeader extends Component { - render() { - return ( -
- - -
- ); - } - - buildBreadcrumb = (breadcrumb) => { - return { - text: breadcrumb.display, - href: breadcrumb.href, - }; - } -} - -PageHeader.propTypes = { - breadcrumbs: PropTypes.array.isRequired -}; \ No newline at end of file diff --git a/x-pack/plugins/spaces/public/views/management/components/page_header.test.js b/x-pack/plugins/spaces/public/views/management/components/page_header.test.js deleted file mode 100644 index 706a6de4a0abc..0000000000000 --- a/x-pack/plugins/spaces/public/views/management/components/page_header.test.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 React from 'react'; -import { PageHeader } from './page_header'; -import { mount, shallow } from 'enzyme'; - -test('it renders without crashing', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); -}); - -test('it renders breadcrumbs', () => { - const component = mount( - - ); - - expect(component.find('a.euiBreadcrumb')).toHaveLength(1); - expect(component.find('span.euiBreadcrumb')).toHaveLength(1); - -}); diff --git a/x-pack/plugins/spaces/public/views/management/edit_space/manage_space_page.js b/x-pack/plugins/spaces/public/views/management/edit_space/manage_space_page.js index 10e7c4040b76a..68c6e3b3d1967 100644 --- a/x-pack/plugins/spaces/public/views/management/edit_space/manage_space_page.js +++ b/x-pack/plugins/spaces/public/views/management/edit_space/manage_space_page.js @@ -20,7 +20,7 @@ import { EuiPanel, } from '@elastic/eui'; -import { DeleteSpacesButton, PageHeader } from '../components'; +import { DeleteSpacesButton } from '../components'; import { SpaceAvatar } from '../../components'; import { Notifier, toastNotifications } from 'ui/notify'; @@ -77,7 +77,6 @@ export class ManageSpacePage extends Component { return ( - {this.getFormHeading()} @@ -396,5 +395,4 @@ ManageSpacePage.propTypes = { space: PropTypes.string, spacesManager: PropTypes.object, spacesNavState: PropTypes.object.isRequired, - breadcrumbs: PropTypes.array.isRequired, }; diff --git a/x-pack/plugins/spaces/public/views/management/page_routes.js b/x-pack/plugins/spaces/public/views/management/page_routes.js index 4367d2b9282a6..5a16ff72ffbcb 100644 --- a/x-pack/plugins/spaces/public/views/management/page_routes.js +++ b/x-pack/plugins/spaces/public/views/management/page_routes.js @@ -21,19 +21,20 @@ const reactRootNodeId = 'manageSpacesReactRoot'; routes.when('/management/spaces/list', { template, controller: function ($scope, $http, chrome, spacesNavState) { - const domNode = document.getElementById(reactRootNodeId); + $scope.$$postDigest(() => { + const domNode = document.getElementById(reactRootNodeId); - const spacesManager = new SpacesManager($http, chrome); + const spacesManager = new SpacesManager($http, chrome); - render(, domNode); + render(, domNode); - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); + // unmount react on controller destroy + $scope.$on('$destroy', () => { + unmountComponentAtNode(domNode); + }); }); } }); @@ -41,19 +42,20 @@ routes.when('/management/spaces/list', { routes.when('/management/spaces/create', { template, controller: function ($scope, $http, chrome, spacesNavState) { - const domNode = document.getElementById(reactRootNodeId); + $scope.$$postDigest(() => { + const domNode = document.getElementById(reactRootNodeId); - const spacesManager = new SpacesManager($http, chrome); + const spacesManager = new SpacesManager($http, chrome); - render(, domNode); + render(, domNode); - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); + // unmount react on controller destroy + $scope.$on('$destroy', () => { + unmountComponentAtNode(domNode); + }); }); } }); @@ -65,28 +67,26 @@ routes.when('/management/spaces/edit', { routes.when('/management/spaces/edit/:space', { template, controller: function ($scope, $http, $route, chrome, spacesNavState) { - const domNode = document.getElementById(reactRootNodeId); + $scope.$$postDigest(() => { - const { space } = $route.current.params; + const domNode = document.getElementById(reactRootNodeId); - const spacesManager = new SpacesManager($http, chrome); + const { space } = $route.current.params; - render(, domNode); + const spacesManager = new SpacesManager($http, chrome); - // unmount react on controller destroy - $scope.$on('$destroy', () => { - unmountComponentAtNode(domNode); + render(, domNode); + + // unmount react on controller destroy + $scope.$on('$destroy', () => { + unmountComponentAtNode(domNode); + }); }); } }); - -function transformBreadcrumbs(routeBreadcrumbs) { - return routeBreadcrumbs.filter(b => b.id !== 'edit'); -} diff --git a/x-pack/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.js b/x-pack/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.js index bb68e235053fe..f18db68dc5a74 100644 --- a/x-pack/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.js +++ b/x-pack/plugins/spaces/public/views/management/spaces_grid/spaces_grid_page.js @@ -19,7 +19,7 @@ import { EuiLink, } from '@elastic/eui'; -import { DeleteSpacesButton, PageHeader } from '../components'; +import { DeleteSpacesButton } from '../components'; import { isReservedSpace } from '../../../../common'; export class SpacesGridPage extends Component { @@ -36,7 +36,6 @@ export class SpacesGridPage extends Component { render() { return ( - @@ -142,5 +141,4 @@ export class SpacesGridPage extends Component { SpacesGridPage.propTypes = { spacesManager: PropTypes.object.isRequired, spacesNavState: PropTypes.object.isRequired, - breadcrumbs: PropTypes.array.isRequired, }; diff --git a/x-pack/plugins/spaces/public/views/management/template.html b/x-pack/plugins/spaces/public/views/management/template.html index 8da58b1e3a547..8e7851095e903 100644 --- a/x-pack/plugins/spaces/public/views/management/template.html +++ b/x-pack/plugins/spaces/public/views/management/template.html @@ -1 +1,3 @@ -
+ +
+