Investigations: Move Grafana core packages to pkg/registry/apps (#109477)

This commit is contained in:
Matheus Macabu
2025-08-12 15:33:23 +02:00
committed by GitHub
parent 80e8a6e211
commit 904bf6b807
5 changed files with 23 additions and 965 deletions
@@ -0,0 +1,38 @@
package investigations
import (
"context"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"k8s.io/apiserver/pkg/authorization/authorizer"
)
func GetAuthorizer() authorizer.Authorizer {
return authorizer.AuthorizerFunc(func(
ctx context.Context, attr authorizer.Attributes,
) (authorized authorizer.Decision, reason string, err error) {
if !attr.IsResourceRequest() {
return authorizer.DecisionNoOpinion, "", nil
}
u, err := identity.GetRequester(ctx)
if err != nil {
return authorizer.DecisionDeny, "valid user is required", err
}
p := u.GetPermissions()
if len(p) == 0 {
return authorizer.DecisionDeny, "no permissions", nil
}
_, ok := p[accesscontrol.ActionDatasourcesExplore]
if !ok {
// defer to the default authorizer if datasources:explore is not present
return authorizer.DecisionNoOpinion, "", nil
}
return authorizer.DecisionAllow, "", nil
})
}
@@ -0,0 +1,87 @@
package investigations
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/stretchr/testify/assert"
"k8s.io/apiserver/pkg/authorization/authorizer"
)
func TestGetAuthorizer(t *testing.T) {
tests := []struct {
name string
ctx context.Context
attr authorizer.Attributes
expectedDecision authorizer.Decision
expectedReason string
expectedErr error
}{
{
name: "non-resource request",
ctx: context.TODO(),
attr: &mockAttributes{resourceRequest: false},
expectedDecision: authorizer.DecisionNoOpinion,
expectedReason: "",
expectedErr: nil,
},
{
name: "user has datasources:explore permission",
ctx: identity.WithRequester(context.TODO(), &mockUser{permissions: map[string][]string{accesscontrol.ActionDatasourcesExplore: {}}}),
attr: &mockAttributes{resourceRequest: true},
expectedDecision: authorizer.DecisionAllow,
expectedReason: "",
expectedErr: nil,
},
{
name: "user does not have datasources:explore permission",
ctx: identity.WithRequester(context.TODO(), &mockUser{}),
attr: &mockAttributes{resourceRequest: true},
expectedDecision: authorizer.DecisionDeny,
expectedReason: "no permissions",
expectedErr: nil,
},
{
name: "user does not have datasources:explore permission",
ctx: identity.WithRequester(context.TODO(), &mockUser{permissions: map[string][]string{"foo": {}}}),
attr: &mockAttributes{resourceRequest: true},
expectedDecision: authorizer.DecisionNoOpinion,
expectedReason: "",
expectedErr: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
auth := GetAuthorizer()
decision, reason, err := auth.Authorize(tt.ctx, tt.attr)
assert.Equal(t, tt.expectedDecision, decision)
assert.Equal(t, tt.expectedReason, reason)
assert.Equal(t, tt.expectedErr, err)
})
}
}
type mockAttributes struct {
authorizer.Attributes
resourceRequest bool
}
func (m *mockAttributes) IsResourceRequest() bool {
return m.resourceRequest
}
// Implement other methods of authorizer.Attributes as needed
type mockUser struct {
identity.Requester
permissions map[string][]string
}
func (m *mockUser) GetPermissions() map[string][]string {
return m.permissions
}
// Implement other methods of identity.Requester as needed
+1 -1
View File
@@ -25,7 +25,7 @@ func RegisterApp(
appCfg := &runner.AppBuilderConfig{
OpenAPIDefGetter: investigationv0alpha1.GetOpenAPIDefinitions,
ManagedKinds: investigationapp.GetKinds(),
Authorizer: investigationapp.GetAuthorizer(),
Authorizer: GetAuthorizer(),
AllowedV0Alpha1Resources: []string{builder.AllResourcesAllowed},
}
provider.Provider = simple.NewAppProvider(apis.LocalManifest(), appCfg, investigationapp.New)