Skip to content

Commit 55f48a5

Browse files
Anisimov.evenot237
authored andcommitted
fix(tenants): correct tenant get route path
The tenant get route was using a hardcoded placeholder string instead of the actual API group and resource types. This prevented the router from correctly matching requests for specific tenants. This change updates the path to use `types.CapsuleGroup` and `types.Tenants` to ensure the route is correctly constructed. Added unit tests for the path matching and e2e tests to verify tenant access control via the API. Signed-off-by: Anisimov Evgeniy <anisimov.evgeniy.s@gmail.com>
1 parent 041eb86 commit 55f48a5

3 files changed

Lines changed: 107 additions & 1 deletion

File tree

e2e/tenant_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package e2e_test
2+
3+
import (
4+
"context"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
capsulerbac "github.com/projectcapsule/capsule/pkg/api/rbac"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/client-go/kubernetes"
11+
12+
capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
13+
)
14+
15+
var _ = Describe("Tenants", func() {
16+
var aliceClient, bobClient *kubernetes.Clientset
17+
18+
tenant := &capsulev1beta2.Tenant{
19+
ObjectMeta: metav1.ObjectMeta{
20+
Name: "tenant-get-owned-by-alice",
21+
Labels: e2eLabels(),
22+
},
23+
Spec: capsulev1beta2.TenantSpec{
24+
Owners: capsulerbac.OwnerListSpec{
25+
{
26+
CoreOwnerSpec: capsulerbac.CoreOwnerSpec{
27+
UserSpec: capsulerbac.UserSpec{
28+
Name: "alice",
29+
Kind: "User",
30+
},
31+
},
32+
},
33+
},
34+
},
35+
}
36+
37+
BeforeEach(func() {
38+
var err error
39+
40+
aliceClient, err = loadKubeConfig("alice")
41+
Expect(err).ToNot(HaveOccurred())
42+
bobClient, err = loadKubeConfig("bob")
43+
Expect(err).ToNot(HaveOccurred())
44+
45+
Eventually(func() error {
46+
tenant.ResourceVersion = ""
47+
48+
return k8sClient.Create(context.TODO(), tenant)
49+
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed())
50+
})
51+
52+
JustAfterEach(func() {
53+
Expect(k8sClient.Delete(context.TODO(), tenant)).Should(Succeed())
54+
})
55+
56+
It("Should allow tenant owners to get their tenant by name", func() {
57+
getTenant := func(clientset *kubernetes.Clientset, name string) error {
58+
_, err := clientset.RESTClient().
59+
Get().
60+
AbsPath("/apis/capsule.clastix.io/v1beta2/tenants/" + name).
61+
DoRaw(context.Background())
62+
63+
return err
64+
}
65+
66+
Eventually(func() error {
67+
return getTenant(aliceClient, tenant.GetName())
68+
}, defaultTimeoutInterval, defaultPollInterval).Should(Succeed(), "Alice should get a tenant she owns by name")
69+
70+
Eventually(func() error {
71+
return getTenant(bobClient, tenant.GetName())
72+
}, defaultTimeoutInterval, defaultPollInterval).Should(HaveOccurred(), "Bob should not get a tenant he does not own by name")
73+
})
74+
})

internal/modules/tenants/get.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (g get) GroupKind() schema.GroupKind {
5353
}
5454

5555
func (g get) Path() string {
56-
return "/apis/{}/v1beta2/tenants/{name}"
56+
return "/apis/" + types.CapsuleGroup + "/v1beta2/" + types.Tenants + "/{name}"
5757
}
5858

5959
func (g get) Methods() []string {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2020-2025 Project Capsule Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package tenants
5+
6+
import (
7+
"net/http"
8+
"net/http/httptest"
9+
"testing"
10+
11+
"github.com/gorilla/mux"
12+
)
13+
14+
func TestGetPathMatchesTenantByName(t *testing.T) {
15+
matched := false
16+
17+
router := mux.NewRouter()
18+
router.Path(Get(nil).Path()).Methods(http.MethodGet).HandlerFunc(func(_ http.ResponseWriter, request *http.Request) {
19+
matched = true
20+
21+
if name := mux.Vars(request)["name"]; name != "3282" {
22+
t.Fatalf("expected tenant name 3282, got %q", name)
23+
}
24+
})
25+
26+
request := httptest.NewRequest(http.MethodGet, "/apis/capsule.clastix.io/v1beta2/tenants/3282", nil)
27+
router.ServeHTTP(httptest.NewRecorder(), request)
28+
29+
if !matched {
30+
t.Fatal("tenant get route did not match")
31+
}
32+
}

0 commit comments

Comments
 (0)