mirror of
https://github.com/grafana/grafana.git
synced 2025-07-28 23:02:28 +08:00
Authz: Account for fixed roles when running oss and using authz service (#99244)
* Extract "PermissionStore" from general store interface * Add static and union permission stores * Add GetStaticRoles * Use accesscontrol.Service for inproc to provide static permissions
This commit is contained in:
@ -59,6 +59,8 @@ type Service interface {
|
||||
DeleteExternalServiceRole(ctx context.Context, externalServiceID string) error
|
||||
// SyncUserRoles adds provided roles to user
|
||||
SyncUserRoles(ctx context.Context, orgID int64, cmd SyncUserRolesCommand) error
|
||||
// GetStaicRoles returns a map where key organization role and value is a static rbac role.
|
||||
GetStaticRoles(ctx context.Context) map[string]*RoleDTO
|
||||
}
|
||||
|
||||
//go:generate mockery --name Store --structname MockStore --outpkg actest --filename store_mock.go --output ./actest/
|
||||
|
@ -464,7 +464,15 @@ func (s *Service) RegisterFixedRoles(ctx context.Context) error {
|
||||
s.registrations.Range(func(registration accesscontrol.RoleRegistration) bool {
|
||||
for br := range accesscontrol.BuiltInRolesWithParents(registration.Grants) {
|
||||
if basicRole, ok := s.roles[br]; ok {
|
||||
basicRole.Permissions = append(basicRole.Permissions, registration.Role.Permissions...)
|
||||
for _, p := range registration.Role.Permissions {
|
||||
perm := accesscontrol.Permission{
|
||||
Action: p.Action,
|
||||
Scope: p.Scope,
|
||||
}
|
||||
|
||||
perm.Kind, perm.Attribute, perm.Identifier = accesscontrol.SplitScope(perm.Scope)
|
||||
basicRole.Permissions = append(basicRole.Permissions, perm)
|
||||
}
|
||||
} else {
|
||||
s.log.Error("Unknown builtin role", "builtInRole", br)
|
||||
}
|
||||
@ -770,10 +778,14 @@ func (s *Service) DeleteExternalServiceRole(ctx context.Context, externalService
|
||||
return s.store.DeleteExternalServiceRole(ctx, slug)
|
||||
}
|
||||
|
||||
func (*Service) SyncUserRoles(ctx context.Context, orgID int64, cmd accesscontrol.SyncUserRolesCommand) error {
|
||||
func (s *Service) SyncUserRoles(ctx context.Context, orgID int64, cmd accesscontrol.SyncUserRolesCommand) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) GetStaticRoles(ctx context.Context) map[string]*accesscontrol.RoleDTO {
|
||||
return s.roles
|
||||
}
|
||||
|
||||
func (s *Service) GetRoleByName(ctx context.Context, orgID int64, roleName string) (*accesscontrol.RoleDTO, error) {
|
||||
_, span := tracer.Start(ctx, "accesscontrol.acimpl.GetRoleByName")
|
||||
defer span.End()
|
||||
|
@ -373,6 +373,7 @@ func TestService_RegisterFixedRoles(t *testing.T) {
|
||||
builtinRole, ok := ac.roles[br]
|
||||
assert.True(t, ok)
|
||||
for _, expectedPermission := range registration.Role.Permissions {
|
||||
expectedPermission.Kind, expectedPermission.Attribute, expectedPermission.Identifier = accesscontrol.SplitScope(expectedPermission.Scope)
|
||||
assert.Contains(t, builtinRole.Permissions, expectedPermission)
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ type Calls struct {
|
||||
}
|
||||
|
||||
type Mock struct {
|
||||
accesscontrol.Service
|
||||
accesscontrol.AccessControl
|
||||
|
||||
// Unless an override is provided, permissions will be returned by GetUserPermissions
|
||||
permissions []accesscontrol.Permission
|
||||
// Unless an override is provided, builtInRoles will be returned by GetUserBuiltInRoles
|
||||
|
@ -18,7 +18,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/authz/rbac"
|
||||
"github.com/grafana/grafana/pkg/services/authz/rbac/store"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@ -30,8 +32,12 @@ const authzServiceAudience = "authzService"
|
||||
|
||||
// ProvideAuthZClient provides an AuthZ client and creates the AuthZ service.
|
||||
func ProvideAuthZClient(
|
||||
cfg *setting.Cfg, features featuremgmt.FeatureToggles, grpcServer grpcserver.Provider,
|
||||
tracer tracing.Tracer, db db.DB,
|
||||
cfg *setting.Cfg,
|
||||
features featuremgmt.FeatureToggles,
|
||||
grpcServer grpcserver.Provider,
|
||||
tracer tracing.Tracer,
|
||||
db db.DB,
|
||||
acService accesscontrol.Service,
|
||||
) (authzlib.AccessClient, error) {
|
||||
authCfg, err := ReadCfg(cfg)
|
||||
if err != nil {
|
||||
@ -43,16 +49,25 @@ func ProvideAuthZClient(
|
||||
return nil, errors.New("authZGRPCServer feature toggle is required for cloud and grpc mode")
|
||||
}
|
||||
|
||||
// Register the server
|
||||
sql := legacysql.NewDatabaseProvider(db)
|
||||
server := rbac.NewService(sql, legacy.NewLegacySQLStores(sql), log.New("authz-grpc-server"), tracer)
|
||||
|
||||
switch authCfg.mode {
|
||||
case ModeGRPC:
|
||||
return newGrpcLegacyClient(authCfg, tracer)
|
||||
case ModeCloud:
|
||||
return newCloudLegacyClient(authCfg, tracer)
|
||||
default:
|
||||
sql := legacysql.NewDatabaseProvider(db)
|
||||
|
||||
// Register the server
|
||||
server := rbac.NewService(
|
||||
sql,
|
||||
legacy.NewLegacySQLStores(sql),
|
||||
store.NewUnionPermissionStore(
|
||||
store.NewStaticPermissionStore(acService),
|
||||
store.NewSQLPermissionStore(sql, tracer),
|
||||
),
|
||||
log.New("authz-grpc-server"),
|
||||
tracer,
|
||||
)
|
||||
return newInProcLegacyClient(server, tracer)
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,10 @@ type Service struct {
|
||||
authzv1.UnimplementedAuthzServiceServer
|
||||
authzextv1.UnimplementedAuthzExtentionServiceServer
|
||||
|
||||
store store.Store
|
||||
identityStore legacy.LegacyIdentityStore
|
||||
actionMapper *mappers.K8sRbacMapper
|
||||
store store.Store
|
||||
permissionStore store.PermissionStore
|
||||
identityStore legacy.LegacyIdentityStore
|
||||
actionMapper *mappers.K8sRbacMapper
|
||||
|
||||
logger log.Logger
|
||||
tracer tracing.Tracer
|
||||
@ -58,19 +59,27 @@ type Service struct {
|
||||
sf *singleflight.Group
|
||||
}
|
||||
|
||||
func NewService(sql legacysql.LegacyDatabaseProvider, identityStore legacy.LegacyIdentityStore, logger log.Logger, tracer tracing.Tracer) *Service {
|
||||
func NewService(
|
||||
sql legacysql.LegacyDatabaseProvider,
|
||||
identityStore legacy.LegacyIdentityStore,
|
||||
permissionStore store.PermissionStore,
|
||||
logger log.Logger,
|
||||
tracer tracing.Tracer,
|
||||
|
||||
) *Service {
|
||||
return &Service{
|
||||
store: store.NewStore(sql, tracer),
|
||||
identityStore: identityStore,
|
||||
actionMapper: mappers.NewK8sRbacMapper(),
|
||||
logger: logger,
|
||||
tracer: tracer,
|
||||
idCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
permCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
teamCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
basicRoleCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
folderCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
sf: new(singleflight.Group),
|
||||
store: store.NewStore(sql, tracer),
|
||||
permissionStore: permissionStore,
|
||||
identityStore: identityStore,
|
||||
actionMapper: mappers.NewK8sRbacMapper(),
|
||||
logger: logger,
|
||||
tracer: tracer,
|
||||
idCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
permCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
teamCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
basicRoleCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
folderCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
sf: new(singleflight.Group),
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,7 +291,7 @@ func (s *Service) getUserPermissions(ctx context.Context, ns claims.NamespaceInf
|
||||
IsServerAdmin: basicRoles.IsAdmin,
|
||||
}
|
||||
|
||||
permissions, err := s.store.GetUserPermissions(ctx, ns, userPermQuery)
|
||||
permissions, err := s.permissionStore.GetUserPermissions(ctx, ns, userPermQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -311,7 +320,7 @@ func (s *Service) getAnonymousPermissions(ctx context.Context, ns claims.Namespa
|
||||
}
|
||||
|
||||
res, err, _ := s.sf.Do(anonPermKey+"_getAnonymousPermissions", func() (interface{}, error) {
|
||||
permissions, err := s.store.GetUserPermissions(ctx, ns, store.PermissionsQuery{Action: action, ActionSets: actionSets, Role: "Viewer"})
|
||||
permissions, err := s.permissionStore.GetUserPermissions(ctx, ns, store.PermissionsQuery{Action: action, ActionSets: actionSets, Role: "Viewer"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -286,10 +286,11 @@ func TestService_getUserBasicRole(t *testing.T) {
|
||||
}
|
||||
|
||||
s := &Service{
|
||||
basicRoleCache: cacheService,
|
||||
store: store,
|
||||
logger: log.New("test"),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
basicRoleCache: cacheService,
|
||||
store: store,
|
||||
permissionStore: store,
|
||||
logger: log.New("test"),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
}
|
||||
|
||||
role, err := s.getUserBasicRole(ctx, ns, userIdentifiers)
|
||||
@ -361,16 +362,17 @@ func TestService_getUserPermissions(t *testing.T) {
|
||||
}
|
||||
|
||||
s := &Service{
|
||||
store: store,
|
||||
identityStore: &fakeIdentityStore{teams: []int64{1, 2}},
|
||||
actionMapper: mappers.NewK8sRbacMapper(),
|
||||
logger: log.New("test"),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
idCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
permCache: cacheService,
|
||||
sf: new(singleflight.Group),
|
||||
basicRoleCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
teamCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
store: store,
|
||||
permissionStore: store,
|
||||
identityStore: &fakeIdentityStore{teams: []int64{1, 2}},
|
||||
actionMapper: mappers.NewK8sRbacMapper(),
|
||||
logger: log.New("test"),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
idCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
permCache: cacheService,
|
||||
sf: new(singleflight.Group),
|
||||
basicRoleCache: localcache.New(longCacheTTL, longCleanupInterval),
|
||||
teamCache: localcache.New(shortCacheTTL, shortCleanupInterval),
|
||||
}
|
||||
|
||||
perms, err := s.getUserPermissions(ctx, ns, claims.TypeUser, userID.UID, action)
|
||||
@ -437,11 +439,12 @@ func TestService_buildFolderTree(t *testing.T) {
|
||||
store := &fakeStore{folders: tc.folders}
|
||||
|
||||
s := &Service{
|
||||
store: store,
|
||||
folderCache: cacheService,
|
||||
logger: log.New("test"),
|
||||
sf: new(singleflight.Group),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
store: store,
|
||||
permissionStore: store,
|
||||
folderCache: cacheService,
|
||||
logger: log.New("test"),
|
||||
sf: new(singleflight.Group),
|
||||
tracer: tracing.NewNoopTracerService(),
|
||||
}
|
||||
|
||||
tree, err := s.buildFolderTree(ctx, ns)
|
||||
|
@ -10,16 +10,6 @@ type BasicRole struct {
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
type PermissionsQuery struct {
|
||||
OrgID int64
|
||||
UserID int64
|
||||
Action string
|
||||
ActionSets []string
|
||||
TeamIDs []int64
|
||||
Role string
|
||||
IsServerAdmin bool
|
||||
}
|
||||
|
||||
type BasicRoleQuery struct {
|
||||
UserID int64
|
||||
OrgID int64
|
||||
|
159
pkg/services/authz/rbac/store/permission_store.go
Normal file
159
pkg/services/authz/rbac/store/permission_store.go
Normal file
@ -0,0 +1,159 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
type PermissionStore interface {
|
||||
GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error)
|
||||
}
|
||||
|
||||
type PermissionsQuery struct {
|
||||
OrgID int64
|
||||
UserID int64
|
||||
Action string
|
||||
ActionSets []string
|
||||
TeamIDs []int64
|
||||
Role string
|
||||
IsServerAdmin bool
|
||||
}
|
||||
|
||||
func NewSQLPermissionStore(sql legacysql.LegacyDatabaseProvider, tracer tracing.Tracer) *SQLPermissionsStore {
|
||||
return &SQLPermissionsStore{sql, tracer}
|
||||
}
|
||||
|
||||
var _ PermissionStore = (*SQLPermissionsStore)(nil)
|
||||
|
||||
type SQLPermissionsStore struct {
|
||||
sql legacysql.LegacyDatabaseProvider
|
||||
tracer tracing.Tracer
|
||||
}
|
||||
|
||||
var sqlUserPerms = mustTemplate("permission_query.sql")
|
||||
|
||||
type getPermissionsQuery struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *PermissionsQuery
|
||||
|
||||
PermissionTable string
|
||||
UserRoleTable string
|
||||
TeamRoleTable string
|
||||
BuiltinRoleTable string
|
||||
}
|
||||
|
||||
func (r getPermissionsQuery) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newGetPermissions(sql *legacysql.LegacyDatabaseHelper, q *PermissionsQuery) getPermissionsQuery {
|
||||
return getPermissionsQuery{
|
||||
SQLTemplate: sqltemplate.New(sql.DialectForDriver()),
|
||||
Query: q,
|
||||
PermissionTable: sql.Table("permission"),
|
||||
UserRoleTable: sql.Table("user_role"),
|
||||
TeamRoleTable: sql.Table("team_role"),
|
||||
BuiltinRoleTable: sql.Table("builtin_role"),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SQLPermissionsStore) GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "authz_direct_db.database.GetUserPermissions")
|
||||
defer span.End()
|
||||
|
||||
sql, err := s.sql(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.OrgID = ns.OrgID
|
||||
req := newGetPermissions(sql, &query)
|
||||
q, err := sqltemplate.Execute(sqlUserPerms, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := sql.DB.GetSqlxSession().Query(ctx, q, req.GetArgs()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if res != nil {
|
||||
_ = res.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
var perms []accesscontrol.Permission
|
||||
for res.Next() {
|
||||
var perm accesscontrol.Permission
|
||||
if err := res.Scan(&perm.Kind, &perm.Attribute, &perm.Identifier, &perm.Scope); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
perms = append(perms, perm)
|
||||
}
|
||||
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
var _ PermissionStore = (*StaticPermissionStore)(nil)
|
||||
|
||||
func NewStaticPermissionStore(ac accesscontrol.Service) *StaticPermissionStore {
|
||||
return &StaticPermissionStore{ac}
|
||||
}
|
||||
|
||||
type StaticPermissionStore struct {
|
||||
ac accesscontrol.Service
|
||||
}
|
||||
|
||||
func (s *StaticPermissionStore) GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error) {
|
||||
roles := []string{query.Role}
|
||||
if query.IsServerAdmin {
|
||||
roles = append(roles, "Grafana Admin")
|
||||
}
|
||||
|
||||
static := s.ac.GetStaticRoles(ctx)
|
||||
|
||||
var permissions []accesscontrol.Permission
|
||||
for _, name := range roles {
|
||||
r, ok := static[name]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, p := range r.Permissions {
|
||||
if p.Action == query.Action {
|
||||
permissions = append(permissions, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return permissions, nil
|
||||
}
|
||||
|
||||
var _ PermissionStore = (*UnionPermissionStore)(nil)
|
||||
|
||||
func NewUnionPermissionStore(stores ...PermissionStore) *UnionPermissionStore {
|
||||
return &UnionPermissionStore{stores}
|
||||
}
|
||||
|
||||
type UnionPermissionStore struct {
|
||||
stores []PermissionStore
|
||||
}
|
||||
|
||||
func (u *UnionPermissionStore) GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error) {
|
||||
var permissions []accesscontrol.Permission
|
||||
for _, s := range u.stores {
|
||||
result, err := s.GetUserPermissions(ctx, ns, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
permissions = append(permissions, result...)
|
||||
}
|
||||
return permissions, nil
|
||||
}
|
@ -14,7 +14,6 @@ var (
|
||||
sqlTemplatesFS embed.FS
|
||||
sqlTemplates = template.Must(template.New("sql").ParseFS(sqlTemplatesFS, `*.sql`))
|
||||
|
||||
sqlUserPerms = mustTemplate("permission_query.sql")
|
||||
sqlQueryBasicRoles = mustTemplate("basic_role_query.sql")
|
||||
sqlUserIdentifiers = mustTemplate("user_identifier_query.sql")
|
||||
sqlFolders = mustTemplate("folder_query.sql")
|
||||
@ -67,31 +66,6 @@ func newGetBasicRoles(sql *legacysql.LegacyDatabaseHelper, q *BasicRoleQuery) ge
|
||||
}
|
||||
}
|
||||
|
||||
type getPermissionsQuery struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *PermissionsQuery
|
||||
|
||||
PermissionTable string
|
||||
UserRoleTable string
|
||||
TeamRoleTable string
|
||||
BuiltinRoleTable string
|
||||
}
|
||||
|
||||
func (r getPermissionsQuery) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newGetPermissions(sql *legacysql.LegacyDatabaseHelper, q *PermissionsQuery) getPermissionsQuery {
|
||||
return getPermissionsQuery{
|
||||
SQLTemplate: sqltemplate.New(sql.DialectForDriver()),
|
||||
Query: q,
|
||||
PermissionTable: sql.Table("permission"),
|
||||
UserRoleTable: sql.Table("user_role"),
|
||||
TeamRoleTable: sql.Table("team_role"),
|
||||
BuiltinRoleTable: sql.Table("builtin_role"),
|
||||
}
|
||||
}
|
||||
|
||||
type getFoldersQuery struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *FolderQuery
|
||||
|
@ -7,13 +7,11 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error)
|
||||
GetUserIdentifiers(ctx context.Context, query UserIdentifierQuery) (*UserIdentifiers, error)
|
||||
GetBasicRoles(ctx context.Context, ns claims.NamespaceInfo, query BasicRoleQuery) (*BasicRole, error)
|
||||
GetFolders(ctx context.Context, ns claims.NamespaceInfo) ([]Folder, error)
|
||||
@ -31,44 +29,6 @@ func NewStore(sql legacysql.LegacyDatabaseProvider, tracer tracing.Tracer) *Stor
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StoreImpl) GetUserPermissions(ctx context.Context, ns claims.NamespaceInfo, query PermissionsQuery) ([]accesscontrol.Permission, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "authz_direct_db.database.GetUserPermissions")
|
||||
defer span.End()
|
||||
|
||||
sql, err := s.sql(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query.OrgID = ns.OrgID
|
||||
req := newGetPermissions(sql, &query)
|
||||
q, err := sqltemplate.Execute(sqlUserPerms, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := sql.DB.GetSqlxSession().Query(ctx, q, req.GetArgs()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if res != nil {
|
||||
_ = res.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
var perms []accesscontrol.Permission
|
||||
for res.Next() {
|
||||
var perm accesscontrol.Permission
|
||||
if err := res.Scan(&perm.Kind, &perm.Attribute, &perm.Identifier, &perm.Scope); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
perms = append(perms, perm)
|
||||
}
|
||||
|
||||
return perms, nil
|
||||
}
|
||||
|
||||
func (s *StoreImpl) GetUserIdentifiers(ctx context.Context, query UserIdentifierQuery) (*UserIdentifiers, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "authz_direct_db.database.GetUserIdentifiers")
|
||||
defer span.End()
|
||||
|
@ -8,12 +8,19 @@ import (
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/legacy"
|
||||
authzextv1 "github.com/grafana/grafana/pkg/services/authz/proto/v1"
|
||||
"github.com/grafana/grafana/pkg/services/authz/rbac"
|
||||
"github.com/grafana/grafana/pkg/services/authz/rbac/store"
|
||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
)
|
||||
|
||||
func RegisterRBACAuthZService(handler grpcserver.Provider, db legacysql.LegacyDatabaseProvider, tracer tracing.Tracer) {
|
||||
server := rbac.NewService(db, legacy.NewLegacySQLStores(db), log.New("authz-grpc-server"), tracer)
|
||||
server := rbac.NewService(
|
||||
db,
|
||||
legacy.NewLegacySQLStores(db),
|
||||
store.NewSQLPermissionStore(db, tracer),
|
||||
log.New("authz-grpc-server"),
|
||||
tracer,
|
||||
)
|
||||
|
||||
srv := handler.GetServer()
|
||||
authzv1.RegisterAuthzServiceServer(srv, server)
|
||||
|
@ -442,14 +442,7 @@ func (c *K8sTestHelper) LoadYAMLOrJSON(body string) *unstructured.Unstructured {
|
||||
func (c *K8sTestHelper) createTestUsers(orgName string) OrgUsers {
|
||||
c.t.Helper()
|
||||
users := OrgUsers{
|
||||
Admin: c.CreateUser("admin", orgName, org.RoleAdmin, []resourcepermissions.SetResourcePermissionCommand{
|
||||
{
|
||||
Actions: []string{"dashboards:read", "dashboards:write", "dashboards:create", "dashboards:delete"},
|
||||
Resource: "dashboards",
|
||||
ResourceAttribute: "uid",
|
||||
ResourceID: "*",
|
||||
},
|
||||
}),
|
||||
Admin: c.CreateUser("admin", orgName, org.RoleAdmin, nil),
|
||||
Editor: c.CreateUser("editor", orgName, org.RoleEditor, nil),
|
||||
Viewer: c.CreateUser("viewer", orgName, org.RoleViewer, nil),
|
||||
}
|
||||
|
Reference in New Issue
Block a user