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)
}
if !securityContext.IsAdmin {
if !securityContext.IsAdmin && !securityContext.IsTeamLeader {
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)
if endpointID == 0 {
if securityContext.IsAdmin {
sanitizeUsers(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 {
// the users who have the endpoint authorization
if _, ok := user.EndpointAuthorizations[endpoint.ID]; ok {
if securityContext.IsAdmin {
sanitizeUser(&user)
}
canAccessEndpoint = append(canAccessEndpoint, user)
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 securityContext.IsAdmin {
sanitizeUser(&user)
}
canAccessEndpoint = append(canAccessEndpoint, user)
}
}
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 { useTeams } from '@/react/portainer/users/teams/queries';
import { useUsers } from '@/portainer/users/queries';
import { useCurrentUser } from '@/react/hooks/useUser';
import { pluralize } from '@/portainer/helpers/strings';
import { Link } from '@@/Link';
@ -31,8 +30,6 @@ export function AccessControlPanelDetails({
resourceControl,
resourceType,
}: Props) {
const { isAdmin } = useCurrentUser();
const inheritanceMessage = getInheritanceMessage(
resourceType,
resourceControl
@ -44,10 +41,7 @@ export function AccessControlPanelDetails({
TeamAccesses: restrictedToTeams = [],
} = resourceControl || {};
const users = useAuthorizedUsers(
restrictedToUsers.map((ra) => ra.UserId),
isAdmin
);
const users = useAuthorizedUsers(restrictedToUsers.map((ra) => ra.UserId));
const teams = useAuthorizedTeams(restrictedToTeams.map((ra) => ra.TeamId));
const teamsLength = teams.data ? teams.data.length : 0;
@ -62,8 +56,8 @@ export function AccessControlPanelDetails({
)} you are not part of`;
}
const userMessage = isAdmin
? (users.data && users.data.join(', ')) || ''
const userMessage = users.data
? users.data.join(', ')
: `${restrictedToUsers.length} ${pluralize(
restrictedToUsers.length,
'user'

View File

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