mirror of https://github.com/grafana/grafana
Investigations: Allow everyone with `datasources:explore` permissions to use investigations (#104280)
* Investigations: Authorize everyone to create investigations * fix testprovisioning/job-errors
parent
f9fb6f3b88
commit
4b48121464
@ -0,0 +1,38 @@ |
||||
package app |
||||
|
||||
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 app |
||||
|
||||
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
|
Loading…
Reference in new issue