mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +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
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:
parent
c08b5af85a
commit
edea9e3481
48 changed files with 389 additions and 198 deletions
|
@ -10,7 +10,7 @@ import { Values } from './BaseForm';
|
|||
|
||||
export function toViewModel(
|
||||
config: ContainerResponse,
|
||||
isAdmin: boolean,
|
||||
isPureAdmin: boolean,
|
||||
currentUserId: UserId,
|
||||
nodeName: string,
|
||||
image: Values['image'],
|
||||
|
@ -18,7 +18,7 @@ export function toViewModel(
|
|||
): Values {
|
||||
// accessControl shouldn't be copied to new container
|
||||
|
||||
const accessControl = parseAccessControlFormData(isAdmin, currentUserId);
|
||||
const accessControl = parseAccessControlFormData(isPureAdmin, currentUserId);
|
||||
|
||||
if (config.Portainer?.ResourceControl?.Public) {
|
||||
accessControl.ownership = ResourceControlOwnership.PUBLIC;
|
||||
|
@ -38,11 +38,11 @@ export function toViewModel(
|
|||
}
|
||||
|
||||
export function getDefaultViewModel(
|
||||
isAdmin: boolean,
|
||||
isPureAdmin: boolean,
|
||||
currentUserId: UserId,
|
||||
nodeName: string
|
||||
): Values {
|
||||
const accessControl = parseAccessControlFormData(isAdmin, currentUserId);
|
||||
const accessControl = parseAccessControlFormData(isPureAdmin, currentUserId);
|
||||
|
||||
return {
|
||||
nodeName,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Formik } from 'formik';
|
|||
import { useRouter } from '@uirouter/react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useCurrentUser, useIsEnvironmentAdmin } from '@/react/hooks/useUser';
|
||||
import { useIsEdgeAdmin, useIsEnvironmentAdmin } from '@/react/hooks/useUser';
|
||||
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
|
||||
import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
|
||||
import { useEnvironmentRegistries } from '@/react/portainer/environments/queries/useEnvironmentRegistries';
|
||||
|
@ -48,7 +48,7 @@ function CreateForm() {
|
|||
const environmentId = useEnvironmentId();
|
||||
const router = useRouter();
|
||||
const { trackEvent } = useAnalytics();
|
||||
const { isAdmin } = useCurrentUser();
|
||||
const isAdminQuery = useIsEdgeAdmin();
|
||||
const isEnvironmentAdmin = useIsEnvironmentAdmin();
|
||||
const [isDockerhubRateLimited, setIsDockerhubRateLimited] = useState(false);
|
||||
|
||||
|
@ -67,7 +67,7 @@ function CreateForm() {
|
|||
const envQuery = useCurrentEnvironment();
|
||||
|
||||
const validationSchema = useValidation({
|
||||
isAdmin,
|
||||
isAdmin: isAdminQuery.isAdmin,
|
||||
maxCpu,
|
||||
maxMemory,
|
||||
isDuplicating: initialValuesQuery?.isDuplicating,
|
||||
|
|
|
@ -102,7 +102,7 @@ export function InnerForm({
|
|||
}
|
||||
errors={errors.volumes}
|
||||
allowBindMounts={
|
||||
isEnvironmentAdmin ||
|
||||
isEnvironmentAdmin.authorized ||
|
||||
environment.SecuritySettings
|
||||
.allowBindMountsForRegularUsers
|
||||
}
|
||||
|
@ -166,18 +166,18 @@ export function InnerForm({
|
|||
setFieldValue(`resources.${field}`, value)
|
||||
}
|
||||
allowPrivilegedMode={
|
||||
isEnvironmentAdmin ||
|
||||
isEnvironmentAdmin.authorized ||
|
||||
environment.SecuritySettings
|
||||
.allowPrivilegedModeForRegularUsers
|
||||
}
|
||||
isDevicesFieldVisible={
|
||||
isEnvironmentAdmin ||
|
||||
isEnvironmentAdmin.authorized ||
|
||||
environment.SecuritySettings
|
||||
.allowDeviceMappingForRegularUsers
|
||||
}
|
||||
isInitFieldVisible={apiVersion >= 1.37}
|
||||
isSysctlFieldVisible={
|
||||
isEnvironmentAdmin ||
|
||||
isEnvironmentAdmin.authorized ||
|
||||
environment.SecuritySettings
|
||||
.allowSysctlSettingForRegularUsers
|
||||
}
|
||||
|
|
|
@ -62,7 +62,8 @@ export function useInitialValues(submitting: boolean) {
|
|||
params: { nodeName, from },
|
||||
} = useCurrentStateAndParams();
|
||||
const environmentId = useEnvironmentId();
|
||||
const { isAdmin, user } = useCurrentUser();
|
||||
const { user, isPureAdmin } = useCurrentUser();
|
||||
|
||||
const networksQuery = useNetworksForSelector();
|
||||
|
||||
const fromContainerQuery = useContainer(environmentId, from, {
|
||||
|
@ -85,7 +86,7 @@ export function useInitialValues(submitting: boolean) {
|
|||
|
||||
if (!from) {
|
||||
return {
|
||||
initialValues: defaultValues(isAdmin, user.Id, nodeName),
|
||||
initialValues: defaultValues(isPureAdmin, user.Id, nodeName),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -136,7 +137,7 @@ export function useInitialValues(submitting: boolean) {
|
|||
env: envVarsTabUtils.toViewModel(fromContainer),
|
||||
...baseFormUtils.toViewModel(
|
||||
fromContainer,
|
||||
isAdmin,
|
||||
isPureAdmin,
|
||||
user.Id,
|
||||
nodeName,
|
||||
imageConfig,
|
||||
|
@ -148,7 +149,7 @@ export function useInitialValues(submitting: boolean) {
|
|||
}
|
||||
|
||||
function defaultValues(
|
||||
isAdmin: boolean,
|
||||
isPureAdmin: boolean,
|
||||
currentUserId: UserId,
|
||||
nodeName: string
|
||||
): Values {
|
||||
|
@ -161,6 +162,6 @@ function defaultValues(
|
|||
resources: resourcesTabUtils.getDefaultViewModel(),
|
||||
capabilities: capabilitiesTabUtils.getDefaultViewModel(),
|
||||
env: envVarsTabUtils.getDefaultViewModel(),
|
||||
...baseFormUtils.getDefaultViewModel(isAdmin, currentUserId, nodeName),
|
||||
...baseFormUtils.getDefaultViewModel(isPureAdmin, currentUserId, nodeName),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
|
||||
|
@ -50,7 +50,7 @@ test('Non system networks should have a delete button', async () => {
|
|||
async function renderComponent(isAdmin: boolean, network: DockerNetwork) {
|
||||
const user = new UserViewModel({ Username: 'test', Role: isAdmin ? 1 : 2 });
|
||||
|
||||
const queries = render(
|
||||
const queries = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<NetworkDetailsTable
|
||||
network={network}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Layers } from 'lucide-react';
|
||||
import { Row } from '@tanstack/react-table';
|
||||
|
||||
import { useAuthorizations, useCurrentUser } from '@/react/hooks/useUser';
|
||||
import { useAuthorizations, useIsEdgeAdmin } from '@/react/hooks/useUser';
|
||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
||||
|
||||
import { Datatable } from '@@/datatables';
|
||||
|
@ -34,7 +34,7 @@ export function StacksDatatable({
|
|||
}) {
|
||||
const tableState = useTableState(settingsStore, tableKey);
|
||||
useRepeater(tableState.autoRefreshRate, onReload);
|
||||
const { isAdmin } = useCurrentUser();
|
||||
const isAdminQuery = useIsEdgeAdmin();
|
||||
const canManageStacks = useAuthorizations([
|
||||
'PortainerStackCreate',
|
||||
'PortainerStackDelete',
|
||||
|
@ -58,7 +58,7 @@ export function StacksDatatable({
|
|||
columns={columns}
|
||||
dataset={dataset}
|
||||
isRowSelectable={({ original: item }) =>
|
||||
allowSelection(item, isAdmin, canManageStacks)
|
||||
allowSelection(item, isAdminQuery.isAdmin, canManageStacks.authorized)
|
||||
}
|
||||
getRowId={(item) => item.Id.toString()}
|
||||
initialTableState={{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { CellContext, Column } from '@tanstack/react-table';
|
||||
|
||||
import { useCurrentUser } from '@/react/hooks/useUser';
|
||||
import { useIsEdgeAdmin } from '@/react/hooks/useUser';
|
||||
import { getValueAsArrayOfStrings } from '@/portainer/helpers/array';
|
||||
import { StackStatus } from '@/react/common/stacks/types';
|
||||
import {
|
||||
|
@ -67,7 +67,7 @@ function NameCell({
|
|||
}
|
||||
|
||||
function NameLink({ item }: { item: DecoratedStack }) {
|
||||
const { isAdmin } = useCurrentUser();
|
||||
const isAdminQuery = useIsEdgeAdmin();
|
||||
|
||||
const name = item.Name;
|
||||
|
||||
|
@ -87,7 +87,7 @@ function NameLink({ item }: { item: DecoratedStack }) {
|
|||
);
|
||||
}
|
||||
|
||||
if (!isAdmin && isOrphanedStack(item)) {
|
||||
if (!isAdminQuery.isAdmin && isOrphanedStack(item)) {
|
||||
return <>{name}</>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue