The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/accesscontrol/mock/mock.go

266 lines
10 KiB

package mock
import (
"context"
"errors"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type fullAccessControl interface {
accesscontrol.AccessControl
accesscontrol.Service
plugins.RoleRegistry
RegisterFixedRoles(context.Context) error
}
type Calls struct {
Evaluate []interface{}
GetRoleByName []interface{}
GetUserPermissions []interface{}
ClearUserPermissionCache []interface{}
DeclareFixedRoles []interface{}
DeclarePluginRoles []interface{}
GetUserBuiltInRoles []interface{}
RegisterFixedRoles []interface{}
RegisterAttributeScopeResolver []interface{}
DeleteUserPermissions []interface{}
DeleteTeamPermissions []interface{}
SearchUsersPermissions []interface{}
SearchUserPermissions []interface{}
SaveExternalServiceRole []interface{}
DeleteExternalServiceRole []interface{}
}
type Mock struct {
// 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
builtInRoles []string
// Track the list of calls
Calls Calls
// Override functions
EvaluateFunc func(context.Context, identity.Requester, accesscontrol.Evaluator) (bool, error)
GetRoleByNameFunc func(context.Context, int64, string) (*accesscontrol.RoleDTO, error)
GetUserPermissionsFunc func(context.Context, identity.Requester, accesscontrol.Options) ([]accesscontrol.Permission, error)
ClearUserPermissionCacheFunc func(identity.Requester)
DeclareFixedRolesFunc func(...accesscontrol.RoleRegistration) error
DeclarePluginRolesFunc func(context.Context, string, string, []plugins.RoleRegistration) error
GetUserBuiltInRolesFunc func(user identity.Requester) []string
RegisterFixedRolesFunc func() error
RegisterScopeAttributeResolverFunc func(string, accesscontrol.ScopeAttributeResolver)
DeleteUserPermissionsFunc func(context.Context, int64) error
DeleteTeamPermissionsFunc func(context.Context, int64) error
SearchUsersPermissionsFunc func(context.Context, identity.Requester, int64, accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error)
SearchUserPermissionsFunc func(ctx context.Context, orgID int64, searchOptions accesscontrol.SearchOptions) ([]accesscontrol.Permission, error)
SaveExternalServiceRoleFunc func(ctx context.Context, cmd accesscontrol.SaveExternalServiceRoleCommand) error
DeleteExternalServiceRoleFunc func(ctx context.Context, externalServiceID string) error
SyncUserRolesFunc func(ctx context.Context, orgID int64, cmd accesscontrol.SyncUserRolesCommand) error
scopeResolvers accesscontrol.Resolvers
}
// Ensure the mock stays in line with the interface
var _ fullAccessControl = New()
// Deprecated: use fake service and real access control evaluator instead
func New() *Mock {
mock := &Mock{
Calls: Calls{},
permissions: []accesscontrol.Permission{},
builtInRoles: []string{},
scopeResolvers: accesscontrol.NewResolvers(log.NewNopLogger()),
}
return mock
}
func (m *Mock) GetRoleByName(ctx context.Context, orgID int64, roleName string) (*accesscontrol.RoleDTO, error) {
m.Calls.GetRoleByName = append(m.Calls.GetRoleByName, []interface{}{ctx, orgID, roleName})
if m.GetRoleByNameFunc != nil {
return m.GetRoleByNameFunc(ctx, orgID, roleName)
}
return nil, nil
}
func (m *Mock) GetUsageStats(ctx context.Context) map[string]interface{} {
return make(map[string]interface{})
}
func (m *Mock) WithPermissions(permissions []accesscontrol.Permission) *Mock {
m.permissions = permissions
return m
}
func (m *Mock) WithBuiltInRoles(builtInRoles []string) *Mock {
m.builtInRoles = builtInRoles
return m
}
// Evaluate evaluates access to the given resource.
// This mock uses GetUserPermissions to then call the evaluator Evaluate function.
func (m *Mock) Evaluate(ctx context.Context, usr identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) {
m.Calls.Evaluate = append(m.Calls.Evaluate, []interface{}{ctx, usr, evaluator})
// Use override if provided
if m.EvaluateFunc != nil {
return m.EvaluateFunc(ctx, usr, evaluator)
}
var permissions map[string][]string
permissions = usr.GetPermissions()
if len(permissions) == 0 {
userPermissions, err := m.GetUserPermissions(ctx, usr, accesscontrol.Options{ReloadCache: true})
if err != nil {
return false, err
}
permissions = accesscontrol.GroupScopesByAction(userPermissions)
}
if evaluator.Evaluate(permissions) {
return true, nil
}
resolvedEvaluator, err := evaluator.MutateScopes(ctx, m.scopeResolvers.GetScopeAttributeMutator(usr.GetOrgID()))
if err != nil {
if errors.Is(err, accesscontrol.ErrResolverNotFound) {
return false, nil
}
return false, err
}
return resolvedEvaluator.Evaluate(permissions), nil
}
// GetUserPermissions returns user permissions.
// This mock return m.permissions unless an override is provided.
func (m *Mock) GetUserPermissions(ctx context.Context, user identity.Requester, opts accesscontrol.Options) ([]accesscontrol.Permission, error) {
m.Calls.GetUserPermissions = append(m.Calls.GetUserPermissions, []interface{}{ctx, user, opts})
// Use override if provided
if m.GetUserPermissionsFunc != nil {
return m.GetUserPermissionsFunc(ctx, user, opts)
}
// Otherwise return the Permissions list
return m.permissions, nil
}
func (m *Mock) ClearUserPermissionCache(user identity.Requester) {
m.Calls.ClearUserPermissionCache = append(m.Calls.ClearUserPermissionCache, []interface{}{user})
// Use override if provided
if m.ClearUserPermissionCacheFunc != nil {
m.ClearUserPermissionCacheFunc(user)
}
}
// DeclareFixedRoles allow the caller to declare, to the service, fixed roles and their
// assignments to organization roles ("Viewer", "Editor", "Admin") or "Grafana Admin"
// This mock returns no error unless an override is provided.
func (m *Mock) DeclareFixedRoles(registrations ...accesscontrol.RoleRegistration) error {
m.Calls.DeclareFixedRoles = append(m.Calls.DeclareFixedRoles, []interface{}{registrations})
// Use override if provided
if m.DeclareFixedRolesFunc != nil {
return m.DeclareFixedRolesFunc(registrations...)
}
return nil
}
// RegisterFixedRoles registers all roles declared to AccessControl
// This mock returns no error unless an override is provided.
func (m *Mock) RegisterFixedRoles(ctx context.Context) error {
m.Calls.RegisterFixedRoles = append(m.Calls.RegisterFixedRoles, []struct{}{})
// Use override if provided
if m.RegisterFixedRolesFunc != nil {
return m.RegisterFixedRolesFunc()
}
return nil
}
// DeclarePluginRoles allow the caller to declare, to the service, plugin roles and their
// assignments to organization roles ("Viewer", "Editor", "Admin") or "Grafana Admin"
// This mock returns no error unless an override is provided.
func (m *Mock) DeclarePluginRoles(ctx context.Context, ID, name string, regs []plugins.RoleRegistration) error {
m.Calls.DeclarePluginRoles = append(m.Calls.DeclarePluginRoles, []interface{}{ctx, ID, name, regs})
// Use override if provided
if m.DeclarePluginRolesFunc != nil {
return m.DeclarePluginRolesFunc(ctx, ID, name, regs)
}
return nil
}
func (m *Mock) RegisterScopeAttributeResolver(scopePrefix string, resolver accesscontrol.ScopeAttributeResolver) {
m.scopeResolvers.AddScopeAttributeResolver(scopePrefix, resolver)
m.Calls.RegisterAttributeScopeResolver = append(m.Calls.RegisterAttributeScopeResolver, []struct{}{})
// Use override if provided
if m.RegisterScopeAttributeResolverFunc != nil {
m.RegisterScopeAttributeResolverFunc(scopePrefix, resolver)
}
}
func (m *Mock) DeleteUserPermissions(ctx context.Context, orgID, userID int64) error {
m.Calls.DeleteUserPermissions = append(m.Calls.DeleteUserPermissions, []interface{}{ctx, orgID, userID})
// Use override if provided
if m.DeleteUserPermissionsFunc != nil {
return m.DeleteUserPermissionsFunc(ctx, userID)
}
return nil
}
func (m *Mock) DeleteTeamPermissions(ctx context.Context, orgID, teamID int64) error {
m.Calls.DeleteTeamPermissions = append(m.Calls.DeleteTeamPermissions, []interface{}{ctx, orgID, teamID})
// Use override if provided
if m.DeleteTeamPermissionsFunc != nil {
return m.DeleteTeamPermissionsFunc(ctx, teamID)
}
return nil
}
// SearchUsersPermissions returns all users' permissions filtered by an action prefix
func (m *Mock) SearchUsersPermissions(ctx context.Context, usr identity.Requester, options accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error) {
user := usr.(*user.SignedInUser)
m.Calls.SearchUsersPermissions = append(m.Calls.SearchUsersPermissions, []interface{}{ctx, user, options})
// Use override if provided
if m.SearchUsersPermissionsFunc != nil {
return m.SearchUsersPermissionsFunc(ctx, user, usr.GetOrgID(), options)
}
return nil, nil
}
func (m *Mock) SearchUserPermissions(ctx context.Context, orgID int64, searchOptions accesscontrol.SearchOptions) ([]accesscontrol.Permission, error) {
m.Calls.SearchUserPermissions = append(m.Calls.SearchUserPermissions, []interface{}{ctx, orgID, searchOptions})
// Use override if provided
if m.SearchUserPermissionsFunc != nil {
return m.SearchUserPermissionsFunc(ctx, orgID, searchOptions)
}
return nil, nil
}
func (m *Mock) SaveExternalServiceRole(ctx context.Context, cmd accesscontrol.SaveExternalServiceRoleCommand) error {
m.Calls.SaveExternalServiceRole = append(m.Calls.SaveExternalServiceRole, []interface{}{ctx, cmd})
// Use override if provided
if m.SaveExternalServiceRoleFunc != nil {
return m.SaveExternalServiceRoleFunc(ctx, cmd)
}
return nil
}
func (m *Mock) DeleteExternalServiceRole(ctx context.Context, externalServiceID string) error {
m.Calls.DeleteExternalServiceRole = append(m.Calls.DeleteExternalServiceRole, []interface{}{ctx, externalServiceID})
// Use override if provided
if m.DeleteExternalServiceRoleFunc != nil {
return m.DeleteExternalServiceRoleFunc(ctx, externalServiceID)
}
return nil
}
func (m *Mock) SyncUserRoles(ctx context.Context, orgID int64, cmd accesscontrol.SyncUserRolesCommand) error {
if m.SyncUserRolesFunc != nil {
return m.SyncUserRolesFunc(ctx, orgID, cmd)
}
return nil
}