Team Admin: Give team admin all team maintainer's permissions for query experience (#2689)
This commit is contained in:
@@ -43,7 +43,7 @@ const App = ({ children }: IAppProps) => {
|
||||
currentUser,
|
||||
isGlobalObserver,
|
||||
isOnlyObserver,
|
||||
isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
enrollSecret,
|
||||
} = useContext(AppContext);
|
||||
|
||||
@@ -68,8 +68,8 @@ const App = ({ children }: IAppProps) => {
|
||||
!isGlobalObserver &&
|
||||
typeof isOnlyObserver !== "undefined" &&
|
||||
!isOnlyObserver &&
|
||||
typeof isAnyTeamMaintainer !== "undefined" &&
|
||||
!isAnyTeamMaintainer;
|
||||
typeof isAnyTeamMaintainerOrTeamAdmin !== "undefined" &&
|
||||
!isAnyTeamMaintainerOrTeamAdmin;
|
||||
|
||||
if (canGetEnrollSecret) {
|
||||
dispatch(getEnrollSecret())
|
||||
|
||||
@@ -23,6 +23,7 @@ type InitialStateType = {
|
||||
isGlobalObserver: boolean | undefined;
|
||||
isOnGlobalTeam: boolean | undefined;
|
||||
isAnyTeamMaintainer: boolean | undefined;
|
||||
isAnyTeamMaintainerOrTeamAdmin: boolean | undefined;
|
||||
isTeamMaintainer: boolean | undefined;
|
||||
isAnyTeamAdmin: boolean | undefined;
|
||||
isTeamAdmin: boolean | undefined;
|
||||
@@ -46,6 +47,7 @@ const initialState = {
|
||||
isGlobalObserver: undefined,
|
||||
isOnGlobalTeam: undefined,
|
||||
isAnyTeamMaintainer: undefined,
|
||||
isAnyTeamMaintainerOrTeamAdmin: undefined,
|
||||
isTeamMaintainer: undefined,
|
||||
isAnyTeamAdmin: undefined,
|
||||
isTeamAdmin: undefined,
|
||||
@@ -82,6 +84,10 @@ const setPermissions = (user: IUser, config: IConfig, teamId = 0) => {
|
||||
isGlobalObserver: permissions.isGlobalObserver(user),
|
||||
isOnGlobalTeam: permissions.isOnGlobalTeam(user),
|
||||
isAnyTeamMaintainer: permissions.isAnyTeamMaintainer(user),
|
||||
isAnyTeamMaintainerOrTeamAdmin: permissions.isAnyTeamMaintainerOrTeamAdmin(
|
||||
user
|
||||
),
|
||||
isAnyTeamAdmin: permissions.isAnyTeamAdmin(user),
|
||||
isTeamMaintainer: permissions.isTeamMaintainer(user, teamId),
|
||||
isOnlyObserver: permissions.isOnlyObserver(user),
|
||||
};
|
||||
@@ -139,6 +145,7 @@ const AppProvider = ({ children }: Props) => {
|
||||
isGlobalObserver: state.isGlobalObserver,
|
||||
isOnGlobalTeam: state.isOnGlobalTeam,
|
||||
isAnyTeamMaintainer: state.isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin: state.isAnyTeamMaintainerOrTeamAdmin,
|
||||
isTeamMaintainer: state.isTeamMaintainer,
|
||||
isTeamAdmin: state.isTeamAdmin,
|
||||
isAnyTeamAdmin: state.isAnyTeamAdmin,
|
||||
|
||||
@@ -59,7 +59,7 @@ const ManagePolicyPage = (managePoliciesPageProps: {
|
||||
const {
|
||||
config,
|
||||
currentUser,
|
||||
isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
isGlobalAdmin,
|
||||
isGlobalMaintainer,
|
||||
isOnGlobalTeam,
|
||||
@@ -287,7 +287,7 @@ const ManagePolicyPage = (managePoliciesPageProps: {
|
||||
// Null case must be distinguished from 0 (which is used as the id for the "All teams" option)
|
||||
// so a falsiness check cannot be used here. Null case here allows us to skip API call.
|
||||
if (selectedTeamId !== null) {
|
||||
if (isOnGlobalTeam || isAnyTeamMaintainer) {
|
||||
if (isOnGlobalTeam || isAnyTeamMaintainerOrTeamAdmin) {
|
||||
getGlobalPolicies();
|
||||
}
|
||||
if (selectedTeamId) {
|
||||
@@ -297,7 +297,7 @@ const ManagePolicyPage = (managePoliciesPageProps: {
|
||||
}, [
|
||||
getGlobalPolicies,
|
||||
getTeamPolicies,
|
||||
isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
isOnGlobalTeam,
|
||||
selectedTeamId,
|
||||
]);
|
||||
|
||||
+7
-4
@@ -63,7 +63,9 @@ interface IDataColumn {
|
||||
// more info here https://react-table.tanstack.com/docs/api/useTable#cell-properties
|
||||
const generateTableHeaders = (currentUser: IUser): IDataColumn[] => {
|
||||
const isOnlyObserver = permissionsUtils.isOnlyObserver(currentUser);
|
||||
const isAnyTeamMaintainer = permissionsUtils.isAnyTeamMaintainer(currentUser);
|
||||
const isAnyTeamMaintainerOrTeamAdmin = permissionsUtils.isAnyTeamMaintainerOrTeamAdmin(
|
||||
currentUser
|
||||
);
|
||||
|
||||
const tableHeaders: IDataColumn[] = [
|
||||
{
|
||||
@@ -145,7 +147,7 @@ const generateTableHeaders = (currentUser: IUser): IDataColumn[] => {
|
||||
value: checked,
|
||||
indeterminate,
|
||||
onChange: () => {
|
||||
if (!isAnyTeamMaintainer) {
|
||||
if (!isAnyTeamMaintainerOrTeamAdmin) {
|
||||
toggleAllRowsSelected();
|
||||
} else {
|
||||
// Team maintainers may only delete the queries that they have authored
|
||||
@@ -181,7 +183,8 @@ const generateTableHeaders = (currentUser: IUser): IDataColumn[] => {
|
||||
value: checked,
|
||||
onChange: () => row.toggleRowSelected(),
|
||||
disabled:
|
||||
isAnyTeamMaintainer && row.original.author_id !== currentUser.id,
|
||||
isAnyTeamMaintainerOrTeamAdmin &&
|
||||
row.original.author_id !== currentUser.id,
|
||||
};
|
||||
// If the user is a team maintainer, we only enable checkboxes for queries
|
||||
// that they authored and we include a tooltip to explain disabled checkboxes
|
||||
@@ -191,7 +194,7 @@ const generateTableHeaders = (currentUser: IUser): IDataColumn[] => {
|
||||
data-tip
|
||||
data-for={`${"select-checkbox"}__${row.original.id}`}
|
||||
data-tip-disable={
|
||||
!isAnyTeamMaintainer ||
|
||||
!isAnyTeamMaintainerOrTeamAdmin ||
|
||||
row.original.author_id === currentUser.id
|
||||
}
|
||||
>
|
||||
|
||||
@@ -41,9 +41,11 @@ const QueryPage = ({
|
||||
location: { query: URLQuerySearch },
|
||||
}: IQueryPageProps): JSX.Element => {
|
||||
const queryIdForEdit = paramsQueryId ? parseInt(paramsQueryId, 10) : null;
|
||||
const { isGlobalAdmin, isGlobalMaintainer, isAnyTeamMaintainer } = useContext(
|
||||
AppContext
|
||||
);
|
||||
const {
|
||||
isGlobalAdmin,
|
||||
isGlobalMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
} = useContext(AppContext);
|
||||
const {
|
||||
selectedOsqueryTable,
|
||||
setSelectedOsqueryTable,
|
||||
@@ -212,7 +214,7 @@ const QueryPage = ({
|
||||
const showSidebar =
|
||||
isFirstStep &&
|
||||
isSidebarOpen &&
|
||||
(isGlobalAdmin || isGlobalMaintainer || isAnyTeamMaintainer);
|
||||
(isGlobalAdmin || isGlobalMaintainer || isAnyTeamMaintainerOrTeamAdmin);
|
||||
|
||||
return (
|
||||
<div className={`${baseClass} ${sidebarClass}`}>
|
||||
|
||||
@@ -83,7 +83,7 @@ const QueryForm = ({
|
||||
currentUser,
|
||||
isOnlyObserver,
|
||||
isGlobalObserver,
|
||||
isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
isGlobalAdmin,
|
||||
isGlobalMaintainer,
|
||||
} = useContext(AppContext);
|
||||
@@ -95,11 +95,11 @@ const QueryForm = ({
|
||||
}, [lastEditedQueryBody]);
|
||||
|
||||
const hasTeamMaintainerPermissions = isEditMode
|
||||
? isAnyTeamMaintainer &&
|
||||
? isAnyTeamMaintainerOrTeamAdmin &&
|
||||
storedQuery &&
|
||||
currentUser &&
|
||||
storedQuery.author_id === currentUser.id
|
||||
: isAnyTeamMaintainer;
|
||||
: isAnyTeamMaintainerOrTeamAdmin;
|
||||
|
||||
const hasSavePermissions = isGlobalAdmin || isGlobalMaintainer;
|
||||
|
||||
@@ -313,7 +313,7 @@ const QueryForm = ({
|
||||
<div
|
||||
className={`${baseClass}__button-wrap ${baseClass}__button-wrap--new-query`}
|
||||
>
|
||||
{(hasSavePermissions || isAnyTeamMaintainer) && (
|
||||
{(hasSavePermissions || isAnyTeamMaintainerOrTeamAdmin) && (
|
||||
<>
|
||||
{isEditMode && (
|
||||
<Button
|
||||
@@ -330,7 +330,10 @@ const QueryForm = ({
|
||||
data-tip
|
||||
data-for="save-query-button"
|
||||
data-tip-disable={
|
||||
!(isAnyTeamMaintainer && !hasTeamMaintainerPermissions)
|
||||
!(
|
||||
isAnyTeamMaintainerOrTeamAdmin &&
|
||||
!hasTeamMaintainerPermissions
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button
|
||||
@@ -338,7 +341,8 @@ const QueryForm = ({
|
||||
variant="brand"
|
||||
onClick={promptSaveQuery()}
|
||||
disabled={
|
||||
isAnyTeamMaintainer && !hasTeamMaintainerPermissions
|
||||
isAnyTeamMaintainerOrTeamAdmin &&
|
||||
!hasTeamMaintainerPermissions
|
||||
}
|
||||
>
|
||||
Save
|
||||
|
||||
@@ -61,6 +61,16 @@ const isAnyTeamAdmin = (user: IUser): boolean => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const isAnyTeamMaintainerOrTeamAdmin = (user: IUser): boolean => {
|
||||
if (!isOnGlobalTeam(user)) {
|
||||
return user.teams.some(
|
||||
(team) => team?.role === "maintainer" || team?.role === "admin"
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const isOnlyObserver = (user: IUser): boolean => {
|
||||
if (isGlobalObserver(user)) {
|
||||
return true;
|
||||
@@ -68,7 +78,9 @@ const isOnlyObserver = (user: IUser): boolean => {
|
||||
|
||||
// Return false if any role is team maintainer
|
||||
if (!isOnGlobalTeam(user)) {
|
||||
return !user.teams.some((team) => team?.role === "maintainer");
|
||||
return !user.teams.some(
|
||||
(team) => team?.role === "maintainer" || team?.role === "admin"
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -84,6 +96,7 @@ export default {
|
||||
isTeamObserver,
|
||||
isTeamMaintainer,
|
||||
isAnyTeamMaintainer,
|
||||
isAnyTeamMaintainerOrTeamAdmin,
|
||||
isTeamAdmin,
|
||||
isAnyTeamAdmin,
|
||||
isOnlyObserver,
|
||||
|
||||
Reference in New Issue
Block a user