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

feat(auth): add useIsEdgeAdmin hook [EE-6627] (#11057)
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:1809]) (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:ltsc2022]) (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:20 +02:00 committed by GitHub
parent 7a6c872948
commit 31f5b42962
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 389 additions and 198 deletions

View file

@ -64,7 +64,7 @@ angular.module('portainer.app').controller('porAccessControlFormController', [
this.$onInit = $onInit;
function $onInit() {
var isAdmin = Authentication.isAdmin();
var isAdmin = Authentication.isPureAdmin();
ctrl.isAdmin = isAdmin;
if (isAdmin) {

View file

@ -1,4 +1,5 @@
import { getCurrentUser } from '../users/queries/useLoadCurrentUser';
import * as userHelpers from '../users/user.helpers';
import { clear as clearSessionStorage } from './session-storage';
const DEFAULT_USER = 'admin';
@ -25,6 +26,9 @@ angular.module('portainer.app').factory('Authentication', [
service.isAuthenticated = isAuthenticated;
service.getUserDetails = getUserDetails;
service.isAdmin = isAdmin;
service.isEdgeAdmin = isEdgeAdmin;
service.isPureAdmin = isPureAdmin;
service.hasAuthorizations = hasAuthorizations;
async function initAsync() {
try {
@ -120,8 +124,36 @@ angular.module('portainer.app').factory('Authentication', [
return login(DEFAULT_USER, DEFAULT_PASSWORD);
}
// To avoid creating divergence between CE and EE
// isAdmin checks if the user is a portainer admin or edge admin
function isEdgeAdmin() {
const environment = EndpointProvider.currentEndpoint();
return userHelpers.isEdgeAdmin({ Role: user.role }, environment);
}
/**
* @deprecated use Authentication.isAdmin instead
*/
function isAdmin() {
return !!user && user.role === 1;
return isEdgeAdmin();
}
// To avoid creating divergence between CE and EE
// isPureAdmin checks if the user is portainer admin only
function isPureAdmin() {
return userHelpers.isPureAdmin({ Role: user.role });
}
function hasAuthorizations(authorizations) {
const endpointId = EndpointProvider.endpointID();
if (isAdmin()) {
return true;
}
if (!user.endpointAuthorizations || !user.endpointAuthorizations[endpointId]) {
return false;
}
const userEndpointAuthorizations = user.endpointAuthorizations[endpointId];
return authorizations.some((authorization) => userEndpointAuthorizations[authorization]);
}
if (process.env.NODE_ENV === 'development') {

View file

@ -1,9 +1,9 @@
import { useQuery } from 'react-query';
import { TeamRole, TeamMembership } from '@/react/portainer/users/teams/types';
import { useCurrentUser, useIsEdgeAdmin } from '@/react/hooks/useUser';
import { User, UserId } from './types';
import { isAdmin } from './user.helpers';
import { getUserMemberships, getUsers } from './user.service';
interface UseUserMembershipOptions<TSelect> {
@ -22,14 +22,21 @@ export function useUserMembership<TSelect = TeamMembership[]>(
);
}
export function useIsTeamLeader(user: User) {
export function useIsCurrentUserTeamLeader() {
const { user } = useCurrentUser();
const isAdminQuery = useIsEdgeAdmin();
const query = useUserMembership(user.Id, {
enabled: !isAdmin(user),
enabled: !isAdminQuery.isLoading && !isAdminQuery.isAdmin,
select: (memberships) =>
memberships.some((membership) => membership.Role === TeamRole.Leader),
});
return isAdmin(user) ? true : query.data;
if (isAdminQuery.isLoading) {
return false;
}
return isAdminQuery.isAdmin ? true : !!query.data;
}
export function useUsers<T = User[]>(

View file

@ -7,6 +7,7 @@ export { type UserId };
export enum Role {
Admin = 1,
Standard,
EdgeAdmin,
}
interface AuthorizationMap {

View file

@ -1,9 +1,30 @@
import { Environment } from '@/react/portainer/environments/types';
import { isEdgeEnvironment } from '@/react/portainer/environments/utils';
import { Role, User } from './types';
export function filterNonAdministratorUsers(users: User[]) {
return users.filter((user) => user.Role !== Role.Admin);
}
export function isAdmin(user?: User): boolean {
return !!user && user.Role === 1;
type UserLike = Pick<User, 'Role'>;
// To avoid creating divergence between CE and EE
// isAdmin checks if the user is portainer admin or edge admin
export function isEdgeAdmin(
user: UserLike | undefined,
environment?: Pick<Environment, 'Type'> | null
): boolean {
return (
isPureAdmin(user) ||
(user?.Role === Role.EdgeAdmin &&
(!environment || isEdgeEnvironment(environment.Type)))
);
}
// To avoid creating divergence between CE and EE
// isPureAdmin checks only if the user is portainer admin
// See bouncer.IsAdmin and bouncer.PureAdminAccess
export function isPureAdmin(user?: UserLike): boolean {
return !!user && user.Role === Role.Admin;
}