mirror of
https://github.com/grafana/grafana.git
synced 2026-08-18 17:15:08 -05:00
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:
@@ -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}},
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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},
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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{},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 +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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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{}, ¢rifuge.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{}, ¢rifuge.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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user