fix(permissions): non admin access to view users [EE-5825] (#10352)

* fix non admin access to view users

* review comments and fix tests
pull/10372/head
Prabhat Khera 2023-09-25 09:08:26 +13:00 committed by GitHub
parent 13c48ab961
commit 3c4660bbf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 11 deletions

View File

@ -31,7 +31,7 @@ func (handler *Handler) userList(w http.ResponseWriter, r *http.Request) *httper
return httperror.InternalServerError("Unable to retrieve info from request context", err) return httperror.InternalServerError("Unable to retrieve info from request context", err)
} }
if !securityContext.IsAdmin { if !securityContext.IsAdmin && !securityContext.IsTeamLeader {
return httperror.Forbidden("Permission denied to access users list", err) return httperror.Forbidden("Permission denied to access users list", err)
} }
@ -42,6 +42,9 @@ func (handler *Handler) userList(w http.ResponseWriter, r *http.Request) *httper
endpointID, _ := request.RetrieveNumericQueryParameter(r, "environmentId", true) endpointID, _ := request.RetrieveNumericQueryParameter(r, "environmentId", true)
if endpointID == 0 { if endpointID == 0 {
if securityContext.IsAdmin {
sanitizeUsers(users)
}
return response.JSON(w, users) return response.JSON(w, users)
} }
@ -60,6 +63,9 @@ func (handler *Handler) userList(w http.ResponseWriter, r *http.Request) *httper
for _, user := range users { for _, user := range users {
// the users who have the endpoint authorization // the users who have the endpoint authorization
if _, ok := user.EndpointAuthorizations[endpoint.ID]; ok { if _, ok := user.EndpointAuthorizations[endpoint.ID]; ok {
if securityContext.IsAdmin {
sanitizeUser(&user)
}
canAccessEndpoint = append(canAccessEndpoint, user) canAccessEndpoint = append(canAccessEndpoint, user)
continue continue
} }
@ -71,9 +77,27 @@ func (handler *Handler) userList(w http.ResponseWriter, r *http.Request) *httper
} }
if security.AuthorizedEndpointAccess(endpoint, endpointGroup, user.ID, teamMemberships) { if security.AuthorizedEndpointAccess(endpoint, endpointGroup, user.ID, teamMemberships) {
if securityContext.IsAdmin {
sanitizeUser(&user)
}
canAccessEndpoint = append(canAccessEndpoint, user) canAccessEndpoint = append(canAccessEndpoint, user)
} }
} }
return response.JSON(w, canAccessEndpoint) return response.JSON(w, canAccessEndpoint)
} }
func sanitizeUser(user *portainer.User) {
user.Password = ""
user.EndpointAuthorizations = nil
user.ThemeSettings = portainer.UserThemeSettings{}
user.PortainerAuthorizations = nil
user.UserTheme = ""
user.TokenIssueAt = 0
}
func sanitizeUsers(users []portainer.User) {
for i := range users {
sanitizeUser(&users[i])
}
}

View File

@ -8,7 +8,6 @@ import { UserId } from '@/portainer/users/types';
import { TeamId } from '@/react/portainer/users/teams/types'; import { TeamId } from '@/react/portainer/users/teams/types';
import { useTeams } from '@/react/portainer/users/teams/queries'; import { useTeams } from '@/react/portainer/users/teams/queries';
import { useUsers } from '@/portainer/users/queries'; import { useUsers } from '@/portainer/users/queries';
import { useCurrentUser } from '@/react/hooks/useUser';
import { pluralize } from '@/portainer/helpers/strings'; import { pluralize } from '@/portainer/helpers/strings';
import { Link } from '@@/Link'; import { Link } from '@@/Link';
@ -31,8 +30,6 @@ export function AccessControlPanelDetails({
resourceControl, resourceControl,
resourceType, resourceType,
}: Props) { }: Props) {
const { isAdmin } = useCurrentUser();
const inheritanceMessage = getInheritanceMessage( const inheritanceMessage = getInheritanceMessage(
resourceType, resourceType,
resourceControl resourceControl
@ -44,10 +41,7 @@ export function AccessControlPanelDetails({
TeamAccesses: restrictedToTeams = [], TeamAccesses: restrictedToTeams = [],
} = resourceControl || {}; } = resourceControl || {};
const users = useAuthorizedUsers( const users = useAuthorizedUsers(restrictedToUsers.map((ra) => ra.UserId));
restrictedToUsers.map((ra) => ra.UserId),
isAdmin
);
const teams = useAuthorizedTeams(restrictedToTeams.map((ra) => ra.TeamId)); const teams = useAuthorizedTeams(restrictedToTeams.map((ra) => ra.TeamId));
const teamsLength = teams.data ? teams.data.length : 0; const teamsLength = teams.data ? teams.data.length : 0;
@ -62,8 +56,8 @@ export function AccessControlPanelDetails({
)} you are not part of`; )} you are not part of`;
} }
const userMessage = isAdmin const userMessage = users.data
? (users.data && users.data.join(', ')) || '' ? users.data.join(', ')
: `${restrictedToUsers.length} ${pluralize( : `${restrictedToUsers.length} ${pluralize(
restrictedToUsers.length, restrictedToUsers.length,
'user' 'user'

View File

@ -18,7 +18,7 @@ export function ListView() {
<> <>
<PageHeader title="Teams" breadcrumbs={[{ label: 'Teams management' }]} /> <PageHeader title="Teams" breadcrumbs={[{ label: 'Teams management' }]} />
{usersQuery.data && teamsQuery.data && ( {isAdmin && usersQuery.data && teamsQuery.data && (
<CreateTeamForm users={usersQuery.data} teams={teamsQuery.data} /> <CreateTeamForm users={usersQuery.data} teams={teamsQuery.data} />
)} )}