dont show os updates page for users who are not global admin or the team admin (#31410)

fixes #25367 

this doesnt show the os updates page for users who are not global admins
or the current team admin. we also redirect users to the os settings
page if they try to navigate to the os updates page and dont have
permission

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] QA'd all new/changed functionality manually
This commit is contained in:
Gabriel Hernandez 2025-07-31 12:04:06 +01:00 committed by GitHub
parent f637cfadac
commit 24e7934646
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 12 deletions

View file

@ -0,0 +1 @@
- add permissions to os updates page so that only global admins and the team admin can see the page

View file

@ -1,4 +1,4 @@
import React, { useCallback, useContext } from "react";
import React, { useCallback, useContext, useMemo } from "react";
import { Tab, Tabs, TabList } from "react-tabs";
import { InjectedRouter } from "react-router";
@ -54,8 +54,11 @@ interface IManageControlsPageProps {
router: InjectedRouter; // v3
}
const getTabIndex = (path: string): number => {
return controlsSubNav.findIndex((navItem) => {
const getTabIndex = (
permittedControlsSubNav: IControlsSubNavItem[],
path: string
): number => {
return permittedControlsSubNav.findIndex((navItem) => {
// tab stays highlighted for paths that start with same pathname
return path.startsWith(navItem.pathname);
});
@ -73,7 +76,13 @@ const ManageControlsPage = ({
}: IManageControlsPageProps): JSX.Element => {
const page = parseInt(location?.query?.page || "", 10) || 0;
const { config, isOnGlobalTeam, isPremiumTier } = useContext(AppContext);
const {
config,
isOnGlobalTeam,
isPremiumTier,
isGlobalAdmin,
isTeamAdmin,
} = useContext(AppContext);
const {
currentTeamId,
@ -93,9 +102,19 @@ const ManageControlsPage = ({
},
});
const permittedControlsSubNav = useMemo(() => {
let renderedSubNav = controlsSubNav;
if (!isGlobalAdmin && !isTeamAdmin) {
renderedSubNav = controlsSubNav.filter((navItem) => {
return navItem.name !== "OS updates";
});
}
return renderedSubNav;
}, [isGlobalAdmin, isTeamAdmin]);
const navigateToNav = useCallback(
(i: number): void => {
const navPath = controlsSubNav[i].pathname;
const navPath = permittedControlsSubNav[i].pathname;
// remove query params related to the prior tab
const newParams = new URLSearchParams(location?.search);
subNavQueryParams.forEach((p) => newParams.delete(p));
@ -107,7 +126,7 @@ const ManageControlsPage = ({
.concat(location?.hash || "")
);
},
[location, router]
[location, router, permittedControlsSubNav]
);
const renderBody = () => {
@ -115,11 +134,14 @@ const ManageControlsPage = ({
<div>
<TabNav>
<Tabs
selectedIndex={getTabIndex(location?.pathname || "")}
selectedIndex={getTabIndex(
permittedControlsSubNav,
location?.pathname || ""
)}
onSelect={navigateToNav}
>
<TabList>
{controlsSubNav.map((navItem) => {
{permittedControlsSubNav.map((navItem) => {
return (
<Tab key={navItem.name} data-text={navItem.name}>
<TabText>{navItem.name}</TabText>

View file

@ -3,6 +3,7 @@ import { InjectedRouter } from "react-router";
import { useQuery } from "react-query";
import { AppContext } from "context/app";
import PATHS from "router/paths";
import { IConfig } from "interfaces/config";
import { ITeamConfig } from "interfaces/team";
@ -46,7 +47,13 @@ interface IOSUpdates {
}
const OSUpdates = ({ router, teamIdForApi, queryParams }: IOSUpdates) => {
const { isPremiumTier, config, setConfig } = useContext(AppContext);
const {
isPremiumTier,
isGlobalAdmin,
isTeamAdmin,
config,
setConfig,
} = useContext(AppContext);
const [
selectedPlatformTab,
@ -54,7 +61,6 @@ const OSUpdates = ({ router, teamIdForApi, queryParams }: IOSUpdates) => {
] = useState<OSUpdatesTargetPlatform | null>(null);
const {
isError: isErrorConfig,
isFetching: isFetchingConfig,
isLoading: isLoadingConfig,
refetch: refetchAppConfig,
@ -66,7 +72,6 @@ const OSUpdates = ({ router, teamIdForApi, queryParams }: IOSUpdates) => {
const {
data: teamConfig,
isError: isErrorTeamConfig,
isFetching: isFetchingTeamConfig,
isLoading: isLoadingTeam,
refetch: refetchTeamConfig,
@ -75,11 +80,15 @@ const OSUpdates = ({ router, teamIdForApi, queryParams }: IOSUpdates) => {
() => teamsAPI.load(teamIdForApi),
{
refetchOnWindowFocus: false,
enabled: !!teamIdForApi,
enabled: !!teamIdForApi && (isGlobalAdmin || isTeamAdmin),
select: (data) => data.team,
}
);
if (!isGlobalAdmin && !isTeamAdmin) {
router.replace(PATHS.CONTROLS_OS_SETTINGS);
}
// Not premium shows premium message
if (!isPremiumTier) {
return (