1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 05:45:22 +02:00

feat(auth): add useIsEdgeAdmin hook [EE-6627] (#11101)
Some checks are pending
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run

This commit is contained in:
Chaim Lev-Ari 2024-02-15 00:50:26 +02:00 committed by GitHub
parent c08b5af85a
commit edea9e3481
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 389 additions and 198 deletions

View file

@ -15,7 +15,7 @@ import {
type Environment,
type EnvironmentId,
} from '@/react/portainer/environments/types';
import { Authorized, useUser, isEnvironmentAdmin } from '@/react/hooks/useUser';
import { Authorized, useIsEnvironmentAdmin } from '@/react/hooks/useUser';
import { useInfo } from '@/react/docker/proxy/queries/useInfo';
import { useApiVersion } from '@/react/docker/proxy/queries/useVersion';
@ -30,11 +30,11 @@ interface Props {
}
export function DockerSidebar({ environmentId, environment }: Props) {
const { user } = useUser();
const isAdmin = isEnvironmentAdmin(user, environmentId);
const isEnvironmentAdmin = useIsEnvironmentAdmin({ adminOnlyCE: true });
const areStacksVisible =
isAdmin || environment.SecuritySettings.allowStackManagementForRegularUsers;
isEnvironmentAdmin ||
environment.SecuritySettings.allowStackManagementForRegularUsers;
const envInfoQuery = useInfo(
environmentId,
@ -167,7 +167,7 @@ export function DockerSidebar({ environmentId, environment }: Props) {
/>
)}
{!isSwarmManager && isAdmin && (
{!isSwarmManager && isEnvironmentAdmin && (
<SidebarItem
to="docker.events"
params={{ endpointId: environmentId }}

View file

@ -12,7 +12,7 @@ import clsx from 'clsx';
import { useSystemStatus } from '@/react/portainer/system/useSystemStatus';
import { useSystemVersion } from '@/react/portainer/system/useSystemVersion';
import { useCurrentUser } from '@/react/hooks/useUser';
import { useIsEdgeAdmin } from '@/react/hooks/useUser';
import { Modal } from '@@/modals';
import { Button } from '@@/buttons';
@ -47,7 +47,7 @@ export function BuildInfoModalButton() {
}
function BuildInfoModal({ closeModal }: { closeModal: () => void }) {
const { isAdmin } = useCurrentUser();
const { isAdmin } = useIsEdgeAdmin({ noEnvScope: true });
const versionQuery = useSystemVersion();
const statusQuery = useSystemStatus();

View file

@ -16,17 +16,19 @@ import { SidebarSection } from './SidebarSection';
import { SidebarParent } from './SidebarItem/SidebarParent';
interface Props {
isPureAdmin: boolean;
isAdmin: boolean;
isTeamLeader?: boolean;
}
export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
export function SettingsSidebar({ isPureAdmin, isAdmin, isTeamLeader }: Props) {
const teamSyncQuery = usePublicSettings<boolean>({
select: (settings) => settings.TeamSync,
});
const showUsersSection =
!window.ddExtension && (isAdmin || (isTeamLeader && !teamSyncQuery.data));
const isPureAdminOrTeamLeader =
isPureAdmin || (isTeamLeader && !teamSyncQuery.data && !isAdmin);
const showUsersSection = !window.ddExtension && isPureAdminOrTeamLeader;
return (
<SidebarSection title="Administration">
@ -51,7 +53,7 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
data-cy="portainerSidebar-teams"
/>
{isAdmin && (
{isPureAdmin && (
<SidebarItem
to="portainer.roles"
label="Roles"
@ -61,7 +63,7 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
)}
</SidebarParent>
)}
{isAdmin && (
{isPureAdmin && (
<>
<SidebarParent
label="Environment-related"
@ -74,7 +76,7 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
'portainer.tags',
],
}}
data-cy="k8sSidebar-networking"
data-cy="portainerSidebar-environments-area"
>
<SidebarItem
label="Environments"
@ -139,13 +141,24 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
</SidebarParent>
</>
)}
{isBE && !isPureAdmin && isAdmin && (
<SidebarParent
label="Environment-related"
icon={HardDrive}
to="portainer.endpoints.updateSchedules"
data-cy="portainerSidebar-environments-area"
>
<EdgeUpdatesSidebarItem />
</SidebarParent>
)}
<SidebarItem
to="portainer.notifications"
icon={Bell}
label="Notifications"
data-cy="portainerSidebar-notifications"
/>
{isAdmin && (
{isPureAdmin && (
<SidebarParent
to="portainer.settings"
label="Settings"
@ -158,6 +171,7 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
isSubMenu
ignorePaths={[
'portainer.settings.authentication',
'portainer.settings.sharedcredentials',
'portainer.settings.edgeCompute',
]}
data-cy="portainerSidebar-generalSettings"
@ -178,6 +192,7 @@ export function SettingsSidebar({ isAdmin, isTeamLeader }: Props) {
data-cy="portainerSidebar-cloud"
/>
)}
<SidebarItem
to="portainer.settings.edgeCompute"
label="Edge Compute"

View file

@ -1,8 +1,8 @@
import clsx from 'clsx';
import { Home } from 'lucide-react';
import { useUser } from '@/react/hooks/useUser';
import { useIsTeamLeader } from '@/portainer/users/queries';
import { useIsEdgeAdmin, useIsPureAdmin } from '@/react/hooks/useUser';
import { useIsCurrentUserTeamLeader } from '@/portainer/users/queries';
import { usePublicSettings } from '@/react/portainer/settings/queries';
import styles from './Sidebar.module.css';
@ -25,16 +25,19 @@ export function Sidebar() {
}
function InnerSidebar() {
const { isAdmin, user } = useUser();
const isTeamLeader = useIsTeamLeader(user) as boolean;
const isPureAdmin = useIsPureAdmin();
const isAdminQuery = useIsEdgeAdmin({ noEnvScope: true });
const isTeamLeader = useIsCurrentUserTeamLeader();
const { isOpen } = useSidebarState();
const settingsQuery = usePublicSettings();
if (!settingsQuery.data) {
if (!settingsQuery.data || isAdminQuery.isLoading) {
return null;
}
const { isAdmin } = isAdminQuery;
const { LogoURL } = settingsQuery.data;
return (
@ -66,7 +69,11 @@ function InnerSidebar() {
/>
<EnvironmentSidebar />
{isAdmin && <EdgeComputeSidebar />}
<SettingsSidebar isAdmin={isAdmin} isTeamLeader={isTeamLeader} />
<SettingsSidebar
isPureAdmin={isPureAdmin}
isAdmin={isAdmin}
isTeamLeader={isTeamLeader}
/>
</ul>
</div>
<div className="mt-auto pt-8">

View file

@ -29,7 +29,7 @@ const enabledPlatforms: Array<ContainerPlatform> = [
function UpgradeBEBanner() {
const {
isAdmin,
isPureAdmin,
user: { Id },
} = useCurrentUser();
@ -90,7 +90,7 @@ function UpgradeBEBanner() {
function handleClick() {
trackEvent(
isAdmin ? 'portainer-upgrade-admin' : 'portainer-upgrade-non-admin',
isPureAdmin ? 'portainer-upgrade-admin' : 'portainer-upgrade-non-admin',
{
category: 'portainer',
metadata,

View file

@ -1,6 +1,6 @@
import { useState } from 'react';
import { useUser } from '@/react/hooks/useUser';
import { useCurrentUser } from '@/react/hooks/useUser';
import { UploadLicenseDialog } from './UploadLicenseDialog';
import { LoadingDialog } from './LoadingDialog';
@ -10,7 +10,7 @@ import { GetLicenseDialog } from './GetLicenseDialog';
type Step = 'uploadLicense' | 'loading' | 'getLicense';
export function UpgradeDialog({ onDismiss }: { onDismiss: () => void }) {
const { isAdmin } = useUser();
const { isPureAdmin } = useCurrentUser();
const [currentStep, setCurrentStep] = useState<Step>('uploadLicense');
const [isGetLicenseSubmitted, setIsGetLicenseSubmitted] = useState(false);
const component = getDialog();
@ -18,7 +18,7 @@ export function UpgradeDialog({ onDismiss }: { onDismiss: () => void }) {
return component;
function getDialog() {
if (!isAdmin) {
if (!isPureAdmin) {
return <NonAdminUpgradeDialog onDismiss={onDismiss} />;
}