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
This commit is contained in:
Gabe Hernandez 2021-05-26 13:08:42 +01:00 committed by GitHub
parent a2a7082bd3
commit d3932d736d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 15 deletions

View file

@ -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) => <TextCell value={cellProps.cell.value} />,
},
{
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,
};

View file

@ -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`}
>
<EditColumnsModal
columns={hostTableHeaders}
columns={generateAvailableTableHeaders(config, currentUser)}
hiddenColumns={hiddenColumns}
onSaveColumns={this.onSaveColumns}
onCancelColumns={this.onCancelColumns}
@ -548,7 +551,14 @@ export class ManageHostsPage extends PureComponent {
};
renderTable = () => {
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 (
<TableContainer
columns={generateVisibleHostColumns(hiddenColumns)}
columns={generateVisibleTableColumns(
hiddenColumns,
config,
currentUser
)}
data={hosts}
isLoading={loadingHosts}
defaultSortHeader={"hostname"}
@ -667,7 +681,6 @@ const mapStateToProps = (state, { location, params }) => {
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,

View file

@ -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";