From 1c7948d4c9b96505135f153c22712cd3e83a92d7 Mon Sep 17 00:00:00 2001 From: Sakala Venkata Krishna Rohit Date: Fri, 18 Jul 2025 15:36:53 -0700 Subject: [PATCH] Revert "Revert "Make view link related to GET RBAC permission. (#699)" (#703)" (#704) This reverts commit 8cd7bd0a8f4832efdd7672e416c0b382b030a35a. --- pkg/resources/common/formatter.go | 9 ++- pkg/resources/common/formatter_test.go | 82 +++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/pkg/resources/common/formatter.go b/pkg/resources/common/formatter.go index e6e5f25c..e6d89a40 100644 --- a/pkg/resources/common/formatter.go +++ b/pkg/resources/common/formatter.go @@ -121,15 +121,22 @@ func formatter(summarycache common.SummaryCache, asl accesscontrol.AccessSetLook return } } + hasGet := accessSet.Grants("get", gvr.GroupResource(), resource.APIObject.Namespace(), resource.APIObject.Name()) hasUpdate := accessSet.Grants("update", gvr.GroupResource(), resource.APIObject.Namespace(), resource.APIObject.Name()) hasDelete := accessSet.Grants("delete", gvr.GroupResource(), resource.APIObject.Namespace(), resource.APIObject.Name()) hasPatch := accessSet.Grants("patch", gvr.GroupResource(), resource.APIObject.Namespace(), resource.APIObject.Name()) selfLink := selfLink(gvr, meta) - u := request.URLBuilder.RelativeToRoot(selfLink) resource.Links["view"] = u + if hasGet { + if attributes.DisallowMethods(resource.Schema)[http.MethodGet] { + resource.Links["view"] = "blocked" + } + } else { + delete(resource.Links, "view") + } if hasUpdate { if attributes.DisallowMethods(resource.Schema)[http.MethodPut] { resource.Links["update"] = "blocked" diff --git a/pkg/resources/common/formatter_test.go b/pkg/resources/common/formatter_test.go index 9eb8b06e..b826cf3d 100644 --- a/pkg/resources/common/formatter_test.go +++ b/pkg/resources/common/formatter_test.go @@ -648,6 +648,75 @@ func Test_formatterLinks(t *testing.T) { currentLinks map[string]string wantLinks map[string]string }{ + { + name: "get permission granted", + hasUser: true, + permissions: &permissions{ + hasGet: true, + }, + schema: &types.APISchema{ + Schema: &schemas.Schema{ + ID: "example", + Attributes: map[string]interface{}{ + "group": "", + "version": "v1", + "resource": "pods", + }, + }, + }, + apiObject: types.APIObject{ + ID: "example", + Object: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-pod", + Namespace: "example-ns", + }, + }, + }, + currentLinks: map[string]string{ + "default": "defaultVal", + }, + wantLinks: map[string]string{ + "default": "defaultVal", + "view": "/api/v1/namespaces/example-ns/pods/example-pod", + }, + }, + { + name: "get permission granted, but disallowed in schema", + hasUser: true, + permissions: &permissions{ + hasGet: true, + }, + schema: &types.APISchema{ + Schema: &schemas.Schema{ + ID: "example", + Attributes: map[string]interface{}{ + "group": "", + "version": "v1", + "resource": "pods", + "disallowMethods": map[string]bool{ + http.MethodGet: true, + }, + }, + }, + }, + apiObject: types.APIObject{ + ID: "example", + Object: &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-pod", + Namespace: "example-ns", + }, + }, + }, + currentLinks: map[string]string{ + "default": "defaultVal", + }, + wantLinks: map[string]string{ + "default": "defaultVal", + "view": "blocked", + }, + }, { name: "no schema", currentLinks: map[string]string{ @@ -784,7 +853,6 @@ func Test_formatterLinks(t *testing.T) { }, wantLinks: map[string]string{ "default": "defaultVal", - "view": "/api/v1/namespaces/example-ns/pods/example-pod", }, }, { @@ -820,7 +888,6 @@ func Test_formatterLinks(t *testing.T) { wantLinks: map[string]string{ "default": "defaultVal", "update": "../v1/namespaces/example-ns/pods/example-pod", - "view": "/api/v1/namespaces/example-ns/pods/example-pod", }, }, { @@ -856,7 +923,6 @@ func Test_formatterLinks(t *testing.T) { wantLinks: map[string]string{ "default": "defaultVal", "remove": "../v1/namespaces/example-ns/pods/example-pod", - "view": "/api/v1/namespaces/example-ns/pods/example-pod", }, }, { @@ -894,7 +960,6 @@ func Test_formatterLinks(t *testing.T) { "default": "defaultVal", "update": "../v1/namespaces/example-ns/pods/example-pod", "remove": "../v1/namespaces/example-ns/pods/example-pod", - "view": "/api/v1/namespaces/example-ns/pods/example-pod", }, }, { @@ -936,7 +1001,6 @@ func Test_formatterLinks(t *testing.T) { "default": "defaultVal", "update": "blocked", "remove": "blocked", - "view": "/api/v1/namespaces/example-ns/pods/example-pod", }, }, { @@ -972,7 +1036,6 @@ func Test_formatterLinks(t *testing.T) { wantLinks: map[string]string{ "default": "defaultVal", "patch": "/v1/apps.deployments/example-ns/example-deployment", - "view": "/apis/apps/v1/namespaces/example-ns/deployments/example-deployment", }, }, { @@ -1011,7 +1074,6 @@ func Test_formatterLinks(t *testing.T) { wantLinks: map[string]string{ "default": "defaultVal", "patch": "blocked", - "view": "/apis/apps/v1/namespaces/example-ns/deployments/example-deployment", }, }, } @@ -1031,6 +1093,12 @@ func Test_formatterLinks(t *testing.T) { meta, err := meta.Accessor(test.apiObject.Object) accessSet := accesscontrol.AccessSet{} require.NoError(t, err) + if test.permissions.hasGet { + accessSet.Add("get", gvr.GroupResource(), accesscontrol.Access{ + Namespace: meta.GetNamespace(), + ResourceName: meta.GetName(), + }) + } if test.permissions.hasUpdate { accessSet.Add("update", gvr.GroupResource(), accesscontrol.Access{ Namespace: meta.GetNamespace(),