From d3932d736dcc9bda6d7470d4bf0c6ac52a17eea1 Mon Sep 17 00:00:00 2001 From: Gabe Hernandez Date: Wed, 26 May 2021 13:08:42 +0100 Subject: [PATCH] add permission to host page (#852) * update genreating of available host table headers based on tier * stoping point for host permissions * fixed up available headers for teams depending on permissions * show select column on host table properly --- .../hosts/ManageHostsPage/HostTableConfig.tsx | 67 +++++++++++++++++-- .../hosts/ManageHostsPage/ManageHostsPage.jsx | 30 ++++++--- frontend/utilities/permissions/permissions.ts | 2 +- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx index e29924f2e0..28a4d722ca 100644 --- a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx +++ b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx @@ -17,7 +17,10 @@ import { humanHostLastSeen, humanHostDetailUpdated, } from "kolide/helpers"; -import PATHS from "../../../router/paths"; +import { IConfig } from "interfaces/config"; +import { IUser } from "interfaces/user"; +import PATHS from "router/paths"; +import permissionUtils from "utilities/permissions"; interface IHeaderProps { column: { @@ -56,7 +59,7 @@ const lastSeenTime = (status: string, seenTime: string): string => { return "Online"; }; -const hostTableHeaders: IHostDataColumn[] = [ +const allHostTableHeaders: IHostDataColumn[] = [ // We are using React Table useRowSelect functionality for the selection header. // More information on its API can be found here // https://react-table.tanstack.com/docs/api/useRowSelect @@ -102,6 +105,12 @@ const hostTableHeaders: IHostDataColumn[] = [ ), disableHidden: true, }, + { + title: "Team", + Header: "Team", + accessor: "team_name", + Cell: (cellProps) => , + }, { title: "Status", Header: "Status", @@ -261,12 +270,58 @@ const defaultHiddenColumns = [ "hardware_serial", ]; -const generateVisibleHostColumns = ( - hiddenColumns: string[] +/** + * Will generate a host table column configuration based off of the current user + * permissions and license tier of fleet they are on. + */ +const generateAvailableTableHeaders = ( + config: IConfig, + currentUser: IUser ): IHostDataColumn[] => { - return hostTableHeaders.filter((column) => { + return allHostTableHeaders.reduce( + (columns: IHostDataColumn[], currentColumn: IHostDataColumn) => { + // skip over column headers that are not shown in core tier + if (permissionUtils.isCoreTier(config)) { + if ( + currentColumn.accessor === "team_name" || + currentColumn.id === "selection" + ) { + return columns; + } + // In base tier, we want to check user role to enable/disable select column + } else if ( + !permissionUtils.isGlobalAdmin(currentUser) && + !permissionUtils.isGlobalMaintainer(currentUser) + ) { + if (currentColumn.id === "selection") { + return columns; + } + } + + columns.push(currentColumn); + return columns; + }, + [] + ); +}; + +/** + * Will generate a host table column configuration that a user currently sees. + * + */ +const generateVisibleTableColumns = ( + hiddenColumns: string[], + config: IConfig, + currentUser: IUser +): IHostDataColumn[] => { + // remove columns set as hidden by the user. + return generateAvailableTableHeaders(config, currentUser).filter((column) => { return !hiddenColumns.includes(column.accessor as string); }); }; -export { hostTableHeaders, defaultHiddenColumns, generateVisibleHostColumns }; +export { + defaultHiddenColumns, + generateAvailableTableHeaders, + generateVisibleTableColumns, +}; diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx index 3135983f99..8fc5993097 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx @@ -14,6 +14,7 @@ import TableContainer from "components/TableContainer"; import labelInterface from "interfaces/label"; import hostInterface from "interfaces/host"; import teamInterface from "interfaces/team"; +import userInterface from "interfaces/user"; import osqueryTableInterface from "interfaces/osquery_table"; import statusLabelsInterface from "interfaces/status_labels"; import enrollSecretInterface from "interfaces/enroll_secret"; @@ -33,8 +34,8 @@ import deepDifference from "utilities/deep_difference"; import permissionUtils from "utilities/permissions"; import { defaultHiddenColumns, - hostTableHeaders, - generateVisibleHostColumns, + generateVisibleTableColumns, + generateAvailableTableHeaders, } from "./HostTableConfig"; import AddHostModal from "./components/AddHostModal"; import NoHosts from "./components/NoHosts"; @@ -69,6 +70,7 @@ export class ManageHostsPage extends PureComponent { canAddNewHosts: PropTypes.bool, teams: PropTypes.arrayOf(teamInterface), isGlobalAdmin: PropTypes.bool, + currentUser: userInterface, }; static defaultProps = { @@ -168,7 +170,7 @@ export class ManageHostsPage extends PureComponent { }; // NOTE: this is called once on the initial rendering. The initial render of - // the TableContainer child component. + // the TableContainer child component will call this handler. onTableQueryChange = (queryData) => { const { selectedFilter, dispatch } = this.props; const { @@ -260,7 +262,7 @@ export class ManageHostsPage extends PureComponent { "success", `Hosts successfully transferred to ${team.name}.` ) - ); // TODO: update team name + ); }) .catch(() => { dispatch( @@ -294,6 +296,7 @@ export class ManageHostsPage extends PureComponent { }; renderEditColumnsModal = () => { + const { config, currentUser } = this.props; const { showEditColumnsModal, hiddenColumns } = this.state; if (!showEditColumnsModal) return null; @@ -305,7 +308,7 @@ export class ManageHostsPage extends PureComponent { className={`${baseClass}__invite-modal`} > { - const { selectedFilter, selectedLabel, hosts, loadingHosts } = this.props; + const { + config, + currentUser, + selectedFilter, + selectedLabel, + hosts, + loadingHosts, + } = this.props; const { hiddenColumns } = this.state; const { onTableQueryChange, @@ -567,7 +577,11 @@ export class ManageHostsPage extends PureComponent { return ( { permissionUtils.isGlobalAdmin(currentUser) || permissionUtils.isGlobalMaintainer(currentUser); const isGlobalAdmin = permissionUtils.isGlobalAdmin(currentUser); - const teams = memoizedGetEntity(state.entities.teams.data); return { @@ -682,6 +695,7 @@ const mapStateToProps = (state, { location, params }) => { selectedOsqueryTable, statusLabels, config, + currentUser, hosts, loadingHosts, canAddNewHosts, diff --git a/frontend/utilities/permissions/permissions.ts b/frontend/utilities/permissions/permissions.ts index 91dd96a7a0..458e15f25e 100644 --- a/frontend/utilities/permissions/permissions.ts +++ b/frontend/utilities/permissions/permissions.ts @@ -1,5 +1,5 @@ import { IUser } from "interfaces/user"; -import { IConfig } from "../../interfaces/config"; +import { IConfig } from "interfaces/config"; const isCoreTier = (config: IConfig): boolean => { return config.tier === "core";