mirror of
https://github.com/portainer/portainer.git
synced 2026-06-23 06:50:12 +00:00
173 lines
6.0 KiB
Go
173 lines
6.0 KiB
Go
package uac
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
portainer "github.com/portainer/portainer/api"
|
|
"github.com/portainer/portainer/api/dataservices"
|
|
"github.com/portainer/portainer/api/datastore"
|
|
"github.com/portainer/portainer/api/docker/consts"
|
|
"github.com/portainer/portainer/api/internal/authorization"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGenericResourcControlGetter(t *testing.T) {
|
|
t.Parallel()
|
|
is := require.New(t)
|
|
|
|
ok, store := datastore.MustNewTestStore(t, true, false)
|
|
is.True(ok)
|
|
is.NotNil(store)
|
|
|
|
endpointID := portainer.EndpointID(1)
|
|
composeStackName := "compose-stack"
|
|
composeStackRCID := StackResourceControlID(endpointID, composeStackName)
|
|
swarmStackName := "swarm-stack"
|
|
swarmStackRCID := StackResourceControlID(endpointID, swarmStackName)
|
|
serviceID := "service"
|
|
|
|
err := store.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
|
// created on container create
|
|
is.NoError(tx.ResourceControl().Create(authorization.NewPublicResourceControl("container", portainer.ContainerResourceControl)))
|
|
// created on compose stack create
|
|
is.NoError(tx.ResourceControl().Create(authorization.NewPublicResourceControl(composeStackRCID, portainer.StackResourceControl)))
|
|
// created on swarm stack create
|
|
is.NoError(tx.ResourceControl().Create(authorization.NewPublicResourceControl(swarmStackRCID, portainer.StackResourceControl)))
|
|
// created a swarm service create
|
|
is.NoError(tx.ResourceControl().Create(authorization.NewPublicResourceControl(serviceID, portainer.ServiceResourceControl)))
|
|
return nil
|
|
})
|
|
is.NoError(err)
|
|
|
|
err = store.ViewTx(func(tx dataservices.DataStoreTx) error {
|
|
context := ResourceContext[container.Summary]{RCType: portainer.ContainerResourceControl, IDGetter: ContainerResourceControlID, LabelsGetter: ContainerLabels}
|
|
|
|
// trying to get UAC for a container created through Portainer
|
|
rc, err := genericResourcControlGetter(tx, 1, context)(container.Summary{ID: "container"})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
|
|
// trying to get UAC for an external container
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{ID: "unknown"})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
// trying to get UAC for a container from a compose stack
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{ID: "by-compose-stack-name-label", Labels: map[string]string{consts.ComposeStackNameLabel: composeStackName}})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Equal(composeStackRCID, rc.ResourceID)
|
|
|
|
// trying to get UAC for a container from a swarm stack
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{ID: "by-swarm-stack-name-label", Labels: map[string]string{consts.SwarmStackNameLabel: swarmStackName}})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Equal(swarmStackRCID, rc.ResourceID)
|
|
|
|
// trying to get UAC for a container from a swarm service
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{ID: "by-swarm-service-id-label", Labels: map[string]string{consts.SwarmServiceIDLabel: serviceID}})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Equal(serviceID, rc.ResourceID)
|
|
|
|
return nil
|
|
})
|
|
|
|
is.NoError(err)
|
|
|
|
}
|
|
|
|
func TestGenericResourcControlGetterWithPortainerLabels(t *testing.T) {
|
|
t.Parallel()
|
|
is := require.New(t)
|
|
|
|
ok, store := datastore.MustNewTestStore(t, true, false)
|
|
is.True(ok)
|
|
is.NotNil(store)
|
|
|
|
is.NoError(store.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
|
is.NoError(tx.User().Create(&portainer.User{Role: portainer.AdministratorRole, Username: "admin"}))
|
|
is.NoError(tx.User().Create(&portainer.User{Role: portainer.AdministratorRole, Username: "user"}))
|
|
is.NoError(tx.Team().Create(&portainer.Team{Name: "team"}))
|
|
is.NoError(tx.TeamMembership().Create(&portainer.TeamMembership{UserID: 2, TeamID: 1}))
|
|
return nil
|
|
}))
|
|
|
|
is.NoError(store.ViewTx(func(tx dataservices.DataStoreTx) error {
|
|
context := ResourceContext[container.Summary]{RCType: portainer.ContainerResourceControl, IDGetter: ContainerResourceControlID, LabelsGetter: ContainerLabels}
|
|
|
|
rc, err := genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "public",
|
|
Labels: map[string]string{publicRCLabel: "true"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.True(rc.Public)
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "team",
|
|
Labels: map[string]string{teamRCLabel: "team"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Contains(rc.TeamAccesses, portainer.TeamResourceAccess{TeamID: 1, AccessLevel: portainer.ReadWriteAccessLevel})
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "no-team",
|
|
Labels: map[string]string{teamRCLabel: "team2"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "user",
|
|
Labels: map[string]string{userRCLabel: "user"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Contains(rc.UserAccesses, portainer.UserResourceAccess{UserID: 2, AccessLevel: portainer.ReadWriteAccessLevel})
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "no-user",
|
|
Labels: map[string]string{userRCLabel: "user2"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "warn-on-unknown",
|
|
Labels: map[string]string{userRCLabel: "user2,user3", teamRCLabel: "team2,team3"},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "empty-when-no-label",
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
rc, err = genericResourcControlGetter(tx, 1, context)(container.Summary{
|
|
ID: "empty-when-empty-labels",
|
|
Labels: map[string]string{},
|
|
})
|
|
is.NoError(err)
|
|
is.NotNil(rc)
|
|
is.Empty(rc.UserAccesses)
|
|
is.Empty(rc.TeamAccesses)
|
|
|
|
return nil
|
|
}))
|
|
}
|