grafana/pkg/services/authz/server_test.go
Gabriel MABILLE 2788817107
AuthZ: Implement Check (#95162)
* AuthZ: Implement Check


---------

Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
2024-10-25 14:57:39 +02:00

219 lines
5.4 KiB
Go

package authz
import (
"context"
"testing"
authzv1 "github.com/grafana/authlib/authz/proto/v1"
"github.com/grafana/authlib/claims"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/services/authz/mappers"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/folder/foldertest"
)
var folderTree = []*folder.Folder{
{
ID: 1,
UID: "top",
Title: "top",
},
{
ID: 2,
UID: "sub",
Title: "sub",
ParentUID: "top",
},
{
ID: 3,
UID: "sub2",
Title: "sub2",
ParentUID: "sub",
},
{
ID: 4,
UID: "sub3",
Title: "sub3",
ParentUID: "sub2",
},
}
func Test_legacyServer_Check(t *testing.T) {
tests := []struct {
name string
req *authzv1.CheckRequest
parents []*folder.Folder
userPerms map[string][]string
wantAllowed bool
wantErr bool
}{
{
name: "should not allow access to a dashboard without read permission",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
},
userPerms: map[string][]string{},
wantAllowed: false,
wantErr: false,
},
{
name: "should allow access to a dashboard with read permission",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
},
userPerms: map[string][]string{"dashboards:read": {"dashboards:uid:dash1"}},
wantAllowed: true,
wantErr: false,
},
{
name: "should allow access to a dashboard through read permission on a parent folder",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
Folder: "sub4",
},
parents: folderTree,
userPerms: map[string][]string{
"dashboards:read": {"folders:uid:sub"},
},
wantAllowed: true,
wantErr: false,
},
{
name: "should check action only",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Namespace: "org-2",
},
userPerms: map[string][]string{"dashboards:read": {"dashboards:uid:dash1"}},
wantAllowed: true,
wantErr: false,
},
// Input validation
{
name: "should return error when group is not set",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
},
wantErr: true,
},
{
name: "should return error when resource is not set",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Name: "dash1",
Namespace: "org-2",
},
wantErr: true,
},
{
name: "should return error when verb is not set",
req: &authzv1.CheckRequest{
Subject: "user:1",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
},
wantErr: true,
},
{
name: "should return error when subject is not set",
req: &authzv1.CheckRequest{
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "org-2",
},
wantErr: true,
},
{
name: "should return error when namespace is incorrect",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "dashboards.grafana.app",
Resource: "dashboards",
Name: "dash1",
Namespace: "stacks-2",
},
wantErr: true,
},
{
name: "should return error when action is not found",
req: &authzv1.CheckRequest{
Subject: "user:1",
Verb: "get",
Group: "unknown.grafana.app",
Resource: "unknown",
Name: "unknown",
Namespace: "org-2",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := featuremgmt.WithFeatures()
l := &legacyServer{
ac: acimpl.ProvideAccessControl(f, nil),
authnSvc: &authntest.FakeService{
ExpectedIdentity: &authn.Identity{
ID: "user:1",
UID: "1",
Type: claims.TypeUser,
OrgID: 2,
OrgRoles: map[int64]identity.RoleType{2: identity.RoleNone},
Login: "user1",
Permissions: map[int64]map[string][]string{2: tt.userPerms},
},
},
folderSvc: &foldertest.FakeService{ExpectedFolders: tt.parents},
logger: log.New("authz-grpc-server.test"),
tracer: tracing.InitializeTracerForTest(),
mapper: mappers.NewK8sRbacMapper(),
}
got, err := l.Check(context.Background(), tt.req)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.NotNil(t, got)
require.Equal(t, tt.wantAllowed, got.Allowed)
})
}
}