mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 13:02:33 +08:00

* update authlib version * add latest versions * make update-workspace * typo * Trigger Build * Trigger Build
224 lines
6.5 KiB
Go
224 lines
6.5 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
authlib "github.com/grafana/authlib/types"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
)
|
|
|
|
func TestAuthzLimitedClient_Check(t *testing.T) {
|
|
mockClient := authlib.FixedAccessClient(false)
|
|
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
|
|
|
tests := []struct {
|
|
group string
|
|
resource string
|
|
expected bool
|
|
}{
|
|
{"dashboard.grafana.app", "dashboards", false},
|
|
{"folder.grafana.app", "folders", false},
|
|
{"unknown.group", "unknown.resource", true},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
req := authlib.CheckRequest{
|
|
Group: test.group,
|
|
Resource: test.resource,
|
|
Verb: utils.VerbGet,
|
|
Namespace: "stacks-1",
|
|
}
|
|
resp, err := client.Check(context.Background(), &identity.StaticRequester{Namespace: "stacks-1"}, req)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.expected, resp.Allowed)
|
|
}
|
|
}
|
|
|
|
func TestAuthzLimitedClient_Compile(t *testing.T) {
|
|
mockClient := authlib.FixedAccessClient(false)
|
|
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
|
|
|
tests := []struct {
|
|
group string
|
|
resource string
|
|
expected bool
|
|
}{
|
|
{"dashboard.grafana.app", "dashboards", false},
|
|
{"folder.grafana.app", "folders", false},
|
|
{"unknown.group", "unknown.resource", true},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
req := authlib.ListRequest{
|
|
Group: test.group,
|
|
Resource: test.resource,
|
|
Verb: utils.VerbGet,
|
|
Namespace: "stacks-1",
|
|
}
|
|
checker, err := client.Compile(context.Background(), &identity.StaticRequester{Namespace: "stacks-1"}, req)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, checker)
|
|
|
|
result := checker("name", "folder")
|
|
assert.Equal(t, test.expected, result)
|
|
}
|
|
}
|
|
|
|
// TestNamespaceMatching tests namespace matching in Check and Compile methods
|
|
func TestNamespaceMatching(t *testing.T) {
|
|
// Create a mock client that always returns allowed=true
|
|
mockClient := authlib.FixedAccessClient(true)
|
|
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
|
|
|
// Create a context with fallback disabled
|
|
ctx := context.Background()
|
|
|
|
tests := []struct {
|
|
name string
|
|
authNamespace string
|
|
reqNamespace string
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "matching namespaces",
|
|
authNamespace: "ns1",
|
|
reqNamespace: "ns1",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "mismatched namespaces",
|
|
authNamespace: "ns1",
|
|
reqNamespace: "ns2",
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "empty request namespace",
|
|
authNamespace: "ns1",
|
|
reqNamespace: "",
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "empty auth namespace",
|
|
authNamespace: "",
|
|
reqNamespace: "ns1",
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "wildcard auth namespace",
|
|
authNamespace: "*",
|
|
reqNamespace: "ns1",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "both empty namespaces",
|
|
authNamespace: "",
|
|
reqNamespace: "",
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Test Check method with namespace matching
|
|
checkReq := authlib.CheckRequest{
|
|
Group: "unknown.group", // Use unknown group to bypass RBAC check
|
|
Resource: "unknown.resource",
|
|
Verb: utils.VerbGet,
|
|
Namespace: tt.reqNamespace,
|
|
}
|
|
// Create a mock auth info with the specified namespace
|
|
// Test Check method
|
|
user := &identity.StaticRequester{Namespace: tt.authNamespace}
|
|
_, checkErr := client.Check(ctx, user, checkReq)
|
|
|
|
// Test Compile method
|
|
compileReq := authlib.ListRequest{
|
|
Group: "unknown.group", // Use unknown group to bypass RBAC check
|
|
Resource: "unknown.resource",
|
|
Verb: utils.VerbGet,
|
|
Namespace: tt.reqNamespace,
|
|
}
|
|
_, compileErr := client.Compile(ctx, user, compileReq)
|
|
|
|
if tt.expectError {
|
|
require.Error(t, checkErr, "Check should return error")
|
|
require.Error(t, compileErr, "Compile should return error")
|
|
assert.ErrorIs(t, checkErr, authlib.ErrNamespaceMismatch, "Check should return namespace mismatch error")
|
|
assert.ErrorIs(t, compileErr, authlib.ErrNamespaceMismatch, "Compile should return namespace mismatch error")
|
|
} else {
|
|
assert.NoError(t, checkErr, "Check should not return error when namespaces match")
|
|
assert.NoError(t, compileErr, "Compile should not return error when namespaces match")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestNamespaceMatchingFallback tests namespace matching in Check and Compile methods when fallback is used
|
|
func TestNamespaceMatchingFallback(t *testing.T) {
|
|
// Create a mock client that always returns allowed=true
|
|
mockClient := authlib.FixedAccessClient(true)
|
|
client := NewAuthzLimitedClient(mockClient, AuthzOptions{})
|
|
|
|
// Create a context with fallback disabled
|
|
ctx := context.Background()
|
|
|
|
tests := []struct {
|
|
name string
|
|
authNamespace string
|
|
reqNamespace string
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "with namespace fallback",
|
|
reqNamespace: "ns1",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty request namespace with fallback",
|
|
reqNamespace: "",
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Test Check method with namespace matching
|
|
checkReq := authlib.CheckRequest{
|
|
Group: "unknown.group", // Use unknown group to bypass RBAC check
|
|
Resource: "unknown.resource",
|
|
Verb: utils.VerbGet,
|
|
Namespace: tt.reqNamespace,
|
|
}
|
|
ctx = WithFallback(ctx)
|
|
// Create a mock auth info with the specified namespace
|
|
// Test Check method
|
|
user := &identity.StaticRequester{Namespace: tt.authNamespace}
|
|
_, checkErr := client.Check(ctx, user, checkReq)
|
|
|
|
// Test Compile method
|
|
compileReq := authlib.ListRequest{
|
|
Group: "unknown.group", // Use unknown group to bypass RBAC check
|
|
Resource: "unknown.resource",
|
|
Verb: utils.VerbGet,
|
|
Namespace: tt.reqNamespace,
|
|
}
|
|
_, compileErr := client.Compile(ctx, user, compileReq)
|
|
|
|
if tt.expectError {
|
|
require.Error(t, checkErr, "Check should return error")
|
|
require.Error(t, compileErr, "Compile should return error")
|
|
assert.ErrorContains(t, checkErr, "namespace empty", "Check should return namespace mismatch error")
|
|
assert.ErrorContains(t, compileErr, "namespace empty", "Compile should return namespace mismatch error")
|
|
} else {
|
|
assert.NoError(t, checkErr, "Check should not return error when namespaces match")
|
|
assert.NoError(t, compileErr, "Compile should not return error when namespaces match")
|
|
}
|
|
})
|
|
}
|
|
}
|