mirror of
https://github.com/portainer/portainer.git
synced 2026-06-23 06:40:13 +00:00
54 lines
1.4 KiB
Go
54 lines
1.4 KiB
Go
package uac
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
"github.com/portainer/portainer/api/internal/authorization"
|
|
"github.com/portainer/portainer/api/slicesx"
|
|
)
|
|
|
|
// FilterByResourceControl filters a list of items based on the user's role and the resource control associated to the item.
|
|
// UAC rules
|
|
// * UAC in DB (direct)
|
|
// * UAC inherited (from swarm service | swarm stack | compose stack)
|
|
// * UAC defined in labels (UAC on external resources)
|
|
func FilterByResourceControl[T any](
|
|
items []T,
|
|
user *portainer.User,
|
|
userMemberships []portainer.TeamMembership,
|
|
resourceControlGetter func(item T) (*portainer.ResourceControl, error),
|
|
) ([]T, error) {
|
|
filteredItems := make([]T, 0)
|
|
|
|
if user == nil {
|
|
return filteredItems, nil
|
|
}
|
|
|
|
if canBypassUAC(user) {
|
|
return items, nil
|
|
}
|
|
|
|
userTeamIDs := slicesx.Map(userMemberships, func(membership portainer.TeamMembership) portainer.TeamID {
|
|
return membership.TeamID
|
|
})
|
|
|
|
for _, item := range items {
|
|
rc, err := resourceControlGetter(item)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Unable to retrieve resource control: %w", err)
|
|
}
|
|
|
|
// TODO: move UserCanAccessResource function to the UAC package
|
|
if authorization.UserCanAccessResource(user.ID, userTeamIDs, rc) {
|
|
filteredItems = append(filteredItems, item)
|
|
}
|
|
}
|
|
|
|
return filteredItems, nil
|
|
}
|
|
|
|
func canBypassUAC(user *portainer.User) bool {
|
|
return user != nil && user.Role == portainer.AdministratorRole
|
|
}
|