mirror of
https://github.com/rancher/steve.git
synced 2025-09-17 07:48:52 +00:00
Add a few unit tests
This commit is contained in:
@@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/rancher/steve/pkg/attributes"
|
"github.com/rancher/steve/pkg/attributes"
|
||||||
"github.com/rancher/steve/pkg/resources/virtual/common"
|
"github.com/rancher/steve/pkg/resources/virtual/common"
|
||||||
"github.com/rancher/steve/pkg/schema"
|
"github.com/rancher/steve/pkg/schema"
|
||||||
metricsStore "githu
|
|
||||||
metricsStore "github.com/rancher/steve/pkg/stores/metrics"
|
metricsStore "github.com/rancher/steve/pkg/stores/metrics"
|
||||||
"github.com/rancher/steve/pkg/stores/proxy"
|
"github.com/rancher/steve/pkg/stores/proxy"
|
||||||
"github.com/rancher/steve/pkg/summarycache"
|
"github.com/rancher/steve/pkg/summarycache"
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rancher/apiserver/pkg/types"
|
"github.com/rancher/apiserver/pkg/types"
|
||||||
@@ -12,7 +13,9 @@ import (
|
|||||||
"github.com/rancher/steve/pkg/accesscontrol"
|
"github.com/rancher/steve/pkg/accesscontrol"
|
||||||
"github.com/rancher/steve/pkg/accesscontrol/fake"
|
"github.com/rancher/steve/pkg/accesscontrol/fake"
|
||||||
"github.com/rancher/steve/pkg/attributes"
|
"github.com/rancher/steve/pkg/attributes"
|
||||||
|
"github.com/rancher/steve/pkg/resources/virtual/common"
|
||||||
"github.com/rancher/wrangler/v3/pkg/schemas"
|
"github.com/rancher/wrangler/v3/pkg/schemas"
|
||||||
|
"github.com/rancher/wrangler/v3/pkg/summary"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
@@ -1072,3 +1075,220 @@ func Test_formatterLinks(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFormatterAddsResourcePermissions(t *testing.T) {
|
||||||
|
const (
|
||||||
|
clusterid = "clusterid"
|
||||||
|
projectid = "projectid"
|
||||||
|
)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
topLevelPermissions []string
|
||||||
|
resourcePermissions map[string][]string
|
||||||
|
schema *types.APISchema
|
||||||
|
apiObject types.APIObject
|
||||||
|
want map[string]map[string]bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "get update patch on project and get on projectroletemplatebindings",
|
||||||
|
topLevelPermissions: []string{"get", "update", "patch"},
|
||||||
|
resourcePermissions: map[string][]string{
|
||||||
|
"projectroletemplatebindings": {"get", "list", "watch"},
|
||||||
|
},
|
||||||
|
schema: &types.APISchema{
|
||||||
|
Schema: &schemas.Schema{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Attributes: map[string]interface{}{
|
||||||
|
"group": "management.cattle.io",
|
||||||
|
"version": "v1",
|
||||||
|
"resource": "projects",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apiObject: types.APIObject{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Object: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: map[string]map[string]bool{
|
||||||
|
"projectroletemplatebindings": {
|
||||||
|
"get": true,
|
||||||
|
"list": true,
|
||||||
|
"watch": true,
|
||||||
|
"create": false,
|
||||||
|
"delete": false,
|
||||||
|
"patch": false,
|
||||||
|
"update": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get update patch on project and get on projectroletemplatebindings and pods",
|
||||||
|
topLevelPermissions: []string{"get", "update", "patch"},
|
||||||
|
resourcePermissions: map[string][]string{
|
||||||
|
"projectroletemplatebindings": {"get", "list", "watch"},
|
||||||
|
"pods": {"get", "list", "watch"},
|
||||||
|
},
|
||||||
|
schema: &types.APISchema{
|
||||||
|
Schema: &schemas.Schema{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Attributes: map[string]interface{}{
|
||||||
|
"group": "management.cattle.io",
|
||||||
|
"version": "v1",
|
||||||
|
"resource": "projects",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apiObject: types.APIObject{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Object: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: map[string]map[string]bool{
|
||||||
|
"projectroletemplatebindings": {
|
||||||
|
"get": true,
|
||||||
|
"list": true,
|
||||||
|
"watch": true,
|
||||||
|
"create": false,
|
||||||
|
"delete": false,
|
||||||
|
"patch": false,
|
||||||
|
"update": false,
|
||||||
|
},
|
||||||
|
"pods": {
|
||||||
|
"get": true,
|
||||||
|
"list": true,
|
||||||
|
"watch": true,
|
||||||
|
"create": false,
|
||||||
|
"delete": false,
|
||||||
|
"patch": false,
|
||||||
|
"update": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get update remove on project and a checkPermissions on an unknown resource",
|
||||||
|
topLevelPermissions: []string{"get", "update", "patch"},
|
||||||
|
resourcePermissions: map[string][]string{},
|
||||||
|
schema: &types.APISchema{
|
||||||
|
Schema: &schemas.Schema{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Attributes: map[string]interface{}{
|
||||||
|
"group": "management.cattle.io",
|
||||||
|
"version": "v1",
|
||||||
|
"resource": "projects",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apiObject: types.APIObject{
|
||||||
|
ID: clusterid + "/" + projectid,
|
||||||
|
Object: &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: map[string]map[string]bool{
|
||||||
|
"unknown": {
|
||||||
|
"get": false,
|
||||||
|
"list": false,
|
||||||
|
"watch": false,
|
||||||
|
"create": false,
|
||||||
|
"delete": false,
|
||||||
|
"patch": false,
|
||||||
|
"update": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
defaultUserInfo := user.DefaultInfo{}
|
||||||
|
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
asl := fake.NewMockAccessSetLookup(ctrl)
|
||||||
|
accessSet := accesscontrol.AccessSet{}
|
||||||
|
|
||||||
|
// Se up the AccessSet for the top level resource
|
||||||
|
if len(test.topLevelPermissions) > 0 {
|
||||||
|
gvr := attributes.GVR(test.schema)
|
||||||
|
objMeta, _ := meta.Accessor(test.apiObject.Object)
|
||||||
|
resource := accesscontrol.Access{
|
||||||
|
Namespace: objMeta.GetNamespace(),
|
||||||
|
ResourceName: objMeta.GetName(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, verb := range test.topLevelPermissions {
|
||||||
|
accessSet.Add(verb, gvr.GroupResource(), resource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se up the AccessSet for the top nested resources
|
||||||
|
for resource, verbs := range test.resourcePermissions {
|
||||||
|
gvr := schema2.GroupVersionResource{
|
||||||
|
Group: "management.cattle.io",
|
||||||
|
Version: "v1",
|
||||||
|
Resource: resource,
|
||||||
|
}
|
||||||
|
for _, verb := range verbs {
|
||||||
|
accessSet.Add(verb, gvr.GroupResource(), accesscontrol.Access{
|
||||||
|
Namespace: projectid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx = request.WithUser(ctx, &defaultUserInfo)
|
||||||
|
httpRequest, _ := http.NewRequestWithContext(ctx, "", "", bytes.NewBuffer([]byte{}))
|
||||||
|
|
||||||
|
var checkPerms []string
|
||||||
|
for res := range test.want {
|
||||||
|
checkPerms = append(checkPerms, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &types.APIRequest{
|
||||||
|
Request: httpRequest,
|
||||||
|
URLBuilder: &urlbuilder.DefaultURLBuilder{},
|
||||||
|
Query: url.Values{
|
||||||
|
"checkPermissions": {strings.Join(checkPerms, ",")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resource := &types.RawResource{
|
||||||
|
Schema: test.schema,
|
||||||
|
APIObject: test.apiObject,
|
||||||
|
Links: map[string]string{},
|
||||||
|
}
|
||||||
|
fakeCache := &common.FakeSummaryCache{
|
||||||
|
SummarizedObject: &summary.SummarizedObject{},
|
||||||
|
}
|
||||||
|
|
||||||
|
asl.EXPECT().AccessFor(&defaultUserInfo).Return(&accessSet).AnyTimes()
|
||||||
|
|
||||||
|
formatter := formatter(fakeCache, asl)
|
||||||
|
formatter(req, resource)
|
||||||
|
|
||||||
|
// Extract the resultant resourcePermissions
|
||||||
|
u, ok := resource.APIObject.Object.(*unstructured.Unstructured)
|
||||||
|
require.True(t, ok, "APIObject.Object is not Unstructured")
|
||||||
|
|
||||||
|
rawPerms, ok := u.Object["resourcePermissions"]
|
||||||
|
require.True(t, ok, "resourcePermissions field missing")
|
||||||
|
|
||||||
|
permMap, ok := rawPerms.(map[string]map[string]bool)
|
||||||
|
require.True(t, ok, "resourcePermissions is not map[string]map[string]bool")
|
||||||
|
|
||||||
|
got := map[string]map[string]bool{}
|
||||||
|
for res, actionMap := range permMap {
|
||||||
|
got[res] = map[string]bool{}
|
||||||
|
for action, boolVal := range actionMap {
|
||||||
|
got[res][action] = boolVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, test.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user