Move SignedInUser to user service and RoleType and Roles to org (#53445)

* Move SignedInUser to user service and RoleType and Roles to org

* Use go naming convention for roles

* Fix some imports and leftovers

* Fix ldap debug test

* Fix lint

* Fix lint 2

* Fix lint 3

* Fix type and not needed conversion

* Clean up messages in api tests

* Clean up api tests 2
This commit is contained in:
idafurjes
2022-08-10 11:56:48 +02:00
committed by GitHub
parent 46004037e2
commit 6afad51761
278 changed files with 1758 additions and 1543 deletions
+11 -9
View File
@@ -7,6 +7,8 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -18,10 +20,10 @@ type AccessControl interface {
registry.ProvidesUsageStats
// Evaluate evaluates access to the given resources.
Evaluate(ctx context.Context, user *models.SignedInUser, evaluator Evaluator) (bool, error)
Evaluate(ctx context.Context, user *user.SignedInUser, evaluator Evaluator) (bool, error)
// GetUserPermissions returns user permissions with only action and scope fields set.
GetUserPermissions(ctx context.Context, user *models.SignedInUser, options Options) ([]Permission, error)
GetUserPermissions(ctx context.Context, user *user.SignedInUser, options Options) ([]Permission, error)
//IsDisabled returns if access control is enabled or not
IsDisabled() bool
@@ -49,7 +51,7 @@ type PermissionsStore interface {
}
type TeamPermissionsService interface {
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]ResourcePermission, error)
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
}
@@ -71,7 +73,7 @@ type ServiceAccountPermissionsService interface {
type PermissionsService interface {
// GetPermissions returns all permissions for given resourceID
GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]ResourcePermission, error)
GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]ResourcePermission, error)
// SetUserPermission sets permission on resource for a user
SetUserPermission(ctx context.Context, orgID int64, user User, resourceID, permission string) (*ResourcePermission, error)
// SetTeamPermission sets permission on resource for a team
@@ -138,17 +140,17 @@ var ReqGrafanaAdmin = func(c *models.ReqContext) bool {
return c.IsGrafanaAdmin
}
// ReqViewer returns true if the current user has models.ROLE_VIEWER. Note: this can be anonymous user as well
// ReqViewer returns true if the current user has org.RoleViewer. Note: this can be anonymous user as well
var ReqViewer = func(c *models.ReqContext) bool {
return c.OrgRole.Includes(models.ROLE_VIEWER)
return c.OrgRole.Includes(org.RoleViewer)
}
var ReqOrgAdmin = func(c *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN
return c.OrgRole == org.RoleAdmin
}
var ReqOrgAdminOrEditor = func(c *models.ReqContext) bool {
return c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR
return c.OrgRole == org.RoleAdmin || c.OrgRole == org.RoleEditor
}
func BuildPermissionsMap(permissions []Permission) map[string]bool {
@@ -268,7 +270,7 @@ func IsDisabled(cfg *setting.Cfg) bool {
}
// GetOrgRoles returns legacy org roles for a user
func GetOrgRoles(cfg *setting.Cfg, user *models.SignedInUser) []string {
func GetOrgRoles(cfg *setting.Cfg, user *user.SignedInUser) []string {
roles := []string{string(user.OrgRole)}
// With built-in role simplifying, inheritance is performed upon role registration.
@@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
@@ -120,7 +121,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
}
var roles []string
role := models.RoleType(tt.role)
role := org.RoleType(tt.role)
if role.IsValid() {
roles = append(roles, string(role))
@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
@@ -118,7 +119,7 @@ func (s *AccessControlStore) SetBuiltInResourcePermission(
cmd types.SetResourcePermissionCommand,
hook types.BuiltinResourceHookFunc,
) (*accesscontrol.ResourcePermission, error) {
if !models.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
if !org.RoleType(builtInRole).IsValid() || builtInRole == accesscontrol.RoleGrafanaAdmin {
return nil, fmt.Errorf("invalid role: %s", builtInRole)
}
@@ -171,7 +172,7 @@ func (s *AccessControlStore) SetResourcePermissions(
p, err = s.setUserResourcePermission(sess, orgID, cmd.User, cmd.SetResourcePermissionCommand, hooks.User)
} else if cmd.TeamID != 0 {
p, err = s.setTeamResourcePermission(sess, orgID, cmd.TeamID, cmd.SetResourcePermissionCommand, hooks.Team)
} else if models.RoleType(cmd.BuiltinRole).IsValid() || cmd.BuiltinRole == accesscontrol.RoleGrafanaAdmin {
} else if org.RoleType(cmd.BuiltinRole).IsValid() || cmd.BuiltinRole == accesscontrol.RoleGrafanaAdmin {
p, err = s.setBuiltInResourcePermission(sess, orgID, cmd.BuiltinRole, cmd.SetResourcePermissionCommand, hooks.BuiltInRole)
}
if err != nil {
@@ -10,7 +10,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/datasources"
@@ -58,7 +57,7 @@ func getDSPermissions(b *testing.B, store *AccessControlStore, dataSources []int
dsId := dataSources[0]
permissions, err := store.GetResourcePermissions(context.Background(), accesscontrol.GlobalOrgID, types.GetResourcePermissionsQuery{
User: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
User: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: {"org.users:read": {"users:*"}, "teams:read": {"teams:*"}}}},
Actions: []string{dsAction},
Resource: dsResource,
ResourceID: strconv.Itoa(int(dsId)),
@@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/sqlstore"
@@ -338,7 +337,7 @@ func TestAccessControlStore_SetResourcePermissions(t *testing.T) {
type getResourcePermissionsTest struct {
desc string
user *models.SignedInUser
user *user.SignedInUser
numUsers int
actions []string
resource string
@@ -351,7 +350,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
tests := []getResourcePermissionsTest{
{
desc: "should return permissions for resource id",
user: &models.SignedInUser{
user: &user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},
@@ -364,7 +363,7 @@ func TestAccessControlStore_GetResourcePermissions(t *testing.T) {
},
{
desc: "should return manage permissions for all resource ids",
user: &models.SignedInUser{
user: &user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}},
+2 -2
View File
@@ -5,7 +5,7 @@ import (
"strconv"
"strings"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
var sqlIDAcceptList = map[string]struct{}{
@@ -33,7 +33,7 @@ type SQLFilter struct {
// Filter creates a where clause to restrict the view of a query based on a users permissions
// Scopes that exists for all actions will be parsed and compared against the supplied sqlID
// Prefix parameter is the prefix of the scope that we support (e.g. "users:id:")
func Filter(user *models.SignedInUser, sqlID, prefix string, actions ...string) (SQLFilter, error) {
func Filter(user *user.SignedInUser, sqlID, prefix string, actions ...string) (SQLFilter, error) {
if _, ok := sqlIDAcceptList[sqlID]; !ok {
return denyQuery, errors.New("sqlID is not in the accept list")
}
@@ -8,10 +8,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
func BenchmarkFilter10_10(b *testing.B) { benchmarkFilter(b, 10, 10) }
@@ -33,7 +33,7 @@ func benchmarkFilter(b *testing.B, numDs, numPermissions int) {
for i := 0; i < b.N; i++ {
baseSql := `SELECT data_source.* FROM data_source WHERE`
acFilter, err := accesscontrol.Filter(
&models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(permissions)}},
&user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(permissions)}},
"data_source.id",
"datasources:id:",
"datasources:read",
+2 -2
View File
@@ -8,10 +8,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type filterDatasourcesTestCase struct {
@@ -177,7 +177,7 @@ func TestFilter_Datasources(t *testing.T) {
baseSql := `SELECT data_source.* FROM data_source WHERE`
acFilter, err := accesscontrol.Filter(
&models.SignedInUser{
&user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{1: tt.permissions},
},
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@@ -25,7 +26,7 @@ func Middleware(ac AccessControl) func(web.Handler, Evaluator) web.Handler {
}
}
func authorize(c *models.ReqContext, ac AccessControl, user *models.SignedInUser, evaluator Evaluator) {
func authorize(c *models.ReqContext, ac AccessControl, user *user.SignedInUser, evaluator Evaluator) {
injected, err := evaluator.MutateScopes(c.Req.Context(), ScopeInjector(ScopeParams{
OrgID: c.OrgId,
URLParams: web.Params(c.Req),
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web"
)
@@ -87,7 +88,7 @@ func contextProvider() web.Handler {
reqCtx := &models.ReqContext{
Context: c,
Logger: log.New(""),
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
IsSignedIn: true,
SkipCache: true,
}
+8 -8
View File
@@ -3,13 +3,13 @@ package mock
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type fullAccessControl interface {
accesscontrol.AccessControl
GetUserBuiltInRoles(user *models.SignedInUser) []string
GetUserBuiltInRoles(user *user.SignedInUser) []string
RegisterFixedRoles(context.Context) error
}
@@ -36,11 +36,11 @@ type Mock struct {
Calls Calls
// Override functions
EvaluateFunc func(context.Context, *models.SignedInUser, accesscontrol.Evaluator) (bool, error)
GetUserPermissionsFunc func(context.Context, *models.SignedInUser, accesscontrol.Options) ([]accesscontrol.Permission, error)
EvaluateFunc func(context.Context, *user.SignedInUser, accesscontrol.Evaluator) (bool, error)
GetUserPermissionsFunc func(context.Context, *user.SignedInUser, accesscontrol.Options) ([]accesscontrol.Permission, error)
IsDisabledFunc func() bool
DeclareFixedRolesFunc func(...accesscontrol.RoleRegistration) error
GetUserBuiltInRolesFunc func(user *models.SignedInUser) []string
GetUserBuiltInRolesFunc func(user *user.SignedInUser) []string
RegisterFixedRolesFunc func() error
RegisterScopeAttributeResolverFunc func(string, accesscontrol.ScopeAttributeResolver)
DeleteUserPermissionsFunc func(context.Context, int64) error
@@ -84,7 +84,7 @@ func (m Mock) WithBuiltInRoles(builtInRoles []string) *Mock {
// 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, user *models.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
func (m *Mock) Evaluate(ctx context.Context, user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
m.Calls.Evaluate = append(m.Calls.Evaluate, []interface{}{ctx, user, evaluator})
// Use override if provided
if m.EvaluateFunc != nil {
@@ -114,7 +114,7 @@ func (m *Mock) Evaluate(ctx context.Context, user *models.SignedInUser, evaluato
// GetUserPermissions returns user permissions.
// This mock return m.permissions unless an override is provided.
func (m *Mock) GetUserPermissions(ctx context.Context, user *models.SignedInUser, opts accesscontrol.Options) ([]accesscontrol.Permission, error) {
func (m *Mock) GetUserPermissions(ctx context.Context, user *user.SignedInUser, 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 {
@@ -151,7 +151,7 @@ func (m *Mock) DeclareFixedRoles(registrations ...accesscontrol.RoleRegistration
// GetUserBuiltInRoles returns the list of organizational roles ("Viewer", "Editor", "Admin")
// or "Grafana Admin" associated to a user
// This mock returns m.builtInRoles unless an override is provided.
func (m *Mock) GetUserBuiltInRoles(user *models.SignedInUser) []string {
func (m *Mock) GetUserBuiltInRoles(user *user.SignedInUser) []string {
m.Calls.GetUserBuiltInRoles = append(m.Calls.GetUserBuiltInRoles, []interface{}{user})
// Use override if provided
@@ -5,8 +5,8 @@ import (
"github.com/stretchr/testify/mock"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
var _ accesscontrol.PermissionsService = new(MockPermissionsService)
@@ -19,7 +19,7 @@ type MockPermissionsService struct {
mock.Mock
}
func (m *MockPermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (m *MockPermissionsService) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
mockedArgs := m.Called(ctx, user, resourceID)
return mockedArgs.Get(0).([]accesscontrol.ResourcePermission), mockedArgs.Error(1)
}
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"strings"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/org"
)
// RoleRegistration stores a role and its assignments to built-in roles
@@ -410,7 +410,7 @@ func BuiltInRolesWithParents(builtInRoles []string) map[string]struct{} {
for _, br := range builtInRoles {
res[br] = struct{}{}
if br != RoleGrafanaAdmin {
for _, parent := range models.RoleType(br).Parents() {
for _, parent := range org.RoleType(br).Parents() {
res[string(parent)] = struct{}{}
}
}
@@ -6,10 +6,10 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/api"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus"
)
@@ -77,7 +77,7 @@ func (ac *OSSAccessControlService) getUsageMetrics() interface{} {
}
// Evaluate evaluates access to the given resources
func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error) {
timer := prometheus.NewTimer(metrics.MAccessEvaluationsSummary)
defer timer.ObserveDuration()
metrics.MAccessEvaluationCount.Inc()
@@ -103,7 +103,7 @@ func (ac *OSSAccessControlService) Evaluate(ctx context.Context, user *models.Si
}
// GetUserPermissions returns user permissions based on built-in roles
func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user *models.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user *user.SignedInUser, _ accesscontrol.Options) ([]accesscontrol.Permission, error) {
timer := prometheus.NewTimer(metrics.MAccessPermissionsSummary)
defer timer.ObserveDuration()
@@ -132,7 +132,7 @@ func (ac *OSSAccessControlService) GetUserPermissions(ctx context.Context, user
return permissions, nil
}
func (ac *OSSAccessControlService) getFixedPermissions(ctx context.Context, user *models.SignedInUser) []accesscontrol.Permission {
func (ac *OSSAccessControlService) getFixedPermissions(ctx context.Context, user *user.SignedInUser) []accesscontrol.Permission {
permissions := make([]accesscontrol.Permission, 0)
for _, builtin := range accesscontrol.GetOrgRoles(ac.cfg, user) {
@@ -13,7 +13,9 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/database"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -52,7 +54,7 @@ type evaluatingPermissionsTestCase struct {
type userTestCase struct {
name string
orgRole models.RoleType
orgRole org.RoleType
isGrafanaAdmin bool
}
@@ -66,7 +68,7 @@ func TestEvaluatingPermissions(t *testing.T) {
desc: "should successfully evaluate access to the endpoint",
user: userTestCase{
name: "testuser",
orgRole: models.ROLE_VIEWER,
orgRole: org.RoleViewer,
isGrafanaAdmin: true,
},
endpoints: []endpointTestCase{
@@ -79,7 +81,7 @@ func TestEvaluatingPermissions(t *testing.T) {
desc: "should restrict access to the unauthorized endpoints",
user: userTestCase{
name: "testuser",
orgRole: models.ROLE_VIEWER,
orgRole: org.RoleViewer,
isGrafanaAdmin: false,
},
endpoints: []endpointTestCase{
@@ -99,7 +101,7 @@ func TestEvaluatingPermissions(t *testing.T) {
errRegisterRoles := ac.RegisterFixedRoles(context.Background())
require.NoError(t, errRegisterRoles)
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: 1,
OrgId: 1,
Name: tc.user.name,
@@ -357,11 +359,11 @@ func TestOSSAccessControlService_RegisterFixedRoles(t *testing.T) {
}
func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
testUser := models.SignedInUser{
testUser := user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",
@@ -377,7 +379,7 @@ func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
}
tests := []struct {
name string
user models.SignedInUser
user user.SignedInUser
rawPerm accesscontrol.Permission
wantPerm accesscontrol.Permission
wantErr bool
@@ -419,11 +421,11 @@ func TestOSSAccessControlService_GetUserPermissions(t *testing.T) {
}
func TestOSSAccessControlService_Evaluate(t *testing.T) {
testUser := models.SignedInUser{
testUser := user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",
@@ -446,7 +448,7 @@ func TestOSSAccessControlService_Evaluate(t *testing.T) {
tests := []struct {
name string
user models.SignedInUser
user user.SignedInUser
rawPerm accesscontrol.Permission
evaluator accesscontrol.Evaluator
wantAccess bool
@@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -235,7 +236,7 @@ var _ accesscontrol.DatasourcePermissionsService = new(DatasourcePermissionsServ
type DatasourcePermissionsService struct{}
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (e DatasourcePermissionsService) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
return nil, nil
}
+6 -6
View File
@@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
const (
@@ -60,7 +60,7 @@ func (s *ScopeResolvers) GetScopeAttributeMutator(orgID int64) ScopeAttributeMut
}
}
func (s *ScopeResolvers) GetScopeKeywordMutator(user *models.SignedInUser) ScopeKeywordMutator {
func (s *ScopeResolvers) GetScopeKeywordMutator(user *user.SignedInUser) ScopeKeywordMutator {
return func(ctx context.Context, scope string) (string, error) {
if resolver, ok := s.keywordResolvers[scope]; ok {
scopes, err := resolver.Resolve(ctx, user)
@@ -103,13 +103,13 @@ type ScopeAttributeMutator func(context.Context, string) ([]string, error)
// ScopeKeywordResolver is used to resolve keywords in scopes e.g. "users:self" -> "user:id:1".
// These type of resolvers is used when fetching stored permissions
type ScopeKeywordResolver interface {
Resolve(ctx context.Context, user *models.SignedInUser) (string, error)
Resolve(ctx context.Context, user *user.SignedInUser) (string, error)
}
// ScopeKeywordResolverFunc is an adapter to allow functions to implement ScopeKeywordResolver interface
type ScopeKeywordResolverFunc func(ctx context.Context, user *models.SignedInUser) (string, error)
type ScopeKeywordResolverFunc func(ctx context.Context, user *user.SignedInUser) (string, error)
func (f ScopeKeywordResolverFunc) Resolve(ctx context.Context, user *models.SignedInUser) (string, error) {
func (f ScopeKeywordResolverFunc) Resolve(ctx context.Context, user *user.SignedInUser) (string, error) {
return f(ctx, user)
}
@@ -135,6 +135,6 @@ func ScopeInjector(params ScopeParams) ScopeAttributeMutator {
}
}
var userSelfResolver = ScopeKeywordResolverFunc(func(ctx context.Context, user *models.SignedInUser) (string, error) {
var userSelfResolver = ScopeKeywordResolverFunc(func(ctx context.Context, user *user.SignedInUser) (string, error) {
return Scope("users", "id", fmt.Sprintf("%v", user.UserId)), nil
})
+5 -4
View File
@@ -6,15 +6,16 @@ import (
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
func TestResolveKeywordScope(t *testing.T) {
tests := []struct {
name string
user *models.SignedInUser
user *user.SignedInUser
permission accesscontrol.Permission
want accesscontrol.Permission
wantErr bool
@@ -50,11 +51,11 @@ func TestResolveKeywordScope(t *testing.T) {
}
}
var testUser = &models.SignedInUser{
var testUser = &user.SignedInUser{
UserId: 2,
OrgId: 3,
OrgName: "TestOrg",
OrgRole: models.ROLE_VIEWER,
OrgRole: org.RoleViewer,
Login: "testUser",
Name: "Test User",
Email: "testuser@example.org",
@@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/web"
)
@@ -97,7 +98,7 @@ func (a *api) getPermissions(c *models.ReqContext) response.Response {
permissions = append(permissions, accesscontrol.ResourcePermission{
Actions: a.service.actions,
Scope: "*",
BuiltInRole: string(models.ROLE_ADMIN),
BuiltInRole: string(org.RoleAdmin),
})
}
@@ -113,7 +113,7 @@ func TestApi_getDescription(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, _ := setupTestEnvironment(t, tt.permissions, tt.options)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1}, service)
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/access-control/%s/description", tt.options.Resource), nil)
require.NoError(t, err)
@@ -160,7 +160,7 @@ func TestApi_getPermissions(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
seedPermissions(t, tt.resourceID, sql, service)
@@ -237,7 +237,7 @@ func TestApi_setBuiltinRolePermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, _ := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
recorder := setPermission(t, server, testOptions.Resource, tt.resourceID, tt.permission, "builtInRoles", tt.builtInRole)
assert.Equal(t, tt.expectedStatus, recorder.Code)
@@ -315,7 +315,7 @@ func TestApi_setTeamPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed team
_, err := sql.CreateTeam("test", "test@test.com", 1)
@@ -398,7 +398,7 @@ func TestApi_setUserPermission(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
service, sql := setupTestEnvironment(t, tt.permissions, testOptions)
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
server := setupTestServer(t, &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed user
_, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "test", OrgID: 1})
@@ -418,7 +418,7 @@ func TestApi_setUserPermission(t *testing.T) {
}
}
func setupTestServer(t *testing.T, user *models.SignedInUser, service *Service) *web.Mux {
func setupTestServer(t *testing.T, user *user.SignedInUser, service *Service) *web.Mux {
server := web.New()
server.UseMiddleware(web.Renderer(path.Join(setting.StaticRootPath, "views"), "[[", "]]"))
server.Use(contextProvider(&testContext{user}))
@@ -427,7 +427,7 @@ func setupTestServer(t *testing.T, user *models.SignedInUser, service *Service)
}
type testContext struct {
user *models.SignedInUser
user *user.SignedInUser
}
func contextProvider(tc *testContext) web.Handler {
@@ -9,7 +9,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -105,7 +107,7 @@ type Service struct {
sqlStore *sqlstore.SQLStore
}
func (s *Service) GetPermissions(ctx context.Context, user *models.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
func (s *Service) GetPermissions(ctx context.Context, user *user.SignedInUser, resourceID string) ([]accesscontrol.ResourcePermission, error) {
var inheritedScopes []string
if s.options.InheritedScopesSolver != nil {
var err error
@@ -318,7 +320,7 @@ func (s *Service) declareFixedRoles() error {
{Action: fmt.Sprintf("%s.permissions:read", s.options.Resource), Scope: scopeAll},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
writerRole := accesscontrol.RoleRegistration{
@@ -330,7 +332,7 @@ func (s *Service) declareFixedRoles() error {
{Action: fmt.Sprintf("%s.permissions:write", s.options.Resource), Scope: scopeAll},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
return s.ac.DeclareFixedRoles(readerRole, writerRole)
@@ -1,8 +1,8 @@
package types
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type SetResourcePermissionCommand struct {
@@ -28,5 +28,5 @@ type GetResourcePermissionsQuery struct {
ResourceAttribute string
OnlyManaged bool
InheritedScopes []string
User *models.SignedInUser
User *user.SignedInUser
}
+10 -10
View File
@@ -5,7 +5,7 @@ import (
"strings"
"sync"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
)
// Roles definition
@@ -181,11 +181,11 @@ func DeclareFixedRoles(ac AccessControl) error {
}
orgUsersReader := RoleRegistration{
Role: orgUsersReaderRole,
Grants: []string{RoleGrafanaAdmin, string(models.ROLE_ADMIN)},
Grants: []string{RoleGrafanaAdmin, string(org.RoleAdmin)},
}
orgUsersWriter := RoleRegistration{
Role: orgUsersWriterRole,
Grants: []string{RoleGrafanaAdmin, string(models.ROLE_ADMIN)},
Grants: []string{RoleGrafanaAdmin, string(org.RoleAdmin)},
}
settingsReader := RoleRegistration{
Role: SettingsReaderRole,
@@ -232,7 +232,7 @@ func ValidateFixedRole(role RoleDTO) error {
// ValidateBuiltInRoles errors when a built-in role does not match expected pattern
func ValidateBuiltInRoles(builtInRoles []string) error {
for _, br := range builtInRoles {
if !models.RoleType(br).IsValid() && br != RoleGrafanaAdmin {
if !org.RoleType(br).IsValid() && br != RoleGrafanaAdmin {
return fmt.Errorf("'%s' %w", br, ErrInvalidBuiltinRole)
}
}
@@ -262,34 +262,34 @@ func (m *RegistrationList) Range(f func(registration RoleRegistration) bool) {
func BuildBasicRoleDefinitions() map[string]*RoleDTO {
return map[string]*RoleDTO{
string(models.ROLE_ADMIN): {
string(org.RoleAdmin): {
Name: BasicRolePrefix + "admin",
UID: BasicRoleUIDPrefix + "admin",
OrgID: GlobalOrgID,
Version: 1,
DisplayName: string(models.ROLE_ADMIN),
DisplayName: string(org.RoleAdmin),
Description: "Admin role",
Group: "Basic",
Permissions: []Permission{},
Hidden: true,
},
string(models.ROLE_EDITOR): {
string(org.RoleEditor): {
Name: BasicRolePrefix + "editor",
UID: BasicRoleUIDPrefix + "editor",
OrgID: GlobalOrgID,
Version: 1,
DisplayName: string(models.ROLE_EDITOR),
DisplayName: string(org.RoleEditor),
Description: "Editor role",
Group: "Basic",
Permissions: []Permission{},
Hidden: true,
},
string(models.ROLE_VIEWER): {
string(org.RoleViewer): {
Name: BasicRolePrefix + "viewer",
UID: BasicRoleUIDPrefix + "viewer",
OrgID: GlobalOrgID,
Version: 1,
DisplayName: string(models.ROLE_VIEWER),
DisplayName: string(org.RoleViewer),
Description: "Viewer role",
Group: "Basic",
Permissions: []Permission{},
+2 -1
View File
@@ -5,6 +5,7 @@ import (
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// Job holds state about when the alert rule should be evaluated.
@@ -45,7 +46,7 @@ type EvalMatch struct {
}
type DashAlertInfo struct {
User *models.SignedInUser
User *user.SignedInUser
Dash *models.Dashboard
OrgID int64
}
+2 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/setting"
)
@@ -210,7 +211,7 @@ func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout
},
AuthOpts: rendering.AuthOpts{
OrgID: evalCtx.Rule.OrgID,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
Width: 1000,
Height: 500,
+2 -1
View File
@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/setting"
@@ -154,7 +155,7 @@ func (ss *sqlStore) HandleAlertsQuery(ctx context.Context, query *models.GetAler
builder.Write(")")
}
if query.User.OrgRole != models.ROLE_ADMIN {
if query.User.OrgRole != org.RoleAdmin {
builder.WriteDashboardPermissionFilter(query.User, models.PERMISSION_VIEW)
}
+10 -8
View File
@@ -10,8 +10,10 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@@ -74,7 +76,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
setup(t)
// Get alert so we can use its ID in tests
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &alertQuery)
require.Nil(t, err2)
@@ -131,7 +133,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
t.Run("Can read properties", func(t *testing.T) {
setup(t)
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &alertQuery)
alert := alertQuery.Result[0]
@@ -152,7 +154,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
t.Run("Viewer can read alerts", func(t *testing.T) {
setup(t)
viewerUser := &models.SignedInUser{OrgRole: models.ROLE_VIEWER, OrgId: 1}
viewerUser := &user.SignedInUser{OrgRole: org.RoleViewer, OrgId: 1}
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: viewerUser}
err2 := store.HandleAlertsQuery(context.Background(), &alertQuery)
@@ -172,7 +174,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
})
t.Run("Alerts should be updated", func(t *testing.T) {
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &query)
require.Nil(t, err2)
@@ -221,7 +223,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
t.Run("Should save 3 dashboards", func(t *testing.T) {
require.Nil(t, err)
queryForDashboard := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
queryForDashboard := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &queryForDashboard)
require.Nil(t, err2)
@@ -234,7 +236,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
err = store.SaveAlerts(context.Background(), testDash.Id, missingOneAlert)
t.Run("should delete the missing alert", func(t *testing.T) {
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &query)
require.Nil(t, err2)
require.Equal(t, 2, len(query.Result))
@@ -264,7 +266,7 @@ func TestIntegrationAlertingDataAccess(t *testing.T) {
require.Nil(t, err)
t.Run("Alerts should be removed", func(t *testing.T) {
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := store.HandleAlertsQuery(context.Background(), &query)
require.Nil(t, err2)
@@ -291,7 +293,7 @@ func TestIntegrationPausingAlerts(t *testing.T) {
stateDateAfterPause := stateDateBeforePause
// Get alert so we can use its ID in tests
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &user.SignedInUser{OrgRole: org.RoleAdmin}}
err2 := sqlStore.HandleAlertsQuery(context.Background(), &alertQuery)
require.Nil(t, err2)
+2 -1
View File
@@ -6,10 +6,11 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// AlertTest makes a test alert.
func (e *AlertEngine) AlertTest(orgID int64, dashboard *simplejson.Json, panelID int64, user *models.SignedInUser) (*EvalContext, error) {
func (e *AlertEngine) AlertTest(orgID int64, dashboard *simplejson.Json, panelID int64, user *user.SignedInUser) (*EvalContext, error) {
dash := models.NewDashboardFromJson(dashboard)
dashInfo := DashAlertInfo{
User: user,
+2 -2
View File
@@ -5,7 +5,7 @@ import (
"errors"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -39,7 +39,7 @@ type ItemQuery struct {
Tags []string `json:"tags"`
Type string `json:"type"`
MatchAny bool `json:"matchAny"`
SignedInUser *models.SignedInUser
SignedInUser *user.SignedInUser
Limit int64 `json:"limit"`
}
+6 -6
View File
@@ -9,10 +9,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/apikey"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
func mockTimeNow() {
@@ -141,7 +141,7 @@ func TestIntegrationApiKeyDataAccess(t *testing.T) {
// advance mocked getTime by 1s
timeNow()
testUser := &models.SignedInUser{
testUser := &user.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{
1: {accesscontrol.ActionAPIKeyRead: []string{accesscontrol.ScopeAPIKeysAll}},
@@ -208,7 +208,7 @@ func TestIntegrationApiKeyErrors(t *testing.T) {
type getApiKeysTestCase struct {
desc string
user *models.SignedInUser
user *user.SignedInUser
expectedNumKeys int
}
@@ -219,21 +219,21 @@ func TestIntegrationSQLStore_GetAPIKeys(t *testing.T) {
tests := []getApiKeysTestCase{
{
desc: "expect all keys for wildcard scope",
user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
1: {"apikeys:read": {"apikeys:*"}},
}},
expectedNumKeys: 10,
},
{
desc: "expect only api keys that user have scopes for",
user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
1: {"apikeys:read": {"apikeys:id:1", "apikeys:id:3"}},
}},
expectedNumKeys: 2,
},
{
desc: "expect no keys when user have no scopes",
user: &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
user: &user.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{
1: {"apikeys:read": {}},
}},
expectedNumKeys: 0,
+10 -9
View File
@@ -4,7 +4,8 @@ import (
"errors"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
var (
@@ -19,7 +20,7 @@ type APIKey struct {
OrgId int64
Name string
Key string
Role models.RoleType
Role org.RoleType
Created time.Time
Updated time.Time
LastUsedAt *time.Time `xorm:"last_used_at"`
@@ -31,12 +32,12 @@ func (k APIKey) TableName() string { return "api_key" }
// swagger:model
type AddCommand struct {
Name string `json:"name" binding:"Required"`
Role models.RoleType `json:"role" binding:"Required"`
OrgId int64 `json:"-"`
Key string `json:"-"`
SecondsToLive int64 `json:"secondsToLive"`
Result *APIKey `json:"-"`
Name string `json:"name" binding:"Required"`
Role org.RoleType `json:"role" binding:"Required"`
OrgId int64 `json:"-"`
Key string `json:"-"`
SecondsToLive int64 `json:"secondsToLive"`
Result *APIKey `json:"-"`
}
type DeleteCommand struct {
@@ -47,7 +48,7 @@ type DeleteCommand struct {
type GetApiKeysQuery struct {
OrgId int64
IncludeExpired bool
User *models.SignedInUser
User *user.SignedInUser
Result []*APIKey
}
type GetByNameQuery struct {
@@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type PermissionChecker struct {
@@ -42,7 +43,7 @@ func (c *PermissionChecker) getDashboardById(ctx context.Context, orgID int64, i
return query.Result, nil
}
func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int64, signedInUser *models.SignedInUser, objectType string, objectID string) (bool, error) {
func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int64, signedInUser *user.SignedInUser, objectType string, objectID string) (bool, error) {
switch objectType {
case ObjectTypeOrg:
return false, nil
@@ -89,7 +90,7 @@ func (c *PermissionChecker) CheckReadPermissions(ctx context.Context, orgId int6
return true, nil
}
func (c *PermissionChecker) CheckWritePermissions(ctx context.Context, orgId int64, signedInUser *models.SignedInUser, objectType string, objectID string) (bool, error) {
func (c *PermissionChecker) CheckWritePermissions(ctx context.Context, orgId int64, signedInUser *user.SignedInUser, objectType string, objectID string) (bool, error) {
switch objectType {
case ObjectTypeOrg:
return false, nil
+3 -2
View File
@@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/comments/commentmodel"
"github.com/grafana/grafana/pkg/services/user"
)
func commentsToDto(items []*commentmodel.Comment, userMap map[int64]*commentmodel.CommentUser) []*commentmodel.CommentDto {
@@ -86,7 +87,7 @@ type CreateCmd struct {
var ErrPermissionDenied = errors.New("permission denied")
func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, cmd CreateCmd) (*commentmodel.CommentDto, error) {
func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, cmd CreateCmd) (*commentmodel.CommentDto, error) {
ok, err := s.permissions.CheckWritePermissions(ctx, orgID, signedInUser, cmd.ObjectType, cmd.ObjectID)
if err != nil {
return nil, err
@@ -120,7 +121,7 @@ func (s *Service) Create(ctx context.Context, orgID int64, signedInUser *models.
return mDto, nil
}
func (s *Service) Get(ctx context.Context, orgID int64, signedInUser *models.SignedInUser, cmd GetCmd) ([]*commentmodel.CommentDto, error) {
func (s *Service) Get(ctx context.Context, orgID int64, signedInUser *user.SignedInUser, cmd GetCmd) ([]*commentmodel.CommentDto, error) {
ok, err := s.permissions.CheckReadPermissions(ctx, orgID, signedInUser, cmd.ObjectType, cmd.ObjectID)
if err != nil {
return nil, err
@@ -99,7 +99,7 @@ func (f *FakeGetSignUserStore) GetSignedInUser(ctx context.Context, query *model
return user.ErrUserNotFound
}
query.Result = &models.SignedInUser{
query.Result = &user.SignedInUser{
UserId: userID,
OrgId: orgID,
}
@@ -19,7 +19,9 @@ import (
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@@ -284,9 +286,9 @@ func (auth *AuthProxy) loginViaHeader(reqCtx *models.ReqContext) (int64, error)
case "Role":
// If Role header is specified, we update the user role of the default org
if header != "" {
rt := models.RoleType(header)
rt := org.RoleType(header)
if rt.IsValid() {
extUser.OrgRoles = map[int64]models.RoleType{}
extUser.OrgRoles = map[int64]org.RoleType{}
orgID := int64(1)
if setting.AutoAssignOrg && setting.AutoAssignOrgId > 0 {
orgID = int64(setting.AutoAssignOrgId)
@@ -344,7 +346,7 @@ func (auth *AuthProxy) headersIterator(reqCtx *models.ReqContext, fn func(field
}
// GetSignedInUser gets full signed in user info.
func (auth *AuthProxy) GetSignedInUser(userID int64, orgID int64) (*models.SignedInUser, error) {
func (auth *AuthProxy) GetSignedInUser(userID int64, orgID int64) (*user.SignedInUser, error) {
query := &models.GetSignedInUserQuery{
OrgId: orgID,
UserId: userID,
+10 -9
View File
@@ -23,6 +23,7 @@ import (
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -96,7 +97,7 @@ func (h *ContextHandler) Middleware(mContext *web.Context) {
reqContext := &models.ReqContext{
Context: mContext,
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
IsSignedIn: false,
AllowAnonymous: false,
SkipCache: false,
@@ -177,7 +178,7 @@ func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqCont
_, span := h.tracer.Start(reqContext.Req.Context(), "initContextWithAnonymousUser")
defer span.End()
org, err := h.SQLStore.GetOrgByName(h.Cfg.AnonymousOrgName)
orga, err := h.SQLStore.GetOrgByName(h.Cfg.AnonymousOrgName)
if err != nil {
reqContext.Logger.Error("Anonymous access organization error.", "org_name", h.Cfg.AnonymousOrgName, "error", err)
return false
@@ -185,10 +186,10 @@ func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqCont
reqContext.IsSignedIn = false
reqContext.AllowAnonymous = true
reqContext.SignedInUser = &models.SignedInUser{IsAnonymous: true}
reqContext.OrgRole = models.RoleType(h.Cfg.AnonymousOrgRole)
reqContext.OrgId = org.Id
reqContext.OrgName = org.Name
reqContext.SignedInUser = &user.SignedInUser{IsAnonymous: true}
reqContext.OrgRole = org.RoleType(h.Cfg.AnonymousOrgRole)
reqContext.OrgId = orga.Id
reqContext.OrgName = orga.Name
return true
}
@@ -288,7 +289,7 @@ func (h *ContextHandler) initContextWithAPIKey(reqContext *models.ReqContext) bo
if apikey.ServiceAccountId == nil || *apikey.ServiceAccountId < 1 { //There is no service account attached to the apikey
//Use the old APIkey method. This provides backwards compatibility.
reqContext.SignedInUser = &models.SignedInUser{}
reqContext.SignedInUser = &user.SignedInUser{}
reqContext.OrgRole = apikey.Role
reqContext.ApiKeyId = apikey.Id
reqContext.OrgId = apikey.OrgId
@@ -466,10 +467,10 @@ func (h *ContextHandler) initContextWithRenderAuth(reqContext *models.ReqContext
return true
}
reqContext.SignedInUser = &models.SignedInUser{
reqContext.SignedInUser = &user.SignedInUser{
OrgId: renderUser.OrgID,
UserId: renderUser.UserID,
OrgRole: models.RoleType(renderUser.OrgRole),
OrgRole: org.RoleType(renderUser.OrgRole),
}
// UserID can be 0 for background tasks and, in this case, there is no user info to retrieve
+6 -5
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/models"
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/dashboardimport"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/web/webtest"
"github.com/stretchr/testify/require"
)
@@ -50,7 +51,7 @@ func TestImportDashboardAPI(t *testing.T) {
jsonBytes, err := json.Marshal(cmd)
require.NoError(t, err)
req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
UserId: 1,
})
resp, err := s.SendJSON(req)
@@ -66,7 +67,7 @@ func TestImportDashboardAPI(t *testing.T) {
jsonBytes, err := json.Marshal(cmd)
require.NoError(t, err)
req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
UserId: 1,
})
resp, err := s.SendJSON(req)
@@ -83,7 +84,7 @@ func TestImportDashboardAPI(t *testing.T) {
jsonBytes, err := json.Marshal(cmd)
require.NoError(t, err)
req := s.NewPostRequest("/api/dashboards/import?trimdefaults=true", bytes.NewReader(jsonBytes))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
UserId: 1,
})
resp, err := s.SendJSON(req)
@@ -115,7 +116,7 @@ func TestImportDashboardAPI(t *testing.T) {
jsonBytes, err := json.Marshal(cmd)
require.NoError(t, err)
req := s.NewPostRequest("/api/dashboards/import?trimdefaults=true", bytes.NewReader(jsonBytes))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
UserId: 1,
})
resp, err := s.SendJSON(req)
@@ -141,7 +142,7 @@ func TestImportDashboardAPI(t *testing.T) {
jsonBytes, err := json.Marshal(cmd)
require.NoError(t, err)
req := s.NewPostRequest("/api/dashboards/import", bytes.NewReader(jsonBytes))
webtest.RequestWithSignedInUser(req, &models.SignedInUser{
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
UserId: 1,
})
resp, err := s.SendJSON(req)
@@ -4,7 +4,7 @@ import (
"context"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// ImportDashboardInput definition of input parameters when importing a dashboard.
@@ -25,7 +25,7 @@ type ImportDashboardRequest struct {
FolderId int64 `json:"folderId"`
FolderUid string `json:"folderUid"`
User *models.SignedInUser `json:"-"`
User *user.SignedInUser `json:"-"`
}
// ImportDashboardResponse response object returned when importing a dashboard.
@@ -11,7 +11,9 @@ import (
"github.com/grafana/grafana/pkg/services/dashboardimport"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/librarypanels"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/plugindashboards"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@@ -42,11 +44,11 @@ func TestImportDashboardService(t *testing.T) {
importLibraryPanelsForDashboard := false
connectLibraryPanelsForDashboardCalled := false
libraryPanelService := &libraryPanelServiceMock{
importLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
importLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
importLibraryPanelsForDashboard = true
return nil
},
connectLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error {
connectLibraryPanelsForDashboardFunc: func(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
connectLibraryPanelsForDashboardCalled = true
return nil
},
@@ -63,7 +65,7 @@ func TestImportDashboardService(t *testing.T) {
Inputs: []dashboardimport.ImportDashboardInput{
{Name: "*", Type: "datasource", Value: "prom"},
},
User: &models.SignedInUser{UserId: 2, OrgRole: models.ROLE_ADMIN, OrgId: 3},
User: &user.SignedInUser{UserId: 2, OrgRole: org.RoleAdmin, OrgId: 3},
FolderId: 5,
}
resp, err := s.ImportDashboard(context.Background(), req)
@@ -120,7 +122,7 @@ func TestImportDashboardService(t *testing.T) {
Inputs: []dashboardimport.ImportDashboardInput{
{Name: "*", Type: "datasource", Value: "prom"},
},
User: &models.SignedInUser{UserId: 2, OrgRole: models.ROLE_ADMIN, OrgId: 3},
User: &user.SignedInUser{UserId: 2, OrgRole: org.RoleAdmin, OrgId: 3},
FolderId: 5,
}
resp, err := s.ImportDashboard(context.Background(), req)
@@ -185,11 +187,11 @@ func (s *dashboardServiceMock) ImportDashboard(ctx context.Context, dto *dashboa
type libraryPanelServiceMock struct {
librarypanels.Service
connectLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error
importLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error
connectLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error
importLibraryPanelsForDashboardFunc func(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error
}
func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error {
func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
if s.connectLibraryPanelsForDashboardFunc != nil {
return s.connectLibraryPanelsForDashboardFunc(ctx, signedInUser, dash)
}
@@ -197,7 +199,7 @@ func (s *libraryPanelServiceMock) ConnectLibraryPanelsForDashboard(ctx context.C
return nil
}
func (s *libraryPanelServiceMock) ImportLibraryPanelsForDashboard(ctx context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
func (s *libraryPanelServiceMock) ImportLibraryPanelsForDashboard(ctx context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
if s.importLibraryPanelsForDashboardFunc != nil {
return s.importLibraryPanelsForDashboardFunc(ctx, signedInUser, libraryPanels, panels, folderID)
}
+3 -2
View File
@@ -4,6 +4,7 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
@@ -97,7 +98,7 @@ func (d *DashboardStore) GetDashboardACLInfoList(ctx context.Context, query *mod
// HasEditPermissionInFolders validates that an user have access to a certain folder
func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
return d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
if query.SignedInUser.HasRole(models.ROLE_EDITOR) {
if query.SignedInUser.HasRole(org.RoleEditor) {
query.Result = true
return nil
}
@@ -125,7 +126,7 @@ func (d *DashboardStore) HasEditPermissionInFolders(ctx context.Context, query *
func (d *DashboardStore) HasAdminPermissionInDashboardsOrFolders(ctx context.Context, query *models.HasAdminPermissionInDashboardsOrFoldersQuery) error {
return d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
if query.SignedInUser.HasRole(models.ROLE_ADMIN) {
if query.SignedInUser.HasRole(org.RoleAdmin) {
query.Result = true
return nil
}
+10 -9
View File
@@ -5,6 +5,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
@@ -47,10 +48,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) {
require.Equal(t, 2, len(query.Result))
defaultPermissionsId := int64(-1)
require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId)
require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role)
require.Equal(t, org.RoleViewer, *query.Result[0].Role)
require.False(t, query.Result[0].Inherited)
require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId)
require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role)
require.Equal(t, org.RoleEditor, *query.Result[1].Role)
require.False(t, query.Result[1].Inherited)
})
@@ -64,10 +65,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) {
require.Equal(t, 2, len(query.Result))
defaultPermissionsId := int64(-1)
require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId)
require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role)
require.Equal(t, org.RoleViewer, *query.Result[0].Role)
require.True(t, query.Result[0].Inherited)
require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId)
require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role)
require.Equal(t, org.RoleEditor, *query.Result[1].Role)
require.True(t, query.Result[1].Inherited)
})
@@ -146,10 +147,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) {
defaultPermissionsId := int64(-1)
require.Equal(t, 3, len(query.Result))
require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId)
require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role)
require.Equal(t, org.RoleViewer, *query.Result[0].Role)
require.True(t, query.Result[0].Inherited)
require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId)
require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role)
require.Equal(t, org.RoleEditor, *query.Result[1].Role)
require.True(t, query.Result[1].Inherited)
require.Equal(t, childDash.Id, query.Result[2].DashboardId)
require.False(t, query.Result[2].Inherited)
@@ -241,10 +242,10 @@ func TestIntegrationDashboardACLDataAccess(t *testing.T) {
require.Equal(t, 2, len(query.Result))
defaultPermissionsId := int64(-1)
require.Equal(t, defaultPermissionsId, query.Result[0].DashboardId)
require.Equal(t, models.ROLE_VIEWER, *query.Result[0].Role)
require.Equal(t, org.RoleViewer, *query.Result[0].Role)
require.False(t, query.Result[0].Inherited)
require.Equal(t, defaultPermissionsId, query.Result[1].DashboardId)
require.Equal(t, models.ROLE_EDITOR, *query.Result[1].Role)
require.Equal(t, org.RoleEditor, *query.Result[1].Role)
require.False(t, query.Result[1].Inherited)
})
@@ -266,6 +267,6 @@ func createUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role str
q1 := models.GetUserOrgListQuery{UserId: currentUser.ID}
err = sqlStore.GetUserOrgList(context.Background(), &q1)
require.NoError(t, err)
require.Equal(t, models.RoleType(role), q1.Result[0].Role)
require.Equal(t, org.RoleType(role), q1.Result[0].Role)
return *currentUser
}
@@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
@@ -43,7 +44,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("and no acls are set", func(t *testing.T) {
t.Run("should return all dashboards", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
@@ -67,7 +68,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
err := testSearchDashboards(dashboardStore, query)
@@ -85,7 +86,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should be able to access folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
@@ -100,10 +101,10 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("when the user is an admin", func(t *testing.T) {
t.Run("should be able to access folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
UserId: currentUser.ID,
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id},
@@ -128,7 +129,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder or child", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
@@ -143,7 +144,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
require.NoError(t, err)
t.Run("should be able to search for child dashboard but not folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}}
query := &models.FindPersistedDashboardsQuery{SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
@@ -155,10 +156,10 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("when the user is an admin", func(t *testing.T) {
t.Run("should be able to search for child dash and folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
UserId: currentUser.ID,
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id, childDash.Id},
@@ -197,8 +198,8 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return dashboards in root and expanded folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
FolderIds: []int64{
rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.ID,
OrgId: 1, OrgRole: models.ROLE_VIEWER,
rootFolderId, folder1.Id}, SignedInUser: &user.SignedInUser{UserId: currentUser.ID,
OrgId: 1, OrgRole: org.RoleViewer,
},
OrgId: 1,
}
@@ -224,7 +225,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder with acl or its children", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder1.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@@ -240,7 +241,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return folder without acl and its children", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@@ -264,7 +265,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return folder without acl but not the dashboard with acl", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
OrgId: 1,
DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@@ -302,7 +303,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Should have write access to all dashboard folders in their org", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgRole: models.ROLE_ADMIN, OrgId: 1},
SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgRole: org.RoleAdmin, OrgId: 1},
Permission: models.PERMISSION_VIEW,
Type: "dash-folder",
}
@@ -317,7 +318,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN},
SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleAdmin},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
require.NoError(t, err)
@@ -326,7 +327,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN},
SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleAdmin},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
@@ -337,7 +338,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Editor users", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgRole: models.ROLE_EDITOR, OrgId: 1},
SignedInUser: &user.SignedInUser{UserId: editorUser.ID, OrgRole: org.RoleEditor, OrgId: 1},
Permission: models.PERMISSION_EDIT,
}
@@ -365,7 +366,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{UserId: editorUser.ID, OrgId: 1, OrgRole: org.RoleEditor},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@@ -374,7 +375,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR},
SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleEditor},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
@@ -385,7 +386,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Viewer users", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgRole: models.ROLE_VIEWER, OrgId: 1},
SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgRole: org.RoleViewer, OrgId: 1},
Permission: models.PERMISSION_EDIT,
}
@@ -413,7 +414,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
setup3()
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@@ -422,7 +423,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInDashboardsOrFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasAdminPermissionInDashboardsOrFolders(context.Background(), query)
require.NoError(t, err)
@@ -437,7 +438,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@@ -453,7 +454,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &user.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: org.RoleViewer},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/services/star"
@@ -239,7 +240,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
FolderIds: []int64{savedFolder.Id},
SignedInUser: &models.SignedInUser{},
SignedInUser: &user.SignedInUser{},
}
res, err := dashboardStore.FindDashboards(context.Background(), &query)
@@ -306,9 +307,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
Title: "1 test dash folder",
OrgId: 1,
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionFoldersRead: []string{dashboards.ScopeFoldersAll}},
},
@@ -330,9 +331,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
Limit: 1,
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionFoldersRead: []string{dashboards.ScopeFoldersAll}},
},
@@ -352,9 +353,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
Limit: 1,
Page: 2,
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {
dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll},
@@ -377,9 +378,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
OrgId: 1,
Type: "dash-db",
Tags: []string{"prod"},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -398,9 +399,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
FolderIds: []int64{savedFolder.Id},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -424,9 +425,9 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
setup()
query := models.FindPersistedDashboardsQuery{
DashboardIds: []int64{savedDash.Id, savedDash2.Id},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -461,10 +462,10 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
require.NoError(t, err)
query := models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
UserId: 10,
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -513,10 +514,10 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) {
assert.NotZero(t, dashA.Id)
assert.Less(t, dashB.Id, dashA.Id)
qNoSort := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -529,10 +530,10 @@ func TestIntegrationDashboard_SortingOptions(t *testing.T) {
assert.Equal(t, dashB.Id, results[1].ID)
qSort := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -559,10 +560,10 @@ func TestIntegrationDashboard_Filter(t *testing.T) {
insertTestDashboard(t, dashboardStore, "Alfa", 1, 0, false)
dashB := insertTestDashboard(t, dashboardStore, "Beta", 1, 0, false)
qNoFilter := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -573,10 +574,10 @@ func TestIntegrationDashboard_Filter(t *testing.T) {
require.Len(t, results, 2)
qFilter := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Permissions: map[int64]map[string][]string{
1: {dashboards.ActionDashboardsRead: []string{dashboards.ScopeDashboardsAll}},
},
@@ -678,7 +679,7 @@ func CreateUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role str
q1 := models.GetUserOrgListQuery{UserId: currentUser.ID}
err = sqlStore.GetUserOrgList(context.Background(), &q1)
require.NoError(t, err)
require.Equal(t, models.RoleType(role), q1.Result[0].Role)
require.Equal(t, org.RoleType(role), q1.Result[0].Role)
return *currentUser
}
+8 -7
View File
@@ -4,17 +4,18 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
//go:generate mockery --name FolderService --structname FakeFolderService --inpackage --filename folder_service_mock.go
// FolderService is a service for operating on folders.
type FolderService interface {
GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error)
GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error)
GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error)
GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error)
CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error)
UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error
DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error)
GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error)
GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error)
GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error)
GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error)
CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error)
UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error
DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error)
MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error
}
+41 -40
View File
@@ -6,6 +6,7 @@ import (
context "context"
models "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
mock "github.com/stretchr/testify/mock"
testing "testing"
@@ -17,12 +18,12 @@ type FakeFolderService struct {
}
// CreateFolder provides a mock function with given fields: ctx, user, orgID, title, uid
func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title string, uid string) (*models.Folder, error) {
ret := _m.Called(ctx, user, orgID, title, uid)
func (_m *FakeFolderService) CreateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, title string, uid string) (*models.Folder, error) {
ret := _m.Called(ctx, usr, orgID, title, uid)
var r0 *models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, string) *models.Folder); ok {
r0 = rf(ctx, user, orgID, title, uid)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, string) *models.Folder); ok {
r0 = rf(ctx, usr, orgID, title, uid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Folder)
@@ -30,8 +31,8 @@ func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.Sign
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string, string) error); ok {
r1 = rf(ctx, user, orgID, title, uid)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, string) error); ok {
r1 = rf(ctx, usr, orgID, title, uid)
} else {
r1 = ret.Error(1)
}
@@ -40,12 +41,12 @@ func (_m *FakeFolderService) CreateFolder(ctx context.Context, user *models.Sign
}
// DeleteFolder provides a mock function with given fields: ctx, user, orgID, uid, forceDeleteRules
func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
ret := _m.Called(ctx, user, orgID, uid, forceDeleteRules)
func (_m *FakeFolderService) DeleteFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
ret := _m.Called(ctx, usr, orgID, uid, forceDeleteRules)
var r0 *models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, bool) *models.Folder); ok {
r0 = rf(ctx, user, orgID, uid, forceDeleteRules)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, bool) *models.Folder); ok {
r0 = rf(ctx, usr, orgID, uid, forceDeleteRules)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Folder)
@@ -53,8 +54,8 @@ func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.Sign
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string, bool) error); ok {
r1 = rf(ctx, user, orgID, uid, forceDeleteRules)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string, bool) error); ok {
r1 = rf(ctx, usr, orgID, uid, forceDeleteRules)
} else {
r1 = ret.Error(1)
}
@@ -63,12 +64,12 @@ func (_m *FakeFolderService) DeleteFolder(ctx context.Context, user *models.Sign
}
// GetFolderByID provides a mock function with given fields: ctx, user, id, orgID
func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
ret := _m.Called(ctx, user, id, orgID)
func (_m *FakeFolderService) GetFolderByID(ctx context.Context, usr *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
ret := _m.Called(ctx, usr, id, orgID)
var r0 *models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, int64) *models.Folder); ok {
r0 = rf(ctx, user, id, orgID)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64) *models.Folder); ok {
r0 = rf(ctx, usr, id, orgID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Folder)
@@ -76,8 +77,8 @@ func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.Sig
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, int64) error); ok {
r1 = rf(ctx, user, id, orgID)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64) error); ok {
r1 = rf(ctx, usr, id, orgID)
} else {
r1 = ret.Error(1)
}
@@ -86,12 +87,12 @@ func (_m *FakeFolderService) GetFolderByID(ctx context.Context, user *models.Sig
}
// GetFolderByTitle provides a mock function with given fields: ctx, user, orgID, title
func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error) {
ret := _m.Called(ctx, user, orgID, title)
func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, usr *user.SignedInUser, orgID int64, title string) (*models.Folder, error) {
ret := _m.Called(ctx, usr, orgID, title)
var r0 *models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string) *models.Folder); ok {
r0 = rf(ctx, user, orgID, title)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok {
r0 = rf(ctx, usr, orgID, title)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Folder)
@@ -99,8 +100,8 @@ func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models.
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string) error); ok {
r1 = rf(ctx, user, orgID, title)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok {
r1 = rf(ctx, usr, orgID, title)
} else {
r1 = ret.Error(1)
}
@@ -109,12 +110,12 @@ func (_m *FakeFolderService) GetFolderByTitle(ctx context.Context, user *models.
}
// GetFolderByUID provides a mock function with given fields: ctx, user, orgID, uid
func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
ret := _m.Called(ctx, user, orgID, uid)
func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, usr *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
ret := _m.Called(ctx, usr, orgID, uid)
var r0 *models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string) *models.Folder); ok {
r0 = rf(ctx, user, orgID, uid)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string) *models.Folder); ok {
r0 = rf(ctx, usr, orgID, uid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.Folder)
@@ -122,8 +123,8 @@ func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.Si
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, string) error); ok {
r1 = rf(ctx, user, orgID, uid)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, string) error); ok {
r1 = rf(ctx, usr, orgID, uid)
} else {
r1 = ret.Error(1)
}
@@ -132,12 +133,12 @@ func (_m *FakeFolderService) GetFolderByUID(ctx context.Context, user *models.Si
}
// GetFolders provides a mock function with given fields: ctx, user, orgID, limit, page
func (_m *FakeFolderService) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
ret := _m.Called(ctx, user, orgID, limit, page)
func (_m *FakeFolderService) GetFolders(ctx context.Context, usr *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
ret := _m.Called(ctx, usr, orgID, limit, page)
var r0 []*models.Folder
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, int64, int64) []*models.Folder); ok {
r0 = rf(ctx, user, orgID, limit, page)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, int64, int64) []*models.Folder); ok {
r0 = rf(ctx, usr, orgID, limit, page)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*models.Folder)
@@ -145,8 +146,8 @@ func (_m *FakeFolderService) GetFolders(ctx context.Context, user *models.Signed
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *models.SignedInUser, int64, int64, int64) error); ok {
r1 = rf(ctx, user, orgID, limit, page)
if rf, ok := ret.Get(1).(func(context.Context, *user.SignedInUser, int64, int64, int64) error); ok {
r1 = rf(ctx, usr, orgID, limit, page)
} else {
r1 = ret.Error(1)
}
@@ -169,12 +170,12 @@ func (_m *FakeFolderService) MakeUserAdmin(ctx context.Context, orgID int64, use
}
// UpdateFolder provides a mock function with given fields: ctx, user, orgID, existingUid, cmd
func (_m *FakeFolderService) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
ret := _m.Called(ctx, user, orgID, existingUid, cmd)
func (_m *FakeFolderService) UpdateFolder(ctx context.Context, usr *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
ret := _m.Called(ctx, usr, orgID, existingUid, cmd)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.SignedInUser, int64, string, *models.UpdateFolderCommand) error); ok {
r0 = rf(ctx, user, orgID, existingUid, cmd)
if rf, ok := ret.Get(0).(func(context.Context, *user.SignedInUser, int64, string, *models.UpdateFolderCommand) error); ok {
r0 = rf(ctx, usr, orgID, existingUid, cmd)
} else {
r0 = ret.Error(0)
}
+2 -1
View File
@@ -4,12 +4,13 @@ import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
type SaveDashboardDTO struct {
OrgId int64
UpdatedAt time.Time
User *models.SignedInUser
User *user.SignedInUser
Message string
Overwrite bool
Dashboard *models.Dashboard
@@ -15,6 +15,8 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@@ -216,9 +218,9 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
dto.Dashboard.Data.Set("refresh", setting.MinRefreshInterval)
}
dto.User = &models.SignedInUser{
dto.User = &user.SignedInUser{
UserId: 0,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
OrgId: dto.OrgId,
Permissions: map[int64]map[string][]string{
dto.OrgId: provisionerPermissions,
@@ -266,9 +268,9 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
}
func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*models.Dashboard, error) {
dto.User = &models.SignedInUser{
dto.User = &user.SignedInUser{
UserId: 0,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
Permissions: map[int64]map[string][]string{dto.OrgId: provisionerPermissions},
}
cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, false, false)
@@ -368,8 +370,8 @@ func (dr *DashboardServiceImpl) GetDashboardByPublicUid(ctx context.Context, das
}
func (dr *DashboardServiceImpl) MakeUserAdmin(ctx context.Context, orgID int64, userID int64, dashboardID int64, setViewAndEditPermissions bool) error {
rtEditor := models.ROLE_EDITOR
rtViewer := models.ROLE_VIEWER
rtEditor := org.RoleEditor
rtViewer := org.RoleViewer
items := []*models.DashboardACL{
{
@@ -478,8 +480,8 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
if !inFolder {
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
{BuiltinRole: string(org.RoleEditor), Permission: models.PERMISSION_EDIT.String()},
{BuiltinRole: string(org.RoleViewer), Permission: models.PERMISSION_VIEW.String()},
}...)
}
@@ -15,7 +15,9 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards/database"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -916,9 +918,9 @@ func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlSto
dto := dashboards.SaveDashboardDTO{
OrgId: orgID,
Dashboard: cmd.GetDashboardModel(),
User: &models.SignedInUser{
User: &user.SignedInUser{
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
}
@@ -953,9 +955,9 @@ func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.
dto := dashboards.SaveDashboardDTO{
OrgId: orgID,
Dashboard: cmd.GetDashboardModel(),
User: &models.SignedInUser{
User: &user.SignedInUser{
UserId: 1,
OrgRole: models.ROLE_ADMIN,
OrgRole: org.RoleAdmin,
},
}
@@ -982,7 +984,7 @@ func toSaveDashboardDto(cmd models.SaveDashboardCommand) dashboards.SaveDashboar
Dashboard: dash,
Message: cmd.Message,
OrgId: cmd.OrgId,
User: &models.SignedInUser{UserId: cmd.UserId},
User: &user.SignedInUser{UserId: cmd.UserId},
Overwrite: cmd.Overwrite,
}
}
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -76,7 +77,7 @@ func TestDashboardService(t *testing.T) {
for _, tc := range testCases {
dto.Dashboard = models.NewDashboard("title")
dto.Dashboard.SetUid(tc.Uid)
dto.User = &models.SignedInUser{}
dto.User = &user.SignedInUser{}
if tc.Error == nil {
fakeStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything).Return(true, nil).Once()
@@ -92,7 +93,7 @@ func TestDashboardService(t *testing.T) {
dto.Dashboard = models.NewDashboard("Dash")
dto.Dashboard.SetId(3)
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
_, err := service.SaveDashboard(context.Background(), dto, false)
require.Equal(t, err, dashboards.ErrDashboardCannotSaveProvisionedDashboard)
})
@@ -103,7 +104,7 @@ func TestDashboardService(t *testing.T) {
dto.Dashboard = models.NewDashboard("Dash")
dto.Dashboard.SetId(3)
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
_, err := service.SaveDashboard(context.Background(), dto, true)
require.NoError(t, err)
})
@@ -129,7 +130,7 @@ func TestDashboardService(t *testing.T) {
fakeStore.On("SaveAlerts", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("alert validation error")).Once()
dto.Dashboard = models.NewDashboard("Dash")
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
_, err := service.SaveDashboard(context.Background(), dto, false)
require.Error(t, err)
require.Equal(t, err.Error(), "alert validation error")
@@ -145,7 +146,7 @@ func TestDashboardService(t *testing.T) {
dto.Dashboard = models.NewDashboard("Dash")
dto.Dashboard.SetId(3)
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
_, err := service.SaveProvisionedDashboard(context.Background(), dto, nil)
require.NoError(t, err)
})
@@ -160,7 +161,7 @@ func TestDashboardService(t *testing.T) {
dto.Dashboard = models.NewDashboard("Dash")
dto.Dashboard.SetId(3)
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
dto.Dashboard.Data.Set("refresh", "1s")
_, err := service.SaveProvisionedDashboard(context.Background(), dto, nil)
require.NoError(t, err)
@@ -177,7 +178,7 @@ func TestDashboardService(t *testing.T) {
dto.Dashboard = models.NewDashboard("Dash")
dto.Dashboard.SetId(3)
dto.User = &models.SignedInUser{UserId: 1}
dto.User = &user.SignedInUser{UserId: 1}
_, err := service.ImportDashboard(context.Background(), dto)
require.Equal(t, err, dashboards.ErrDashboardCannotSaveProvisionedDashboard)
})
@@ -13,7 +13,9 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -50,7 +52,7 @@ func ProvideFolderService(
}
}
func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *models.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *user.SignedInUser, orgID int64, limit int64, page int64) ([]*models.Folder, error) {
searchQuery := search.Query{
SignedInUser: user,
DashboardIds: make([]int64, 0),
@@ -79,7 +81,7 @@ func (f *FolderServiceImpl) GetFolders(ctx context.Context, user *models.SignedI
return folders, nil
}
func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *models.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *user.SignedInUser, id int64, orgID int64) (*models.Folder, error) {
if id == 0 {
return &models.Folder{Id: id, Title: "General"}, nil
}
@@ -99,7 +101,7 @@ func (f *FolderServiceImpl) GetFolderByID(ctx context.Context, user *models.Sign
return dashFolder, nil
}
func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *models.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *user.SignedInUser, orgID int64, uid string) (*models.Folder, error) {
dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid)
if err != nil {
return nil, err
@@ -116,7 +118,7 @@ func (f *FolderServiceImpl) GetFolderByUID(ctx context.Context, user *models.Sig
return dashFolder, nil
}
func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *models.SignedInUser, orgID int64, title string) (*models.Folder, error) {
func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *user.SignedInUser, orgID int64, title string) (*models.Folder, error) {
dashFolder, err := f.dashboardStore.GetFolderByTitle(ctx, orgID, title)
if err != nil {
return nil, err
@@ -133,7 +135,7 @@ func (f *FolderServiceImpl) GetFolderByTitle(ctx context.Context, user *models.S
return dashFolder, nil
}
func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) {
func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, title, uid string) (*models.Folder, error) {
dashFolder := models.NewDashboardFolder(title)
dashFolder.OrgId = orgID
@@ -183,8 +185,8 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe
}
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
{BuiltinRole: string(org.RoleEditor), Permission: models.PERMISSION_EDIT.String()},
{BuiltinRole: string(org.RoleViewer), Permission: models.PERMISSION_VIEW.String()},
}...)
_, permissionErr = f.permissions.SetPermissions(ctx, orgID, folder.Uid, permissions...)
@@ -199,7 +201,7 @@ func (f *FolderServiceImpl) CreateFolder(ctx context.Context, user *models.Signe
return folder, nil
}
func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *models.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *user.SignedInUser, orgID int64, existingUid string, cmd *models.UpdateFolderCommand) error {
query := models.GetDashboardQuery{OrgId: orgID, Uid: existingUid}
if _, err := f.dashboardStore.GetDashboard(ctx, &query); err != nil {
return toFolderError(err)
@@ -253,7 +255,7 @@ func (f *FolderServiceImpl) UpdateFolder(ctx context.Context, user *models.Signe
return nil
}
func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *models.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
func (f *FolderServiceImpl) DeleteFolder(ctx context.Context, user *user.SignedInUser, orgID int64, uid string, forceDeleteRules bool) (*models.Folder, error) {
dashFolder, err := f.dashboardStore.GetFolderByUID(ctx, orgID, uid)
if err != nil {
return nil, err
@@ -16,12 +16,13 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
var orgID = int64(1)
var user = &models.SignedInUser{UserId: 1}
var usr = &user.SignedInUser{UserId: 1}
func TestIntegrationProvideFolderService(t *testing.T) {
if testing.Short() {
@@ -76,24 +77,24 @@ func TestIntegrationFolderService(t *testing.T) {
store.On("GetFolderByUID", mock.Anything, orgID, folderUID).Return(folder, nil)
t.Run("When get folder by id should return access denied error", func(t *testing.T) {
_, err := service.GetFolderByID(context.Background(), user, folderId, orgID)
_, err := service.GetFolderByID(context.Background(), usr, folderId, orgID)
require.Equal(t, err, dashboards.ErrFolderAccessDenied)
})
t.Run("When get folder by id, with id = 0 should return default folder", func(t *testing.T) {
folder, err := service.GetFolderByID(context.Background(), user, 0, orgID)
folder, err := service.GetFolderByID(context.Background(), usr, 0, orgID)
require.NoError(t, err)
require.Equal(t, folder, &models.Folder{Id: 0, Title: "General"})
})
t.Run("When get folder by uid should return access denied error", func(t *testing.T) {
_, err := service.GetFolderByUID(context.Background(), user, orgID, folderUID)
_, err := service.GetFolderByUID(context.Background(), usr, orgID, folderUID)
require.Equal(t, err, dashboards.ErrFolderAccessDenied)
})
t.Run("When creating folder should return access denied error", func(t *testing.T) {
store.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything).Return(true, nil).Times(2)
_, err := service.CreateFolder(context.Background(), user, orgID, folder.Title, folderUID)
_, err := service.CreateFolder(context.Background(), usr, orgID, folder.Title, folderUID)
require.Equal(t, err, dashboards.ErrFolderAccessDenied)
})
@@ -103,7 +104,7 @@ func TestIntegrationFolderService(t *testing.T) {
folder.Result = models.NewDashboard("dashboard-test")
folder.Result.IsFolder = true
}).Return(&models.Dashboard{}, nil)
err := service.UpdateFolder(context.Background(), user, orgID, folderUID, &models.UpdateFolderCommand{
err := service.UpdateFolder(context.Background(), usr, orgID, folderUID, &models.UpdateFolderCommand{
Uid: folderUID,
Title: "Folder-TEST",
})
@@ -111,7 +112,7 @@ func TestIntegrationFolderService(t *testing.T) {
})
t.Run("When deleting folder by uid should return access denied error", func(t *testing.T) {
_, err := service.DeleteFolder(context.Background(), user, orgID, folderUID, false)
_, err := service.DeleteFolder(context.Background(), usr, orgID, folderUID, false)
require.Error(t, err)
require.Equal(t, err, dashboards.ErrFolderAccessDenied)
})
@@ -134,7 +135,7 @@ func TestIntegrationFolderService(t *testing.T) {
store.On("SaveDashboard", mock.Anything).Return(dash, nil).Once()
store.On("GetFolderByID", mock.Anything, orgID, dash.Id).Return(f, nil)
actualFolder, err := service.CreateFolder(context.Background(), user, orgID, dash.Title, "")
actualFolder, err := service.CreateFolder(context.Background(), usr, orgID, dash.Title, "")
require.NoError(t, err)
require.Equal(t, f, actualFolder)
})
@@ -143,7 +144,7 @@ func TestIntegrationFolderService(t *testing.T) {
dash := models.NewDashboardFolder("Test-Folder")
dash.Id = rand.Int63()
_, err := service.CreateFolder(context.Background(), user, orgID, dash.Title, "general")
_, err := service.CreateFolder(context.Background(), usr, orgID, dash.Title, "general")
require.ErrorIs(t, err, dashboards.ErrFolderInvalidUID)
})
@@ -162,7 +163,7 @@ func TestIntegrationFolderService(t *testing.T) {
Title: "TEST-Folder",
}
err := service.UpdateFolder(context.Background(), user, orgID, dashboardFolder.Uid, req)
err := service.UpdateFolder(context.Background(), usr, orgID, dashboardFolder.Uid, req)
require.NoError(t, err)
require.Equal(t, f, req.Result)
})
@@ -179,7 +180,7 @@ func TestIntegrationFolderService(t *testing.T) {
}).Return(nil).Once()
expectedForceDeleteRules := rand.Int63()%2 == 0
_, err := service.DeleteFolder(context.Background(), user, orgID, f.Uid, expectedForceDeleteRules)
_, err := service.DeleteFolder(context.Background(), usr, orgID, f.Uid, expectedForceDeleteRules)
require.NoError(t, err)
require.NotNil(t, actualCmd)
require.Equal(t, f.Id, actualCmd.Id)
@@ -202,7 +203,7 @@ func TestIntegrationFolderService(t *testing.T) {
store.On("GetFolderByID", mock.Anything, orgID, expected.Id).Return(expected, nil)
actual, err := service.GetFolderByID(context.Background(), user, expected.Id, orgID)
actual, err := service.GetFolderByID(context.Background(), usr, expected.Id, orgID)
require.Equal(t, expected, actual)
require.NoError(t, err)
})
@@ -213,7 +214,7 @@ func TestIntegrationFolderService(t *testing.T) {
store.On("GetFolderByUID", mock.Anything, orgID, expected.Uid).Return(expected, nil)
actual, err := service.GetFolderByUID(context.Background(), user, orgID, expected.Uid)
actual, err := service.GetFolderByUID(context.Background(), usr, orgID, expected.Uid)
require.Equal(t, expected, actual)
require.NoError(t, err)
})
@@ -223,7 +224,7 @@ func TestIntegrationFolderService(t *testing.T) {
store.On("GetFolderByTitle", mock.Anything, orgID, expected.Title).Return(expected, nil)
actual, err := service.GetFolderByTitle(context.Background(), user, orgID, expected.Title)
actual, err := service.GetFolderByTitle(context.Background(), usr, orgID, expected.Title)
require.Equal(t, expected, actual)
require.NoError(t, err)
})
@@ -6,8 +6,8 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/setting"
@@ -115,7 +115,7 @@ func (d *DashboardSnapshotStore) SearchDashboardSnapshots(ctx context.Context, q
// admins can see all snapshots, everyone else can only see their own snapshots
switch {
case query.SignedInUser.OrgRole == models.ROLE_ADMIN:
case query.SignedInUser.OrgRole == org.RoleAdmin:
sess.Where("org_id = ?", query.OrgId)
case !query.SignedInUser.IsAnonymous:
sess.Where("org_id = ? AND user_id = ?", query.OrgId, query.SignedInUser.UserId)
@@ -9,11 +9,12 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -71,7 +72,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
t.Run("And the user has the admin role", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin},
}
err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
@@ -85,7 +86,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
t.Run("And the user has the editor role and has created a snapshot", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, UserId: 1000},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserId: 1000},
}
err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
@@ -99,7 +100,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
t.Run("And the user has the editor role and has not created any snapshot", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, UserId: 2},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, UserId: 2},
}
err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
@@ -126,7 +127,7 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
t.Run("Should not return any snapshots", func(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_EDITOR, IsAnonymous: true, UserId: 0},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleEditor, IsAnonymous: true, UserId: 0},
}
err := dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
@@ -167,7 +168,7 @@ func TestIntegrationDeleteExpiredSnapshots(t *testing.T) {
query := dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin},
}
err = dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
@@ -180,7 +181,7 @@ func TestIntegrationDeleteExpiredSnapshots(t *testing.T) {
query = dashboardsnapshots.GetDashboardSnapshotsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{OrgRole: models.ROLE_ADMIN},
SignedInUser: &user.SignedInUser{OrgRole: org.RoleAdmin},
}
err = dashStore.SearchDashboardSnapshots(context.Background(), &query)
require.NoError(t, err)
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// DashboardSnapshot model
@@ -102,7 +102,7 @@ type GetDashboardSnapshotsQuery struct {
Name string
Limit int
OrgId int64
SignedInUser *models.SignedInUser
SignedInUser *user.SignedInUser
Result DashboardSnapshotsList
}
+3 -3
View File
@@ -7,7 +7,7 @@ import (
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// DataSourceService interface for interacting with datasources.
@@ -59,8 +59,8 @@ type DataSourceService interface {
// CacheService interface for retrieving a cached datasource.
type CacheService interface {
// GetDatasource gets a datasource identified by datasource numeric identifier.
GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*DataSource, error)
GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*DataSource, error)
// GetDatasourceByUID gets a datasource identified by datasource unique identifier (UID).
GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*DataSource, error)
GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*DataSource, error)
}
@@ -3,8 +3,8 @@ package datasources
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/user"
)
type FakeCacheService struct {
@@ -13,7 +13,7 @@ type FakeCacheService struct {
var _ datasources.CacheService = &FakeCacheService{}
func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
for _, datasource := range c.DataSources {
if datasource.Id == datasourceID {
return datasource, nil
@@ -22,7 +22,7 @@ func (c *FakeCacheService) GetDatasource(ctx context.Context, datasourceID int64
return nil, datasources.ErrDataSourceNotFound
}
func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *models.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
func (c *FakeCacheService) GetDatasourceByUID(ctx context.Context, datasourceUID string, user *user.SignedInUser, skipCache bool) (*datasources.DataSource, error) {
for _, datasource := range c.DataSources {
if datasource.Uid == datasourceUID {
return datasource, nil
+4 -4
View File
@@ -4,7 +4,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
const (
@@ -156,7 +156,7 @@ type UpdateSecretFn func() error
type GetDataSourcesQuery struct {
OrgId int64
DataSourceLimit int
User *models.SignedInUser
User *user.SignedInUser
Result []*DataSource
}
@@ -172,7 +172,7 @@ type GetDataSourcesByTypeQuery struct {
type GetDefaultDataSourceQuery struct {
OrgId int64
User *models.SignedInUser
User *user.SignedInUser
Result *DataSource
}
@@ -214,7 +214,7 @@ func (p DsPermissionType) String() string {
}
type DatasourcesPermissionFilterQuery struct {
User *models.SignedInUser
User *user.SignedInUser
Datasources []*DataSource
Result []*DataSource
}
@@ -4,15 +4,15 @@ import (
"context"
"errors"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/user"
)
var ErrNotImplemented = errors.New("not implemented")
type DatasourcePermissionsService interface {
FilterDatasourcesBasedOnQueryPermissions(ctx context.Context, cmd *datasources.DatasourcesPermissionFilterQuery) error
FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error)
FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error)
}
// dummy method
@@ -20,7 +20,7 @@ func (hs *OSSDatasourcePermissionsService) FilterDatasourcesBasedOnQueryPermissi
return ErrNotImplemented
}
func (hs *OSSDatasourcePermissionsService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error) {
func (hs *OSSDatasourcePermissionsService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error) {
return nil, ErrNotImplemented
}
@@ -3,8 +3,8 @@ package permissions
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/user"
)
type mockDatasourcePermissionService struct {
@@ -13,7 +13,7 @@ type mockDatasourcePermissionService struct {
ErrResult error
}
func (m *mockDatasourcePermissionService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *models.SignedInUser, datasourceUids []string) ([]string, error) {
func (m *mockDatasourcePermissionService) FilterDatasourceUidsBasedOnQueryPermissions(ctx context.Context, user *user.SignedInUser, datasourceUids []string) ([]string, error) {
return m.DsUidResult, m.ErrResult
}
@@ -7,9 +7,9 @@ import (
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
const (
@@ -35,7 +35,7 @@ type CacheServiceImpl struct {
func (dc *CacheServiceImpl) GetDatasource(
ctx context.Context,
datasourceID int64,
user *models.SignedInUser,
user *user.SignedInUser,
skipCache bool,
) (*datasources.DataSource, error) {
cacheKey := idKey(datasourceID)
@@ -69,7 +69,7 @@ func (dc *CacheServiceImpl) GetDatasource(
func (dc *CacheServiceImpl) GetDatasourceByUID(
ctx context.Context,
datasourceUID string,
user *models.SignedInUser,
user *user.SignedInUser,
skipCache bool,
) (*datasources.DataSource, error) {
if datasourceUID == "" {
@@ -7,7 +7,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -20,7 +22,7 @@ var permissionMap = map[string]models.PermissionType{
var _ DashboardGuardian = new(AccessControlDashboardGuardian)
func NewAccessControlDashboardGuardian(
ctx context.Context, dashboardId int64, user *models.SignedInUser,
ctx context.Context, dashboardId int64, user *user.SignedInUser,
store sqlstore.Store, ac accesscontrol.AccessControl,
folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService,
@@ -44,7 +46,7 @@ type AccessControlDashboardGuardian struct {
log log.Logger
dashboardID int64
dashboard *models.Dashboard
user *models.SignedInUser
user *user.SignedInUser
store sqlstore.Store
ac accesscontrol.AccessControl
folderPermissionsService accesscontrol.FolderPermissionsService
@@ -182,9 +184,9 @@ func (a *AccessControlDashboardGuardian) GetACL() ([]*models.DashboardACLInfoDTO
continue
}
var role *models.RoleType
var role *org.RoleType
if p.BuiltInRole != "" {
tmp := models.RoleType(p.BuiltInRole)
tmp := org.RoleType(p.BuiltInRole)
role = &tmp
}
@@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -610,7 +611,7 @@ func setupAccessControlGuardianTest(t *testing.T, uid string, permissions []acce
if dashboardSvc == nil {
dashboardSvc = &dashboards.FakeDashboardService{}
}
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &models.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, dashboardSvc), dash
return NewAccessControlDashboardGuardian(context.Background(), dash.Id, &user.SignedInUser{OrgId: 1}, store, ac, folderPermissions, dashboardPermissions, dashboardSvc), dash
}
func testDashSvc(t *testing.T) dashboards.DashboardService {
+10 -8
View File
@@ -7,7 +7,9 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -37,7 +39,7 @@ type DashboardGuardian interface {
}
type dashboardGuardianImpl struct {
user *models.SignedInUser
user *user.SignedInUser
dashId int64
orgId int64
acl []*models.DashboardACLInfoDTO
@@ -50,11 +52,11 @@ type dashboardGuardianImpl struct {
// New factory for creating a new dashboard guardian instance
// When using access control this function is replaced on startup and the AccessControlDashboardGuardian is returned
var New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
var New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian {
panic("no guardian factory implementation provided")
}
func newDashboardGuardian(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser, store sqlstore.Store, dashSvc dashboards.DashboardService) *dashboardGuardianImpl {
func newDashboardGuardian(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser, store sqlstore.Store, dashSvc dashboards.DashboardService) *dashboardGuardianImpl {
return &dashboardGuardianImpl{
user: user,
dashId: dashId,
@@ -97,7 +99,7 @@ func (g *dashboardGuardianImpl) CanCreate(_ int64, _ bool) (bool, error) {
}
func (g *dashboardGuardianImpl) HasPermission(permission models.PermissionType) (bool, error) {
if g.user.OrgRole == models.ROLE_ADMIN {
if g.user.OrgRole == org.RoleAdmin {
return g.logHasPermissionResult(permission, true, nil)
}
@@ -174,7 +176,7 @@ func (g *dashboardGuardianImpl) checkACL(permission models.PermissionType, acl [
func (g *dashboardGuardianImpl) CheckPermissionBeforeUpdate(permission models.PermissionType, updatePermissions []*models.DashboardACL) (bool, error) {
acl := []*models.DashboardACLInfoDTO{}
adminRole := models.ROLE_ADMIN
adminRole := org.RoleAdmin
everyoneWithAdminRole := &models.DashboardACLInfoDTO{DashboardId: g.dashId, UserId: 0, TeamId: 0, Role: &adminRole, Permission: models.PERMISSION_ADMIN}
// validate that duplicate permissions don't exists
@@ -211,7 +213,7 @@ func (g *dashboardGuardianImpl) CheckPermissionBeforeUpdate(permission models.Pe
}
}
if g.user.OrgRole == models.ROLE_ADMIN {
if g.user.OrgRole == org.RoleAdmin {
return true, nil
}
@@ -316,7 +318,7 @@ func (g *dashboardGuardianImpl) GetHiddenACL(cfg *setting.Cfg) ([]*models.Dashbo
type FakeDashboardGuardian struct {
DashId int64
OrgId int64
User *models.SignedInUser
User *user.SignedInUser
CanSaveValue bool
CanEditValue bool
CanViewValue bool
@@ -374,7 +376,7 @@ func (g *FakeDashboardGuardian) GetHiddenACL(cfg *setting.Cfg) ([]*models.Dashbo
// nolint:unused
func MockDashboardGuardian(mock *FakeDashboardGuardian) {
New = func(_ context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
New = func(_ context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian {
mock.OrgId = orgId
mock.DashId = dashId
mock.User = user
+12 -10
View File
@@ -12,7 +12,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -29,13 +31,13 @@ const (
)
var (
adminRole = models.ROLE_ADMIN
editorRole = models.ROLE_EDITOR
viewerRole = models.ROLE_VIEWER
adminRole = org.RoleAdmin
editorRole = org.RoleEditor
viewerRole = org.RoleViewer
)
func TestGuardianAdmin(t *testing.T) {
orgRoleScenario("Given user has admin org role", t, models.ROLE_ADMIN, func(sc *scenarioContext) {
orgRoleScenario("Given user has admin org role", t, org.RoleAdmin, func(sc *scenarioContext) {
// dashboard has default permissions
sc.defaultPermissionScenario(USER, FULL_ACCESS)
@@ -82,7 +84,7 @@ func TestGuardianAdmin(t *testing.T) {
}
func TestGuardianEditor(t *testing.T) {
orgRoleScenario("Given user has editor org role", t, models.ROLE_EDITOR, func(sc *scenarioContext) {
orgRoleScenario("Given user has editor org role", t, org.RoleEditor, func(sc *scenarioContext) {
// dashboard has default permissions
sc.defaultPermissionScenario(USER, EDITOR_ACCESS)
@@ -129,7 +131,7 @@ func TestGuardianEditor(t *testing.T) {
}
func TestGuardianViewer(t *testing.T) {
orgRoleScenario("Given user has viewer org role", t, models.ROLE_VIEWER, func(sc *scenarioContext) {
orgRoleScenario("Given user has viewer org role", t, org.RoleViewer, func(sc *scenarioContext) {
// dashboard has default permissions
sc.defaultPermissionScenario(USER, VIEWER_ACCESS)
@@ -174,7 +176,7 @@ func TestGuardianViewer(t *testing.T) {
sc.parentFolderPermissionScenario(VIEWER, models.PERMISSION_VIEW, VIEWER_ACCESS)
})
apiKeyScenario("Given api key with viewer role", t, models.ROLE_VIEWER, func(sc *scenarioContext) {
apiKeyScenario("Given api key with viewer role", t, org.RoleViewer, func(sc *scenarioContext) {
// dashboard has default permissions
sc.defaultPermissionScenario(VIEWER, VIEWER_ACCESS)
})
@@ -699,7 +701,7 @@ func TestGuardianGetHiddenACL(t *testing.T) {
cfg.HiddenUsers = map[string]struct{}{"user2": {}}
t.Run("Should get hidden acl", func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
OrgId: orgID,
UserId: 1,
Login: "user1",
@@ -714,7 +716,7 @@ func TestGuardianGetHiddenACL(t *testing.T) {
})
t.Run("Grafana admin should not get hidden acl", func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
OrgId: orgID,
UserId: 1,
Login: "user1",
@@ -749,7 +751,7 @@ func TestGuardianGetACLWithoutDuplicates(t *testing.T) {
}).Return(nil)
t.Run("Should get acl without duplicates", func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
OrgId: orgID,
UserId: 1,
Login: "user1",
+7 -5
View File
@@ -12,7 +12,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
)
type scenarioContext struct {
@@ -20,7 +22,7 @@ type scenarioContext struct {
orgRoleScenario string
permissionScenario string
g DashboardGuardian
givenUser *models.SignedInUser
givenUser *user.SignedInUser
givenDashboardID int64
givenPermissions []*models.DashboardACLInfoDTO
givenTeams []*models.TeamDTO
@@ -32,9 +34,9 @@ type scenarioContext struct {
type scenarioFunc func(c *scenarioContext)
func orgRoleScenario(desc string, t *testing.T, role models.RoleType, fn scenarioFunc) {
func orgRoleScenario(desc string, t *testing.T, role org.RoleType, fn scenarioFunc) {
t.Run(desc, func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: userID,
OrgId: orgID,
OrgRole: role,
@@ -53,9 +55,9 @@ func orgRoleScenario(desc string, t *testing.T, role models.RoleType, fn scenari
})
}
func apiKeyScenario(desc string, t *testing.T, role models.RoleType, fn scenarioFunc) {
func apiKeyScenario(desc string, t *testing.T, role org.RoleType, fn scenarioFunc) {
t.Run(desc, func(t *testing.T) {
user := &models.SignedInUser{
user := &user.SignedInUser{
UserId: 0,
OrgId: orgID,
OrgRole: role,
+3 -3
View File
@@ -3,10 +3,10 @@ package guardian
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type Provider struct{}
@@ -26,7 +26,7 @@ func ProvideService(
}
func InitLegacyGuardian(store sqlstore.Store, dashSvc dashboards.DashboardService) {
New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian {
return newDashboardGuardian(ctx, dashId, orgId, user, store, dashSvc)
}
}
@@ -35,7 +35,7 @@ func InitAccessControlGuardian(
store sqlstore.Store, ac accesscontrol.AccessControl, folderPermissionsService accesscontrol.FolderPermissionsService,
dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardService dashboards.DashboardService,
) {
New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
New = func(ctx context.Context, dashId int64, orgId int64, user *user.SignedInUser) DashboardGuardian {
return NewAccessControlDashboardGuardian(ctx, dashId, user, store, ac, folderPermissionsService, dashboardPermissionsService, dashboardService)
}
}
+2 -1
View File
@@ -18,6 +18,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/org"
)
// IConnection is interface for LDAP connection manipulation
@@ -442,7 +443,7 @@ func (server *Server) buildGrafanaUser(user *ldap.Entry) (*models.ExternalUserIn
Login: getAttribute(attrs.Username, user),
Email: getAttribute(attrs.Email, user),
Groups: memberOf,
OrgRoles: map[int64]models.RoleType{},
OrgRoles: map[int64]org.RoleType{},
}
for _, group := range server.Config.Groups {
+3 -2
View File
@@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
)
func TestServer_getSearchRequest(t *testing.T) {
@@ -126,7 +127,7 @@ func TestSerializeUsers(t *testing.T) {
Groups: []*GroupToOrgRole{{
GroupDN: "foo",
OrgId: 1,
OrgRole: models.ROLE_EDITOR,
OrgRole: org.RoleEditor,
}},
},
Connection: &MockConnection{},
@@ -180,7 +181,7 @@ func TestServer_validateGrafanaUser(t *testing.T) {
user := &models.ExternalUserInfo{
Login: "markelog",
OrgRoles: map[int64]models.RoleType{
OrgRoles: map[int64]org.RoleType{
1: "test",
},
}
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting"
)
@@ -62,7 +62,7 @@ type GroupToOrgRole struct {
// This pointer specifies if setting was set (for backwards compatibility)
IsGrafanaAdmin *bool `toml:"grafana_admin"`
OrgRole models.RoleType `toml:"org_role"`
OrgRole org.RoleType `toml:"org_role"`
}
// logger for all LDAP stuff
+16 -14
View File
@@ -11,9 +11,11 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
)
@@ -98,7 +100,7 @@ func getLibraryElement(dialect migrator.Dialect, session *sqlstore.DBSession, ui
}
// createLibraryElement adds a library element.
func (l *LibraryElementService) createLibraryElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) {
func (l *LibraryElementService) createLibraryElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) {
if err := l.requireSupportedElementKind(cmd.Kind); err != nil {
return LibraryElementDTO{}, err
}
@@ -177,7 +179,7 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn
}
// deleteLibraryElement deletes a library element.
func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedInUser *models.SignedInUser, uid string) (int64, error) {
func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedInUser *user.SignedInUser, uid string) (int64, error) {
var elementID int64
err := l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error {
element, err := getLibraryElement(l.SQLStore.Dialect, session, uid, signedInUser.OrgId)
@@ -220,7 +222,7 @@ func (l *LibraryElementService) deleteLibraryElement(c context.Context, signedIn
}
// getLibraryElements gets a Library Element where param == value
func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUser *models.SignedInUser, params []Pair) ([]LibraryElementDTO, error) {
func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUser *user.SignedInUser, params []Pair) ([]LibraryElementDTO, error) {
libraryElements := make([]LibraryElementWithMeta, 0)
err := store.WithDbSession(c, func(session *sqlstore.DBSession) error {
builder := sqlstore.NewSqlBuilder(store.Cfg)
@@ -236,7 +238,7 @@ func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUse
builder.Write(getFromLibraryElementDTOWithMeta(store.Dialect))
builder.Write(" INNER JOIN dashboard AS dashboard on le.folder_id = dashboard.id AND le.folder_id <> 0")
writeParamSelectorSQL(&builder, params...)
if signedInUser.OrgRole != models.ROLE_ADMIN {
if signedInUser.OrgRole != org.RoleAdmin {
builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW)
}
builder.Write(` OR dashboard.id=0`)
@@ -291,7 +293,7 @@ func getLibraryElements(c context.Context, store *sqlstore.SQLStore, signedInUse
}
// getLibraryElementByUid gets a Library Element by uid.
func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error) {
func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error) {
libraryElements, err := getLibraryElements(c, l.SQLStore, signedInUser, []Pair{{key: "org_id", value: signedInUser.OrgId}, {key: "uid", value: UID}})
if err != nil {
return LibraryElementDTO{}, err
@@ -304,12 +306,12 @@ func (l *LibraryElementService) getLibraryElementByUid(c context.Context, signed
}
// getLibraryElementByName gets a Library Element by name.
func (l *LibraryElementService) getLibraryElementsByName(c context.Context, signedInUser *models.SignedInUser, name string) ([]LibraryElementDTO, error) {
func (l *LibraryElementService) getLibraryElementsByName(c context.Context, signedInUser *user.SignedInUser, name string) ([]LibraryElementDTO, error) {
return getLibraryElements(c, l.SQLStore, signedInUser, []Pair{{"org_id", signedInUser.OrgId}, {"name", name}})
}
// getAllLibraryElements gets all Library Elements.
func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedInUser *models.SignedInUser, query searchLibraryElementsQuery) (LibraryElementSearchResult, error) {
func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedInUser *user.SignedInUser, query searchLibraryElementsQuery) (LibraryElementSearchResult, error) {
elements := make([]LibraryElementWithMeta, 0)
result := LibraryElementSearchResult{}
if query.perPage <= 0 {
@@ -353,7 +355,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
if err := folderFilter.writeFolderFilterSQL(false, &builder); err != nil {
return err
}
if signedInUser.OrgRole != models.ROLE_ADMIN {
if signedInUser.OrgRole != org.RoleAdmin {
builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW)
}
if query.sortDirection == search.SortAlphaDesc.Name {
@@ -428,7 +430,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
return result, err
}
func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *models.SignedInUser) error {
func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, elementToPatch *LibraryElement, fromFolderID int64, toFolderID int64, user *user.SignedInUser) error {
// FolderID was not provided in the PATCH request
if toFolderID == -1 {
toFolderID = fromFolderID
@@ -452,7 +454,7 @@ func (l *LibraryElementService) handleFolderIDPatches(ctx context.Context, eleme
}
// patchLibraryElement updates a Library Element.
func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInUser *models.SignedInUser, cmd PatchLibraryElementCommand, uid string) (LibraryElementDTO, error) {
func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInUser *user.SignedInUser, cmd PatchLibraryElementCommand, uid string) (LibraryElementDTO, error) {
var dto LibraryElementDTO
if err := l.requireSupportedElementKind(cmd.Kind); err != nil {
return LibraryElementDTO{}, err
@@ -553,7 +555,7 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU
}
// getConnections gets all connections for a Library Element.
func (l *LibraryElementService) getConnections(c context.Context, signedInUser *models.SignedInUser, uid string) ([]LibraryElementConnectionDTO, error) {
func (l *LibraryElementService) getConnections(c context.Context, signedInUser *user.SignedInUser, uid string) ([]LibraryElementConnectionDTO, error) {
connections := make([]LibraryElementConnectionDTO, 0)
err := l.SQLStore.WithDbSession(c, func(session *sqlstore.DBSession) error {
element, err := getLibraryElement(l.SQLStore.Dialect, session, uid, signedInUser.OrgId)
@@ -567,7 +569,7 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser *
builder.Write(" LEFT JOIN " + l.SQLStore.Dialect.Quote("user") + " AS u1 ON lec.created_by = u1.id")
builder.Write(" INNER JOIN dashboard AS dashboard on lec.connection_id = dashboard.id")
builder.Write(` WHERE lec.element_id=?`, element.ID)
if signedInUser.OrgRole != models.ROLE_ADMIN {
if signedInUser.OrgRole != org.RoleAdmin {
builder.WriteDashboardPermissionFilter(signedInUser, models.PERMISSION_VIEW)
}
if err := session.SQL(builder.GetSQLString(), builder.GetParams()...).Find(&libraryElementConnections); err != nil {
@@ -652,7 +654,7 @@ func (l *LibraryElementService) getElementsForDashboardID(c context.Context, das
}
// connectElementsToDashboardID adds connections for all elements Library Elements in a Dashboard.
func (l *LibraryElementService) connectElementsToDashboardID(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error {
func (l *LibraryElementService) connectElementsToDashboardID(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error {
err := l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error {
_, err := session.Exec("DELETE FROM "+models.LibraryElementConnectionTableName+" WHERE kind=1 AND connection_id=?", dashboardID)
if err != nil {
@@ -699,7 +701,7 @@ func (l *LibraryElementService) disconnectElementsFromDashboardID(c context.Cont
}
// deleteLibraryElementsInFolderUID deletes all Library Elements in a folder.
func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c context.Context, signedInUser *models.SignedInUser, folderUID string) error {
func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c context.Context, signedInUser *user.SignedInUser, folderUID string) error {
return l.SQLStore.WithTransactionalDbSession(c, func(session *sqlstore.DBSession) error {
var folderUIDs []struct {
ID int64 `xorm:"id"`
+7 -5
View File
@@ -6,6 +6,8 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
func isGeneralFolder(folderID int64) bool {
@@ -24,12 +26,12 @@ func (l *LibraryElementService) requireSupportedElementKind(kindAsInt int64) err
}
}
func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Context, user *models.SignedInUser, folderID int64) error {
if isGeneralFolder(folderID) && user.HasRole(models.ROLE_EDITOR) {
func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Context, user *user.SignedInUser, folderID int64) error {
if isGeneralFolder(folderID) && user.HasRole(org.RoleEditor) {
return nil
}
if isGeneralFolder(folderID) && user.HasRole(models.ROLE_VIEWER) {
if isGeneralFolder(folderID) && user.HasRole(org.RoleViewer) {
return dashboards.ErrFolderAccessDenied
}
folder, err := l.folderService.GetFolderByID(ctx, user, folderID, user.OrgId)
@@ -50,8 +52,8 @@ func (l *LibraryElementService) requireEditPermissionsOnFolder(ctx context.Conte
return nil
}
func (l *LibraryElementService) requireViewPermissionsOnFolder(ctx context.Context, user *models.SignedInUser, folderID int64) error {
if isGeneralFolder(folderID) && user.HasRole(models.ROLE_VIEWER) {
func (l *LibraryElementService) requireViewPermissionsOnFolder(ctx context.Context, user *user.SignedInUser, folderID int64) error {
if isGeneralFolder(folderID) && user.HasRole(org.RoleViewer) {
return nil
}
@@ -5,9 +5,9 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -25,12 +25,12 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister
// Service is a service for operating on library elements.
type Service interface {
CreateElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error)
GetElement(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error)
CreateElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error)
GetElement(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error)
GetElementsForDashboard(c context.Context, dashboardID int64) (map[string]LibraryElementDTO, error)
ConnectElementsToDashboard(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error
ConnectElementsToDashboard(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error
DisconnectElementsFromDashboard(c context.Context, dashboardID int64) error
DeleteLibraryElementsInFolder(c context.Context, signedInUser *models.SignedInUser, folderUID string) error
DeleteLibraryElementsInFolder(c context.Context, signedInUser *user.SignedInUser, folderUID string) error
}
// LibraryElementService is the service for the Library Element feature.
@@ -43,12 +43,12 @@ type LibraryElementService struct {
}
// CreateElement creates a Library Element.
func (l *LibraryElementService) CreateElement(c context.Context, signedInUser *models.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) {
func (l *LibraryElementService) CreateElement(c context.Context, signedInUser *user.SignedInUser, cmd CreateLibraryElementCommand) (LibraryElementDTO, error) {
return l.createLibraryElement(c, signedInUser, cmd)
}
// GetElement gets an element from a UID.
func (l *LibraryElementService) GetElement(c context.Context, signedInUser *models.SignedInUser, UID string) (LibraryElementDTO, error) {
func (l *LibraryElementService) GetElement(c context.Context, signedInUser *user.SignedInUser, UID string) (LibraryElementDTO, error) {
return l.getLibraryElementByUid(c, signedInUser, UID)
}
@@ -58,7 +58,7 @@ func (l *LibraryElementService) GetElementsForDashboard(c context.Context, dashb
}
// ConnectElementsToDashboard connects elements to a specific dashboard.
func (l *LibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *models.SignedInUser, elementUIDs []string, dashboardID int64) error {
func (l *LibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser *user.SignedInUser, elementUIDs []string, dashboardID int64) error {
return l.connectElementsToDashboardID(c, signedInUser, elementUIDs, dashboardID)
}
@@ -68,6 +68,6 @@ func (l *LibraryElementService) DisconnectElementsFromDashboard(c context.Contex
}
// DeleteLibraryElementsInFolder deletes all elements for a specific folder.
func (l *LibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *models.SignedInUser, folderUID string) error {
func (l *LibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser *user.SignedInUser, folderUID string) error {
return l.deleteLibraryElementsInFolderUID(c, signedInUser, folderUID)
}
@@ -5,6 +5,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
@@ -35,7 +36,7 @@ func TestDeleteLibraryElement(t *testing.T) {
func(t *testing.T, sc scenarioContext) {
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
sc.reqContext.SignedInUser.OrgId = 2
sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN
sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin
resp := sc.service.deleteHandler(sc.reqContext)
require.Equal(t, 404, resp.Status())
})
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/search"
)
@@ -1240,7 +1241,7 @@ func TestGetAllLibraryElements(t *testing.T) {
require.Equal(t, "Text - Library Panel", result.Result.Elements[0].Name)
sc.reqContext.SignedInUser.OrgId = 2
sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN
sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
@@ -5,6 +5,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
@@ -183,7 +184,7 @@ func TestGetLibraryElement(t *testing.T) {
scenarioWithPanel(t, "When an admin tries to get a library panel that exists in an other org, it should fail",
func(t *testing.T, sc scenarioContext) {
sc.reqContext.SignedInUser.OrgId = 2
sc.reqContext.SignedInUser.OrgRole = models.ROLE_ADMIN
sc.reqContext.SignedInUser.OrgRole = org.RoleAdmin
// by uid
sc.ctx.Req = web.SetURLParams(sc.ctx.Req, map[string]string{":uid": sc.initialResult.Result.UID})
@@ -7,18 +7,19 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
)
func TestLibraryElementPermissions(t *testing.T) {
var defaultPermissions = []folderACLItem{}
var adminOnlyPermissions = []folderACLItem{{models.ROLE_ADMIN, models.PERMISSION_EDIT}}
var editorOnlyPermissions = []folderACLItem{{models.ROLE_EDITOR, models.PERMISSION_EDIT}}
var editorAndViewerPermissions = []folderACLItem{{models.ROLE_EDITOR, models.PERMISSION_EDIT}, {models.ROLE_VIEWER, models.PERMISSION_EDIT}}
var viewerOnlyPermissions = []folderACLItem{{models.ROLE_VIEWER, models.PERMISSION_EDIT}}
var everyonePermissions = []folderACLItem{{models.ROLE_ADMIN, models.PERMISSION_EDIT}, {models.ROLE_EDITOR, models.PERMISSION_EDIT}, {models.ROLE_VIEWER, models.PERMISSION_EDIT}}
var noPermissions = []folderACLItem{{models.ROLE_VIEWER, models.PERMISSION_VIEW}}
var adminOnlyPermissions = []folderACLItem{{org.RoleAdmin, models.PERMISSION_EDIT}}
var editorOnlyPermissions = []folderACLItem{{org.RoleEditor, models.PERMISSION_EDIT}}
var editorAndViewerPermissions = []folderACLItem{{org.RoleEditor, models.PERMISSION_EDIT}, {org.RoleViewer, models.PERMISSION_EDIT}}
var viewerOnlyPermissions = []folderACLItem{{org.RoleViewer, models.PERMISSION_EDIT}}
var everyonePermissions = []folderACLItem{{org.RoleAdmin, models.PERMISSION_EDIT}, {org.RoleEditor, models.PERMISSION_EDIT}, {org.RoleViewer, models.PERMISSION_EDIT}}
var noPermissions = []folderACLItem{{org.RoleViewer, models.PERMISSION_VIEW}}
var folderCases = [][]folderACLItem{
defaultPermissions,
adminOnlyPermissions,
@@ -36,34 +37,34 @@ func TestLibraryElementPermissions(t *testing.T) {
var everyoneDesc = "everyone has editor permissions"
var noDesc = "everyone has view permissions"
var accessCases = []struct {
role models.RoleType
role org.RoleType
items []folderACLItem
desc string
status int
}{
{models.ROLE_ADMIN, defaultPermissions, defaultDesc, 200},
{models.ROLE_ADMIN, adminOnlyPermissions, adminOnlyDesc, 200},
{models.ROLE_ADMIN, editorOnlyPermissions, editorOnlyDesc, 200},
{models.ROLE_ADMIN, editorAndViewerPermissions, editorAndViewerDesc, 200},
{models.ROLE_ADMIN, viewerOnlyPermissions, viewerOnlyDesc, 200},
{models.ROLE_ADMIN, everyonePermissions, everyoneDesc, 200},
{models.ROLE_ADMIN, noPermissions, noDesc, 200},
{org.RoleAdmin, defaultPermissions, defaultDesc, 200},
{org.RoleAdmin, adminOnlyPermissions, adminOnlyDesc, 200},
{org.RoleAdmin, editorOnlyPermissions, editorOnlyDesc, 200},
{org.RoleAdmin, editorAndViewerPermissions, editorAndViewerDesc, 200},
{org.RoleAdmin, viewerOnlyPermissions, viewerOnlyDesc, 200},
{org.RoleAdmin, everyonePermissions, everyoneDesc, 200},
{org.RoleAdmin, noPermissions, noDesc, 200},
{models.ROLE_EDITOR, defaultPermissions, defaultDesc, 200},
{models.ROLE_EDITOR, adminOnlyPermissions, adminOnlyDesc, 403},
{models.ROLE_EDITOR, editorOnlyPermissions, editorOnlyDesc, 200},
{models.ROLE_EDITOR, editorAndViewerPermissions, editorAndViewerDesc, 200},
{models.ROLE_EDITOR, viewerOnlyPermissions, viewerOnlyDesc, 403},
{models.ROLE_EDITOR, everyonePermissions, everyoneDesc, 200},
{models.ROLE_EDITOR, noPermissions, noDesc, 403},
{org.RoleEditor, defaultPermissions, defaultDesc, 200},
{org.RoleEditor, adminOnlyPermissions, adminOnlyDesc, 403},
{org.RoleEditor, editorOnlyPermissions, editorOnlyDesc, 200},
{org.RoleEditor, editorAndViewerPermissions, editorAndViewerDesc, 200},
{org.RoleEditor, viewerOnlyPermissions, viewerOnlyDesc, 403},
{org.RoleEditor, everyonePermissions, everyoneDesc, 200},
{org.RoleEditor, noPermissions, noDesc, 403},
{models.ROLE_VIEWER, defaultPermissions, defaultDesc, 403},
{models.ROLE_VIEWER, adminOnlyPermissions, adminOnlyDesc, 403},
{models.ROLE_VIEWER, editorOnlyPermissions, editorOnlyDesc, 403},
{models.ROLE_VIEWER, editorAndViewerPermissions, editorAndViewerDesc, 200},
{models.ROLE_VIEWER, viewerOnlyPermissions, viewerOnlyDesc, 200},
{models.ROLE_VIEWER, everyonePermissions, everyoneDesc, 200},
{models.ROLE_VIEWER, noPermissions, noDesc, 403},
{org.RoleViewer, defaultPermissions, defaultDesc, 403},
{org.RoleViewer, adminOnlyPermissions, adminOnlyDesc, 403},
{org.RoleViewer, editorOnlyPermissions, editorOnlyDesc, 403},
{org.RoleViewer, editorAndViewerPermissions, editorAndViewerDesc, 200},
{org.RoleViewer, viewerOnlyPermissions, viewerOnlyDesc, 200},
{org.RoleViewer, everyonePermissions, everyoneDesc, 200},
{org.RoleViewer, noPermissions, noDesc, 403},
}
for _, testCase := range accessCases {
@@ -128,12 +129,12 @@ func TestLibraryElementPermissions(t *testing.T) {
}
var generalFolderCases = []struct {
role models.RoleType
role org.RoleType
status int
}{
{models.ROLE_ADMIN, 200},
{models.ROLE_EDITOR, 200},
{models.ROLE_VIEWER, 403},
{org.RoleAdmin, 200},
{org.RoleEditor, 200},
{org.RoleViewer, 403},
}
for _, testCase := range generalFolderCases {
@@ -194,11 +195,11 @@ func TestLibraryElementPermissions(t *testing.T) {
}
var missingFolderCases = []struct {
role models.RoleType
role org.RoleType
}{
{models.ROLE_ADMIN},
{models.ROLE_EDITOR},
{models.ROLE_VIEWER},
{org.RoleAdmin},
{org.RoleEditor},
{org.RoleViewer},
}
for _, testCase := range missingFolderCases {
@@ -230,12 +231,12 @@ func TestLibraryElementPermissions(t *testing.T) {
}
var getCases = []struct {
role models.RoleType
role org.RoleType
statuses []int
}{
{models.ROLE_ADMIN, []int{200, 200, 200, 200, 200, 200, 200}},
{models.ROLE_EDITOR, []int{200, 404, 200, 200, 200, 200, 200}},
{models.ROLE_VIEWER, []int{200, 404, 404, 200, 200, 200, 200}},
{org.RoleAdmin, []int{200, 200, 200, 200, 200, 200, 200}},
{org.RoleEditor, []int{200, 404, 200, 200, 200, 200, 200}},
{org.RoleViewer, []int{200, 404, 404, 200, 200, 200, 200}},
}
for _, testCase := range getCases {
@@ -292,13 +293,13 @@ func TestLibraryElementPermissions(t *testing.T) {
}
var getAllCases = []struct {
role models.RoleType
role org.RoleType
panels int
folderIndexes []int
}{
{models.ROLE_ADMIN, 7, []int{0, 1, 2, 3, 4, 5, 6}},
{models.ROLE_EDITOR, 6, []int{0, 2, 3, 4, 5, 6}},
{models.ROLE_VIEWER, 5, []int{0, 3, 4, 5, 6}},
{org.RoleAdmin, 7, []int{0, 1, 2, 3, 4, 5, 6}},
{org.RoleEditor, 6, []int{0, 2, 3, 4, 5, 6}},
{org.RoleViewer, 5, []int{0, 3, 4, 5, 6}},
}
for _, testCase := range getAllCases {
@@ -23,6 +23,7 @@ import (
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -248,18 +249,18 @@ type scenarioContext struct {
ctx *web.Context
service *LibraryElementService
reqContext *models.ReqContext
user models.SignedInUser
user user.SignedInUser
folder *models.Folder
initialResult libraryElementResult
sqlStore *sqlstore.SQLStore
}
type folderACLItem struct {
roleType models.RoleType
roleType org.RoleType
permission models.PermissionType
}
func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard {
func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user user.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard {
dash.FolderId = folderID
dashItem := &dashboards.SaveDashboardDTO{
Dashboard: dash,
@@ -287,7 +288,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user models.Sign
return dashboard
}
func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user models.SignedInUser,
func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user user.SignedInUser,
items []folderACLItem) *models.Folder {
t.Helper()
@@ -399,7 +400,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
},
}}
orgID := int64(1)
role := models.ROLE_ADMIN
role := org.RoleAdmin
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
features := featuremgmt.WithFeatures()
@@ -422,7 +423,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
),
}
usr := models.SignedInUser{
usr := user.SignedInUser{
UserId: 1,
Name: "Signed In User",
Login: "signed_in_user",
+6 -5
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/libraryelements"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@@ -30,8 +31,8 @@ func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, routeRegister
type Service interface {
LoadLibraryPanelsForDashboard(c context.Context, dash *models.Dashboard) error
CleanLibraryPanelsForDashboard(dash *models.Dashboard) error
ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error
ImportLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error
ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error
ImportLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error
}
type LibraryInfo struct {
@@ -203,7 +204,7 @@ func cleanLibraryPanelsRecursively(parent *simplejson.Json) error {
}
// ConnectLibraryPanelsForDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard.
func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, dash *models.Dashboard) error {
func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, dash *models.Dashboard) error {
panels := dash.Data.Get("panels").MustArray()
libraryPanels := make(map[string]string)
err := connectLibraryPanelsRecursively(c, panels, libraryPanels)
@@ -257,11 +258,11 @@ func connectLibraryPanelsRecursively(c context.Context, panels []interface{}, li
}
// ImportLibraryPanelsForDashboard loops through all panels in dashboard JSON and creates any missing library panels in the database.
func (lps *LibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
func (lps *LibraryPanelService) ImportLibraryPanelsForDashboard(c context.Context, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
return importLibraryPanelsRecursively(c, lps.LibraryElementService, signedInUser, libraryPanels, panels, folderID)
}
func importLibraryPanelsRecursively(c context.Context, service libraryelements.Service, signedInUser *models.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
func importLibraryPanelsRecursively(c context.Context, service libraryelements.Service, signedInUser *user.SignedInUser, libraryPanels *simplejson.Json, panels []interface{}, folderID int64) error {
for _, panel := range panels {
panelAsJSON := simplejson.NewFromAny(panel)
libraryPanel := panelAsJSON.Get("libraryPanel")
@@ -21,6 +21,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/libraryelements"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -1279,14 +1280,14 @@ type scenarioContext struct {
ctx context.Context
service Service
elementService libraryelements.Service
user *models.SignedInUser
user *user.SignedInUser
folder *models.Folder
initialResult libraryPanelResult
sqlStore *sqlstore.SQLStore
}
type folderACLItem struct {
roleType models.RoleType
roleType org.RoleType
permission models.PermissionType
}
@@ -1364,7 +1365,7 @@ func getExpected(t *testing.T, res libraryelements.LibraryElementDTO, UID string
}
}
func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard {
func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *user.SignedInUser, dash *models.Dashboard, folderID int64) *models.Dashboard {
dash.FolderId = folderID
dashItem := &dashboards.SaveDashboardDTO{
Dashboard: dash,
@@ -1389,7 +1390,7 @@ func createDashboard(t *testing.T, sqlStore *sqlstore.SQLStore, user *models.Sig
return dashboard
}
func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user *models.SignedInUser,
func createFolderWithACL(t *testing.T, sqlStore *sqlstore.SQLStore, title string, user *user.SignedInUser,
items []folderACLItem) *models.Folder {
t.Helper()
@@ -1489,7 +1490,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
t.Run(desc, func(t *testing.T) {
cfg := setting.NewCfg()
orgID := int64(1)
role := models.ROLE_ADMIN
role := org.RoleAdmin
sqlStore := sqlstore.InitTestDB(t)
dashboardStore := database.ProvideDashboardStore(sqlStore, featuremgmt.WithFeatures())
@@ -1514,7 +1515,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
LibraryElementService: elementService,
}
usr := &models.SignedInUser{
usr := &user.SignedInUser{
UserId: 1,
Name: "Signed In User",
Login: "signed_in_user",
+3 -2
View File
@@ -5,6 +5,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
)
@@ -36,7 +37,7 @@ func (b *BroadcastRunner) GetHandlerForPath(_ string) (models.ChannelHandler, er
}
// OnSubscribe will let anyone connect to the path
func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
reply := models.SubscribeReply{
Presence: true,
JoinLeave: true,
@@ -56,7 +57,7 @@ func (b *BroadcastRunner) OnSubscribe(_ context.Context, u *models.SignedInUser,
}
// OnPublish is called when a client wants to broadcast on the websocket
func (b *BroadcastRunner) OnPublish(_ context.Context, u *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
func (b *BroadcastRunner) OnPublish(_ context.Context, u *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
query := &models.SaveLiveMessageQuery{
OrgId: u.OrgId,
Channel: e.Channel,
+3 -2
View File
@@ -8,6 +8,7 @@ import (
"github.com/golang/mock/gomock"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@@ -42,7 +43,7 @@ func TestBroadcastRunner_OnSubscribe(t *testing.T) {
require.NoError(t, err)
reply, status, err := handler.OnSubscribe(
context.Background(),
&models.SignedInUser{OrgId: 1, UserId: 2},
&user.SignedInUser{OrgId: 1, UserId: 2},
models.SubscribeEvent{Channel: channel, Path: "test"},
)
require.NoError(t, err)
@@ -76,7 +77,7 @@ func TestBroadcastRunner_OnPublish(t *testing.T) {
require.NoError(t, err)
reply, status, err := handler.OnPublish(
context.Background(),
&models.SignedInUser{OrgId: 1, UserId: 2},
&user.SignedInUser{OrgId: 1, UserId: 2},
models.PublishEvent{Channel: channel, Path: "test", Data: data},
)
require.NoError(t, err)
+3 -2
View File
@@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/comments/commentmodel"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
)
@@ -25,7 +26,7 @@ func (h *CommentHandler) GetHandlerForPath(_ string) (models.ChannelHandler, err
}
// OnSubscribe handles subscription to comment group channel.
func (h *CommentHandler) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
func (h *CommentHandler) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
parts := strings.Split(e.Path, "/")
if len(parts) != 2 {
return models.SubscribeReply{}, backend.SubscribeStreamStatusNotFound, nil
@@ -43,6 +44,6 @@ func (h *CommentHandler) OnSubscribe(ctx context.Context, user *models.SignedInU
}
// OnPublish is not used for comments.
func (h *CommentHandler) OnPublish(_ context.Context, _ *models.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
func (h *CommentHandler) OnPublish(_ context.Context, _ *user.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil
}
+15 -13
View File
@@ -11,7 +11,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type actionType string
@@ -27,13 +29,13 @@ const (
// DashboardEvent events related to dashboards
type dashboardEvent struct {
UID string `json:"uid"`
Action actionType `json:"action"` // saved, editing, deleted
User *models.UserDisplayDTO `json:"user,omitempty"`
SessionID string `json:"sessionId,omitempty"`
Message string `json:"message,omitempty"`
Dashboard *models.Dashboard `json:"dashboard,omitempty"`
Error string `json:"error,omitempty"`
UID string `json:"uid"`
Action actionType `json:"action"` // saved, editing, deleted
User *user.UserDisplayDTO `json:"user,omitempty"`
SessionID string `json:"sessionId,omitempty"`
Message string `json:"message,omitempty"`
Dashboard *models.Dashboard `json:"dashboard,omitempty"`
Error string `json:"error,omitempty"`
}
// DashboardHandler manages all the `grafana/dashboard/*` channels
@@ -50,11 +52,11 @@ func (h *DashboardHandler) GetHandlerForPath(_ string) (models.ChannelHandler, e
}
// OnSubscribe for now allows anyone to subscribe to any dashboard
func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
parts := strings.Split(e.Path, "/")
if parts[0] == "gitops" {
// gitops gets all changes for everything, so lets make sure it is an admin user
if !user.HasRole(models.ROLE_ADMIN) {
if !user.HasRole(org.RoleAdmin) {
return models.SubscribeReply{}, backend.SubscribeStreamStatusPermissionDenied, nil
}
return models.SubscribeReply{
@@ -88,11 +90,11 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedI
}
// OnPublish is called when someone begins to edit a dashboard
func (h *DashboardHandler) OnPublish(ctx context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
func (h *DashboardHandler) OnPublish(ctx context.Context, user *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
parts := strings.Split(e.Path, "/")
if parts[0] == "gitops" {
// gitops gets all changes for everything, so lets make sure it is an admin user
if !user.HasRole(models.ROLE_ADMIN) {
if !user.HasRole(org.RoleAdmin) {
return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil
}
@@ -161,7 +163,7 @@ func (h *DashboardHandler) publish(orgID int64, event dashboardEvent) error {
}
// DashboardSaved will broadcast to all connected dashboards
func (h *DashboardHandler) DashboardSaved(orgID int64, user *models.UserDisplayDTO, message string, dashboard *models.Dashboard, err error) error {
func (h *DashboardHandler) DashboardSaved(orgID int64, user *user.UserDisplayDTO, message string, dashboard *models.Dashboard, err error) error {
if err != nil && !h.HasGitOpsObserver(orgID) {
return nil // only broadcast if it was OK
}
@@ -182,7 +184,7 @@ func (h *DashboardHandler) DashboardSaved(orgID int64, user *models.UserDisplayD
}
// DashboardDeleted will broadcast to all connected dashboards
func (h *DashboardHandler) DashboardDeleted(orgID int64, user *models.UserDisplayDTO, uid string) error {
func (h *DashboardHandler) DashboardDeleted(orgID int64, user *user.UserDisplayDTO, uid string) error {
return h.publish(orgID, dashboardEvent{
UID: uid,
Action: ActionDeleted,
+4 -3
View File
@@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/live/orgchannel"
"github.com/grafana/grafana/pkg/services/live/runstream"
"github.com/grafana/grafana/pkg/services/user"
"github.com/centrifugal/centrifuge"
"github.com/grafana/grafana-plugin-sdk-go/backend"
@@ -14,7 +15,7 @@ import (
//go:generate mockgen -destination=plugin_mock.go -package=features github.com/grafana/grafana/pkg/services/live/features PluginContextGetter
type PluginContextGetter interface {
GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error)
GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error)
}
// PluginRunner can handle streaming operations for channels belonging to plugins.
@@ -60,7 +61,7 @@ type PluginPathRunner struct {
}
// OnSubscribe passes control to a plugin.
func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
pCtx, found, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false)
if err != nil {
logger.Error("Get plugin context error", "error", err, "path", r.path)
@@ -104,7 +105,7 @@ func (r *PluginPathRunner) OnSubscribe(ctx context.Context, user *models.SignedI
}
// OnPublish passes control to a plugin.
func (r *PluginPathRunner) OnPublish(ctx context.Context, user *models.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
func (r *PluginPathRunner) OnPublish(ctx context.Context, user *user.SignedInUser, e models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
pCtx, found, err := r.pluginContextGetter.GetPluginContext(ctx, user, r.pluginID, r.datasourceUID, false)
if err != nil {
logger.Error("Get plugin context error", "error", err, "path", r.path)
+2 -2
View File
@@ -10,7 +10,7 @@ import (
gomock "github.com/golang/mock/gomock"
backend "github.com/grafana/grafana-plugin-sdk-go/backend"
models "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// MockPluginContextGetter is a mock of PluginContextGetter interface.
@@ -37,7 +37,7 @@ func (m *MockPluginContextGetter) EXPECT() *MockPluginContextGetterMockRecorder
}
// GetPluginContext mocks base method.
func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *models.SignedInUser, arg1, arg2 string) (backend.PluginContext, bool, error) {
func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *user.SignedInUser, arg1, arg2 string) (backend.PluginContext, bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetPluginContext", arg0, arg1, arg2)
ret0, _ := ret[0].(backend.PluginContext)
+10 -8
View File
@@ -39,9 +39,11 @@ import (
"github.com/grafana/grafana/pkg/services/live/pushws"
"github.com/grafana/grafana/pkg/services/live/runstream"
"github.com/grafana/grafana/pkg/services/live/survey"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/query"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@@ -752,7 +754,7 @@ func (g *GrafanaLive) handleOnPublish(ctx context.Context, client *centrifuge.Cl
return centrifuge.PublishReply{}, &centrifuge.Error{Code: uint32(code), Message: text}
}
} else {
if !user.HasRole(models.ROLE_ADMIN) {
if !user.HasRole(org.RoleAdmin) {
// using HTTP error codes for WS errors too.
code, text := publishStatusToHTTPError(backend.PublishStreamStatusPermissionDenied)
return centrifuge.PublishReply{}, &centrifuge.Error{Code: uint32(code), Message: text}
@@ -839,7 +841,7 @@ func publishStatusToHTTPError(status backend.PublishStreamStatus) (int, string)
}
// GetChannelHandler gives thread-safe access to the channel.
func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *models.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) {
func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error) {
// Parse the identifier ${scope}/${namespace}/${path}
addr, err := live.ParseChannel(channel)
if err != nil {
@@ -880,7 +882,7 @@ func (g *GrafanaLive) GetChannelHandler(ctx context.Context, user *models.Signed
// GetChannelHandlerFactory gets a ChannelHandlerFactory for a namespace.
// It gives thread-safe access to the channel.
func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *models.SignedInUser, scope string, namespace string) (models.ChannelHandlerFactory, error) {
func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *user.SignedInUser, scope string, namespace string) (models.ChannelHandlerFactory, error) {
switch scope {
case live.ScopeGrafana:
return g.handleGrafanaScope(user, namespace)
@@ -895,14 +897,14 @@ func (g *GrafanaLive) GetChannelHandlerFactory(ctx context.Context, user *models
}
}
func (g *GrafanaLive) handleGrafanaScope(_ *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
func (g *GrafanaLive) handleGrafanaScope(_ *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
if p, ok := g.GrafanaScope.Features[namespace]; ok {
return p, nil
}
return nil, fmt.Errorf("unknown feature: %q", namespace)
}
func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
streamHandler, err := g.getStreamPlugin(ctx, namespace)
if err != nil {
return nil, fmt.Errorf("can't find stream plugin: %s", namespace)
@@ -916,11 +918,11 @@ func (g *GrafanaLive) handlePluginScope(ctx context.Context, _ *models.SignedInU
), nil
}
func (g *GrafanaLive) handleStreamScope(u *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
func (g *GrafanaLive) handleStreamScope(u *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
return g.ManagedStreamRunner.GetOrCreateStream(u.OrgId, live.ScopeStream, namespace)
}
func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user *models.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
func (g *GrafanaLive) handleDatasourceScope(ctx context.Context, user *user.SignedInUser, namespace string) (models.ChannelHandlerFactory, error) {
ds, err := g.DataSourceCache.GetDatasourceByUID(ctx, namespace, user, false)
if err != nil {
return nil, fmt.Errorf("error getting datasource: %w", err)
@@ -984,7 +986,7 @@ func (g *GrafanaLive) HandleHTTPPublish(ctx *models.ReqContext) response.Respons
return response.Error(http.StatusForbidden, http.StatusText(http.StatusForbidden), nil)
}
} else {
if !user.HasRole(models.ROLE_ADMIN) {
if !user.HasRole(org.RoleAdmin) {
return response.Error(http.StatusForbidden, http.StatusText(http.StatusForbidden), nil)
}
}
+4 -4
View File
@@ -3,21 +3,21 @@ package livecontext
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
type signedUserContextKeyType int
var signedUserContextKey signedUserContextKeyType
func SetContextSignedUser(ctx context.Context, user *models.SignedInUser) context.Context {
func SetContextSignedUser(ctx context.Context, user *user.SignedInUser) context.Context {
ctx = context.WithValue(ctx, signedUserContextKey, user)
return ctx
}
func GetContextSignedUser(ctx context.Context) (*models.SignedInUser, bool) {
func GetContextSignedUser(ctx context.Context) (*user.SignedInUser, bool) {
if val := ctx.Value(signedUserContextKey); val != nil {
user, ok := val.(*models.SignedInUser)
user, ok := val.(*user.SignedInUser)
return user, ok
}
return nil, false
+2 -2
View File
@@ -4,11 +4,11 @@ import (
"context"
"fmt"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins/plugincontext"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/live/orgchannel"
"github.com/grafana/grafana/pkg/services/live/pipeline"
"github.com/grafana/grafana/pkg/services/user"
"github.com/centrifugal/centrifuge"
"github.com/grafana/grafana-plugin-sdk-go/backend"
@@ -72,7 +72,7 @@ func NewContextGetter(pluginContextProvider *plugincontext.Provider, dataSourceC
}
}
func (g *ContextGetter) GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
func (g *ContextGetter) GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
if datasourceUID == "" {
return g.pluginContextProvider.Get(ctx, pluginID, user)
}
+3 -2
View File
@@ -9,6 +9,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/services/live/orgchannel"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
@@ -238,7 +239,7 @@ func (s *NamespaceStream) GetHandlerForPath(_ string) (models.ChannelHandler, er
return s, nil
}
func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *models.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *user.SignedInUser, e models.SubscribeEvent) (models.SubscribeReply, backend.SubscribeStreamStatus, error) {
reply := models.SubscribeReply{}
frameJSON, ok, err := s.frameCache.GetFrame(ctx, u.OrgId, e.Channel)
if err != nil {
@@ -250,6 +251,6 @@ func (s *NamespaceStream) OnSubscribe(ctx context.Context, u *models.SignedInUse
return reply, backend.SubscribeStreamStatusOK, nil
}
func (s *NamespaceStream) OnPublish(_ context.Context, _ *models.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
func (s *NamespaceStream) OnPublish(_ context.Context, _ *user.SignedInUser, _ models.PublishEvent) (models.PublishReply, backend.PublishStreamStatus, error) {
return models.PublishReply{}, backend.PublishStreamStatusPermissionDenied, nil
}
+6 -5
View File
@@ -3,21 +3,22 @@ package pipeline
import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
)
type RoleCheckAuthorizer struct {
role models.RoleType
role org.RoleType
}
func NewRoleCheckAuthorizer(role models.RoleType) *RoleCheckAuthorizer {
func NewRoleCheckAuthorizer(role org.RoleType) *RoleCheckAuthorizer {
return &RoleCheckAuthorizer{role: role}
}
func (s *RoleCheckAuthorizer) CanSubscribe(_ context.Context, u *models.SignedInUser) (bool, error) {
func (s *RoleCheckAuthorizer) CanSubscribe(_ context.Context, u *user.SignedInUser) (bool, error) {
return u.HasRole(s.role), nil
}
func (s *RoleCheckAuthorizer) CanPublish(_ context.Context, u *models.SignedInUser) (bool, error) {
func (s *RoleCheckAuthorizer) CanPublish(_ context.Context, u *user.SignedInUser) (bool, error) {
return u.HasRole(s.role), nil
}
+2 -2
View File
@@ -2,12 +2,12 @@ package pipeline
import (
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
)
// ChannelAuthCheckConfig is used to define auth rules for a channel.
type ChannelAuthCheckConfig struct {
RequireRole models.RoleType `json:"role,omitempty"`
RequireRole org.RoleType `json:"role,omitempty"`
}
type ChannelAuthConfig struct {
+4 -3
View File
@@ -7,6 +7,7 @@ import (
"os"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
@@ -112,12 +113,12 @@ type Subscriber interface {
// PublishAuthChecker checks whether current user can publish to a channel.
type PublishAuthChecker interface {
CanPublish(ctx context.Context, u *models.SignedInUser) (bool, error)
CanPublish(ctx context.Context, u *user.SignedInUser) (bool, error)
}
// SubscribeAuthChecker checks whether current user can subscribe to a channel.
type SubscribeAuthChecker interface {
CanSubscribe(ctx context.Context, u *models.SignedInUser) (bool, error)
CanSubscribe(ctx context.Context, u *user.SignedInUser) (bool, error)
}
// LiveChannelRule is an in-memory representation of each specific rule to be executed by Pipeline.
@@ -140,7 +141,7 @@ type LiveChannelRule struct {
Subscribers []Subscriber
// PublishAuth allows providing authorization logic for publishing into a channel.
// If PublishAuth is not set then ROLE_ADMIN is required to publish.
// If PublishAuth is not set then RoleAdmin is required to publish.
PublishAuth PublishAuthChecker
// DataOutputters if set allows doing something useful with raw input data. If not set then
// we step further to the converter. Each DataOutputter can optionally return a slice
@@ -5,6 +5,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/live/livecontext"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/live"
@@ -15,7 +16,7 @@ type BuiltinSubscriber struct {
}
type ChannelHandlerGetter interface {
GetChannelHandler(ctx context.Context, user *models.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error)
GetChannelHandler(ctx context.Context, user *user.SignedInUser, channel string) (models.ChannelHandler, live.Channel, error)
}
const SubscriberTypeBuiltin = "builtin"
+4 -4
View File
@@ -9,7 +9,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana-plugin-sdk-go/backend"
)
@@ -25,7 +25,7 @@ type ChannelLocalPublisher interface {
}
type PluginContextGetter interface {
GetPluginContext(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error)
GetPluginContext(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error)
}
type NumLocalSubscribersGetter interface {
@@ -373,7 +373,7 @@ func (s *Manager) Run(ctx context.Context) error {
type streamRequest struct {
Channel string
Path string
user *models.SignedInUser
user *user.SignedInUser
PluginContext backend.PluginContext
StreamRunner StreamRunner
Data []byte
@@ -400,7 +400,7 @@ var errDatasourceNotFound = errors.New("datasource not found")
// SubmitStream submits stream handler in Manager to manage.
// The stream will be opened and kept till channel has active subscribers.
func (s *Manager) SubmitStream(ctx context.Context, user *models.SignedInUser, channel string, path string, data []byte, pCtx backend.PluginContext, streamRunner StreamRunner, isResubmit bool) (*submitResult, error) {
func (s *Manager) SubmitStream(ctx context.Context, user *user.SignedInUser, channel string, path string, data []byte, pCtx backend.PluginContext, streamRunner StreamRunner, isResubmit bool) (*submitResult, error) {
if isResubmit {
// Resolve new plugin context as it could be modified since last call.
var datasourceUID string
+17 -18
View File
@@ -6,10 +6,9 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/golang/mock/gomock"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@@ -71,7 +70,7 @@ func TestStreamManager_SubmitStream_Send(t *testing.T) {
},
}
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
require.Equal(t, int64(2), user.UserId)
require.Equal(t, int64(1), user.OrgId)
require.Equal(t, testPluginContext.PluginID, pluginID)
@@ -94,12 +93,12 @@ func TestStreamManager_SubmitStream_Send(t *testing.T) {
return ctx.Err()
}).Times(1)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, testPluginContext, mockStreamRunner, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, testPluginContext, mockStreamRunner, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
// try submit the same.
result, err = manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
result, err = manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
require.NoError(t, err)
require.True(t, result.StreamExists)
@@ -133,7 +132,7 @@ func TestStreamManager_SubmitStream_DifferentOrgID(t *testing.T) {
mockPacketSender.EXPECT().PublishLocal("1/test", gomock.Any()).Times(1)
mockPacketSender.EXPECT().PublishLocal("2/test", gomock.Any()).Times(1)
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
return backend.PluginContext{}, true, nil
}).Times(0)
@@ -163,12 +162,12 @@ func TestStreamManager_SubmitStream_DifferentOrgID(t *testing.T) {
return ctx.Err()
}).Times(1)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner1, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner1, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
// try submit the same channel but different orgID.
result, err = manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 2}, "2/test", "test", nil, backend.PluginContext{}, mockStreamRunner2, false)
result, err = manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 2}, "2/test", "test", nil, backend.PluginContext{}, mockStreamRunner2, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
@@ -205,7 +204,7 @@ func TestStreamManager_SubmitStream_CloseNoSubscribers(t *testing.T) {
startedCh := make(chan struct{})
doneCh := make(chan struct{})
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
return backend.PluginContext{}, true, nil
}).Times(0)
@@ -219,7 +218,7 @@ func TestStreamManager_SubmitStream_CloseNoSubscribers(t *testing.T) {
return ctx.Err()
}).Times(1)
_, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
_, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "1/test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
require.NoError(t, err)
waitWithTimeout(t, startedCh, time.Second)
@@ -254,7 +253,7 @@ func TestStreamManager_SubmitStream_ErrorRestartsRunStream(t *testing.T) {
},
}
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
require.Equal(t, int64(2), user.UserId)
require.Equal(t, int64(1), user.OrgId)
require.Equal(t, testPluginContext.PluginID, pluginID)
@@ -273,7 +272,7 @@ func TestStreamManager_SubmitStream_ErrorRestartsRunStream(t *testing.T) {
return errors.New("boom")
}).Times(numErrors + 1)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
@@ -296,7 +295,7 @@ func TestStreamManager_SubmitStream_NilErrorStopsRunStream(t *testing.T) {
_ = manager.Run(ctx)
}()
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
return backend.PluginContext{}, true, nil
}).Times(0)
@@ -307,7 +306,7 @@ func TestStreamManager_SubmitStream_NilErrorStopsRunStream(t *testing.T) {
return nil
}).Times(1)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, backend.PluginContext{}, mockStreamRunner, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
waitWithTimeout(t, result.CloseNotify, time.Second)
@@ -337,7 +336,7 @@ func TestStreamManager_HandleDatasourceUpdate(t *testing.T) {
},
}
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
require.Equal(t, int64(2), user.UserId)
require.Equal(t, int64(1), user.OrgId)
require.Equal(t, testPluginContext.PluginID, pluginID)
@@ -366,7 +365,7 @@ func TestStreamManager_HandleDatasourceUpdate(t *testing.T) {
return nil
}).Times(2)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
@@ -403,7 +402,7 @@ func TestStreamManager_HandleDatasourceDelete(t *testing.T) {
},
}
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *models.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
mockContextGetter.EXPECT().GetPluginContext(context.Background(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, user *user.SignedInUser, pluginID string, datasourceUID string, skipCache bool) (backend.PluginContext, bool, error) {
require.Equal(t, int64(2), user.UserId)
require.Equal(t, int64(1), user.OrgId)
require.Equal(t, testPluginContext.PluginID, pluginID)
@@ -422,7 +421,7 @@ func TestStreamManager_HandleDatasourceDelete(t *testing.T) {
return ctx.Err()
}).Times(1)
result, err := manager.SubmitStream(context.Background(), &models.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
result, err := manager.SubmitStream(context.Background(), &user.SignedInUser{UserId: 2, OrgId: 1}, "test", "test", nil, testPluginContext, mockStreamRunner, false)
require.NoError(t, err)
require.False(t, result.StreamExists)
+2 -2
View File
@@ -10,7 +10,7 @@ import (
gomock "github.com/golang/mock/gomock"
backend "github.com/grafana/grafana-plugin-sdk-go/backend"
models "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
// MockChannelLocalPublisher is a mock of ChannelLocalPublisher interface.
@@ -149,7 +149,7 @@ func (m *MockPluginContextGetter) EXPECT() *MockPluginContextGetterMockRecorder
}
// GetPluginContext mocks base method.
func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *models.SignedInUser, arg1, arg2 string, arg3 bool) (backend.PluginContext, bool, error) {
func (m *MockPluginContextGetter) GetPluginContext(ctx context.Context, arg0 *user.SignedInUser, arg1, arg2 string, arg3 bool) (backend.PluginContext, bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetPluginContext", ctx, arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(backend.PluginContext)
@@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
@@ -127,17 +128,17 @@ func createUserOrgDTO() []*models.UserOrgDTO {
{
OrgId: 1,
Name: "Bar",
Role: models.ROLE_VIEWER,
Role: org.RoleViewer,
},
{
OrgId: 10,
Name: "Foo",
Role: models.ROLE_ADMIN,
Role: org.RoleAdmin,
},
{
OrgId: 11,
Name: "Stuff",
Role: models.ROLE_VIEWER,
Role: org.RoleViewer,
},
}
return users
@@ -146,8 +147,8 @@ func createUserOrgDTO() []*models.UserOrgDTO {
func createSimpleExternalUser() models.ExternalUserInfo {
externalUser := models.ExternalUserInfo{
AuthModule: login.LDAPAuthModule,
OrgRoles: map[int64]models.RoleType{
1: models.ROLE_VIEWER,
OrgRoles: map[int64]org.RoleType{
1: org.RoleViewer,
},
}
+4 -4
View File
@@ -1,10 +1,10 @@
package ngalert
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/org"
)
const AlertRolesGroup = "Alerting"
@@ -140,7 +140,7 @@ var (
Group: AlertRolesGroup,
Permissions: accesscontrol.ConcatPermissions(rulesReaderRole.Role.Permissions, instancesReaderRole.Role.Permissions, notificationsReaderRole.Role.Permissions),
},
Grants: []string{string(models.ROLE_VIEWER)},
Grants: []string{string(org.RoleViewer)},
}
alertingWriterRole = accesscontrol.RoleRegistration{
@@ -151,7 +151,7 @@ var (
Group: AlertRolesGroup,
Permissions: accesscontrol.ConcatPermissions(rulesWriterRole.Role.Permissions, instancesWriterRole.Role.Permissions, notificationsWriterRole.Role.Permissions),
},
Grants: []string{string(models.ROLE_EDITOR), string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleEditor), string(org.RoleAdmin)},
}
alertingProvisionerRole = accesscontrol.RoleRegistration{
@@ -169,7 +169,7 @@ var (
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
Grants: []string{string(org.RoleAdmin)},
}
)
@@ -23,8 +23,10 @@ import (
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@@ -167,7 +169,7 @@ func TestAlertmanagerConfig(t *testing.T) {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 12,
},
}
@@ -184,7 +186,7 @@ func TestAlertmanagerConfig(t *testing.T) {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 1,
},
}
@@ -201,7 +203,7 @@ func TestAlertmanagerConfig(t *testing.T) {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: 3, // Org 3 was initialized with broken config.
},
}
@@ -331,8 +333,8 @@ func TestSilenceCreate(t *testing.T) {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
OrgRole: models.ROLE_EDITOR,
SignedInUser: &user.SignedInUser{
OrgRole: org.RoleEditor,
OrgId: 1,
},
}
@@ -353,7 +355,7 @@ func TestRouteCreateSilence(t *testing.T) {
name string
silence func() apimodels.PostableSilence
accessControl func() accesscontrol.AccessControl
role models.RoleType
role org.RoleType
expectedStatus int
}{
{
@@ -380,7 +382,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_VIEWER,
role: org.RoleViewer,
expectedStatus: http.StatusUnauthorized,
},
{
@@ -389,7 +391,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_EDITOR,
role: org.RoleEditor,
expectedStatus: http.StatusAccepted,
},
{
@@ -398,7 +400,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_ADMIN,
role: org.RoleAdmin,
expectedStatus: http.StatusAccepted,
},
{
@@ -425,7 +427,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_VIEWER,
role: org.RoleViewer,
expectedStatus: http.StatusUnauthorized,
},
{
@@ -434,7 +436,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_EDITOR,
role: org.RoleEditor,
expectedStatus: http.StatusAccepted,
},
{
@@ -443,7 +445,7 @@ func TestRouteCreateSilence(t *testing.T) {
accessControl: func() accesscontrol.AccessControl {
return acMock.New().WithDisabled()
},
role: models.ROLE_ADMIN,
role: org.RoleAdmin,
expectedStatus: http.StatusAccepted,
},
}
@@ -457,7 +459,7 @@ func TestRouteCreateSilence(t *testing.T) {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgRole: tesCase.role,
OrgId: 1,
},
@@ -624,7 +626,7 @@ func createRequestCtxInOrg(org int64) *models.ReqContext {
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
SignedInUser: &user.SignedInUser{
OrgId: org,
},
}
@@ -13,6 +13,7 @@ import (
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util"
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
@@ -43,7 +44,7 @@ func (srv ConfigSrv) RouteGetAlertmanagers(c *models.ReqContext) response.Respon
}
func (srv ConfigSrv) RouteGetNGalertConfig(c *models.ReqContext) response.Response {
if c.OrgRole != models.ROLE_ADMIN {
if c.OrgRole != org.RoleAdmin {
return accessForbiddenResp()
}
@@ -66,7 +67,7 @@ func (srv ConfigSrv) RouteGetNGalertConfig(c *models.ReqContext) response.Respon
}
func (srv ConfigSrv) RoutePostNGalertConfig(c *models.ReqContext, body apimodels.PostableNGalertConfig) response.Response {
if c.OrgRole != models.ROLE_ADMIN {
if c.OrgRole != org.RoleAdmin {
return accessForbiddenResp()
}
@@ -108,7 +109,7 @@ func (srv ConfigSrv) RoutePostNGalertConfig(c *models.ReqContext, body apimodels
}
func (srv ConfigSrv) RouteDeleteNGalertConfig(c *models.ReqContext) response.Response {
if c.OrgRole != models.ROLE_ADMIN {
if c.OrgRole != org.RoleAdmin {
return accessForbiddenResp()
}

Some files were not shown because too many files have changed in this diff Show More