mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 18:01:40 -06:00
Chore: Propagate context for dashboard guardian (#39201)
Require guardian.New to take context.Context as first argument. Migrates the GetDashboardAclInfoListQuery to be dispatched using context. Ref #36734 Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com> Co-authored-by: sam boyer <sam.boyer@grafana.com>
This commit is contained in:
parent
914ae81026
commit
518a0d0458
@ -1,10 +1,15 @@
|
||||
package api
|
||||
|
||||
import "github.com/grafana/grafana/pkg/models"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
// updateDashboardACL updates a dashboard's ACL items.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
return hs.SQLStore.UpdateDashboardACL(dashID, items)
|
||||
var updateDashboardACL = func(ctx context.Context, s dashboards.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return s.UpdateDashboardACLCtx(ctx, dashID, items)
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ func PauseAlert(c *models.ReqContext, dto dtos.PauseAlertCommand) response.Respo
|
||||
return response.Error(500, "Get Alert failed", err)
|
||||
}
|
||||
|
||||
guardian := guardian.New(query.Result.DashboardId, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), query.Result.DashboardId, c.OrgId, c.SignedInUser)
|
||||
if canEdit, err := guardian.CanEdit(); err != nil || !canEdit {
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking permissions for Alert", err)
|
||||
|
@ -265,7 +265,7 @@ func canSaveByDashboardID(c *models.ReqContext, dashboardID int64) (bool, error)
|
||||
}
|
||||
|
||||
if dashboardID != 0 {
|
||||
guard := guardian.New(dashboardID, c.OrgId, c.SignedInUser)
|
||||
guard := guardian.New(c.Req.Context(), dashboardID, c.OrgId, c.SignedInUser)
|
||||
if canEdit, err := guard.CanEdit(); err != nil || !canEdit {
|
||||
return false, err
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
}
|
||||
}
|
||||
|
||||
guardian := guardian.New(dash.Id, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dash.Id, c.OrgId, c.SignedInUser)
|
||||
if canView, err := guardian.CanView(); err != nil || !canView {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -238,7 +238,7 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
||||
return rsp
|
||||
}
|
||||
|
||||
guardian := guardian.New(dash.Id, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dash.Id, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -508,7 +508,7 @@ func (hs *HTTPServer) addGettingStartedPanelToHomeDashboard(c *models.ReqContext
|
||||
func GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
dashID := c.ParamsInt64(":dashboardId")
|
||||
|
||||
guardian := guardian.New(dashID, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -547,7 +547,7 @@ func GetDashboardVersions(c *models.ReqContext) response.Response {
|
||||
func GetDashboardVersion(c *models.ReqContext) response.Response {
|
||||
dashID := c.ParamsInt64(":dashboardId")
|
||||
|
||||
guardian := guardian.New(dashID, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -584,13 +584,13 @@ func GetDashboardVersion(c *models.ReqContext) response.Response {
|
||||
|
||||
// POST /api/dashboards/calculate-diff performs diffs on two dashboards
|
||||
func CalculateDashboardDiff(c *models.ReqContext, apiOptions dtos.CalculateDiffOptions) response.Response {
|
||||
guardianBase := guardian.New(apiOptions.Base.DashboardId, c.OrgId, c.SignedInUser)
|
||||
guardianBase := guardian.New(c.Req.Context(), apiOptions.Base.DashboardId, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardianBase.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
||||
if apiOptions.Base.DashboardId != apiOptions.New.DashboardId {
|
||||
guardianNew := guardian.New(apiOptions.New.DashboardId, c.OrgId, c.SignedInUser)
|
||||
guardianNew := guardian.New(c.Req.Context(), apiOptions.New.DashboardId, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardianNew.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -633,7 +633,7 @@ func (hs *HTTPServer) RestoreDashboardVersion(c *models.ReqContext, apiCmd dtos.
|
||||
return rsp
|
||||
}
|
||||
|
||||
guardian := guardian.New(dash.Id, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dash.Id, c.OrgId, c.SignedInUser)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ func (hs *HTTPServer) GetDashboardPermissionList(c *models.ReqContext) response.
|
||||
return rsp
|
||||
}
|
||||
|
||||
g := guardian.New(dashID, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
|
||||
|
||||
if canAdmin, err := g.CanAdmin(); err != nil || !canAdmin {
|
||||
return dashboardGuardianResponse(err)
|
||||
@ -62,7 +62,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt
|
||||
return rsp
|
||||
}
|
||||
|
||||
g := guardian.New(dashID, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), dashID, c.OrgId, c.SignedInUser)
|
||||
if canAdmin, err := g.CanAdmin(); err != nil || !canAdmin {
|
||||
return dashboardGuardianResponse(err)
|
||||
}
|
||||
@ -99,7 +99,7 @@ func (hs *HTTPServer) UpdateDashboardPermissions(c *models.ReqContext, apiCmd dt
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := updateDashboardACL(hs, dashID, items); err != nil {
|
||||
if err := updateDashboardACL(c.Req.Context(), hs.SQLStore, dashID, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) ||
|
||||
errors.Is(err, models.ErrDashboardPermissionDashboardEmpty) {
|
||||
return response.Error(409, err.Error(), err)
|
||||
|
@ -6,15 +6,17 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/dashboards"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
@ -342,7 +344,7 @@ func TestDashboardPermissionAPIEndpoint(t *testing.T) {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(hs *HTTPServer, folderID int64, items []*models.DashboardAcl) error {
|
||||
updateDashboardACL = func(_ context.Context, _ dashboards.Store, folderID int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
@ -368,7 +370,7 @@ func callUpdateDashboardPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
updateDashboardACL = func(_ context.Context, _ dashboards.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ func DeleteDashboardSnapshot(c *models.ReqContext) response.Response {
|
||||
|
||||
dashboardID := query.Result.Dashboard.Get("id").MustInt64()
|
||||
|
||||
guardian := guardian.New(dashboardID, c.OrgId, c.SignedInUser)
|
||||
guardian := guardian.New(c.Req.Context(), dashboardID, c.OrgId, c.SignedInUser)
|
||||
canEdit, err := guardian.CanEdit()
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while checking permissions for snapshot", err)
|
||||
|
@ -44,7 +44,7 @@ func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext, cmd models.CreateFolder
|
||||
}
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, folder))
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func (hs *HTTPServer) UpdateFolder(c *models.ReqContext, cmd models.UpdateFolder
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
g := guardian.New(cmd.Result.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), cmd.Result.Id, c.OrgId, c.SignedInUser)
|
||||
return response.JSON(200, toFolderDto(c.Req.Context(), g, cmd.Result))
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/apierrors"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
@ -11,7 +13,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) GetFolderPermissionList(c *models.ReqContext) response.Response {
|
||||
@ -22,7 +23,7 @@ func (hs *HTTPServer) GetFolderPermissionList(c *models.ReqContext) response.Res
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
|
||||
if canAdmin, err := g.CanAdmin(); err != nil || !canAdmin {
|
||||
return apierrors.ToFolderErrorResponse(models.ErrFolderAccessDenied)
|
||||
@ -69,7 +70,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
|
||||
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
|
||||
canAdmin, err := g.CanAdmin()
|
||||
if err != nil {
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
@ -112,7 +113,7 @@ func (hs *HTTPServer) UpdateFolderPermissions(c *models.ReqContext, apiCmd dtos.
|
||||
return response.Error(403, "Cannot remove own admin permission for a folder", nil)
|
||||
}
|
||||
|
||||
if err := updateDashboardACL(hs, folder.Id, items); err != nil {
|
||||
if err := updateDashboardACL(c.Req.Context(), hs.SQLStore, folder.Id, items); err != nil {
|
||||
if errors.Is(err, models.ErrDashboardAclInfoMissing) {
|
||||
err = models.ErrFolderAclInfoMissing
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
dashboardifaces "github.com/grafana/grafana/pkg/dashboards"
|
||||
"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/setting"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
@ -360,7 +363,7 @@ func TestFolderPermissionAPIEndpoint(t *testing.T) {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
var gotItems []*models.DashboardAcl
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
updateDashboardACL = func(_ context.Context, _ dashboardifaces.Store, _ int64, items []*models.DashboardAcl) error {
|
||||
gotItems = items
|
||||
return nil
|
||||
}
|
||||
@ -385,7 +388,7 @@ func callUpdateFolderPermissions(t *testing.T, sc *scenarioContext) {
|
||||
t.Cleanup(func() {
|
||||
updateDashboardACL = origUpdateDashboardACL
|
||||
})
|
||||
updateDashboardACL = func(hs *HTTPServer, dashID int64, items []*models.DashboardAcl) error {
|
||||
updateDashboardACL = func(_ context.Context, _ dashboardifaces.Store, dashID int64, items []*models.DashboardAcl) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
package dashboards
|
||||
|
||||
import "github.com/grafana/grafana/pkg/models"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
// Store is a dashboard store.
|
||||
type Store interface {
|
||||
@ -12,7 +16,7 @@ type Store interface {
|
||||
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
|
||||
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
|
||||
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
|
||||
UpdateDashboardACL(uid int64, items []*models.DashboardAcl) error
|
||||
UpdateDashboardACLCtx(ctx context.Context, uid int64, items []*models.DashboardAcl) error
|
||||
// SaveAlerts saves dashboard alerts.
|
||||
SaveAlerts(dashID int64, alerts []*models.Alert) error
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func (dr *dashboardServiceImpl) MakeUserAdmin(ctx context.Context, orgID int64,
|
||||
)
|
||||
}
|
||||
|
||||
if err := dr.dashboardStore.UpdateDashboardACL(dashboardID, items); err != nil {
|
||||
if err := dr.dashboardStore.UpdateDashboardACLCtx(ctx, dashboardID, items); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO,
|
||||
}
|
||||
|
||||
if isParentFolderChanged {
|
||||
folderGuardian := guardian.New(dash.FolderId, dto.OrgId, dto.User)
|
||||
folderGuardian := guardian.New(context.TODO(), dash.FolderId, dto.OrgId, dto.User)
|
||||
if canSave, err := folderGuardian.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -144,7 +144,7 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO,
|
||||
}
|
||||
}
|
||||
|
||||
guard := guardian.New(dash.GetDashboardIdForSavePermissionCheck(), dto.OrgId, dto.User)
|
||||
guard := guardian.New(context.TODO(), dash.GetDashboardIdForSavePermissionCheck(), dto.OrgId, dto.User)
|
||||
if canSave, err := guard.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -72,7 +72,7 @@ func (dr *dashboardServiceImpl) GetFolderByID(ctx context.Context, id int64) (*m
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
|
||||
g := guardian.New(dashFolder.Id, dr.orgId, dr.user)
|
||||
g := guardian.New(ctx, dashFolder.Id, dr.orgId, dr.user)
|
||||
if canView, err := g.CanView(); err != nil || !canView {
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@ -91,7 +91,7 @@ func (dr *dashboardServiceImpl) GetFolderByUID(ctx context.Context, uid string)
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
|
||||
g := guardian.New(dashFolder.Id, dr.orgId, dr.user)
|
||||
g := guardian.New(ctx, dashFolder.Id, dr.orgId, dr.user)
|
||||
if canView, err := g.CanView(); err != nil || !canView {
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@ -108,7 +108,7 @@ func (dr *dashboardServiceImpl) GetFolderByTitle(ctx context.Context, title stri
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
|
||||
g := guardian.New(dashFolder.Id, dr.orgId, dr.user)
|
||||
g := guardian.New(ctx, dashFolder.Id, dr.orgId, dr.user)
|
||||
if canView, err := g.CanView(); err != nil || !canView {
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
@ -200,7 +200,7 @@ func (dr *dashboardServiceImpl) DeleteFolder(ctx context.Context, uid string, fo
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
|
||||
guardian := guardian.New(dashFolder.Id, dr.orgId, dr.user)
|
||||
guardian := guardian.New(ctx, dashFolder.Id, dr.orgId, dr.user)
|
||||
if canSave, err := guardian.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package guardian
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@ -40,15 +41,17 @@ type dashboardGuardianImpl struct {
|
||||
acl []*models.DashboardAclInfoDTO
|
||||
teams []*models.TeamDTO
|
||||
log log.Logger
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// New factory for creating a new dashboard guardian instance
|
||||
var New = func(dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
|
||||
var New = func(ctx context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
|
||||
return &dashboardGuardianImpl{
|
||||
user: user,
|
||||
dashId: dashId,
|
||||
orgId: orgId,
|
||||
log: log.New("dashboard.permissions"),
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +204,7 @@ func (g *dashboardGuardianImpl) GetAcl() ([]*models.DashboardAclInfoDTO, error)
|
||||
}
|
||||
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: g.dashId, OrgID: g.orgId}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
if err := bus.DispatchCtx(g.ctx, &query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -251,6 +254,7 @@ func (g *dashboardGuardianImpl) getTeams() ([]*models.TeamDTO, error) {
|
||||
}
|
||||
|
||||
query := models.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId}
|
||||
// TODO: Use bus.DispatchCtx(g.Ctx, &query) when GetTeamsByUserQuery supports context.
|
||||
err := bus.Dispatch(&query)
|
||||
|
||||
g.teams = query.Result
|
||||
@ -343,7 +347,7 @@ func (g *FakeDashboardGuardian) GetHiddenACL(cfg *setting.Cfg) ([]*models.Dashbo
|
||||
|
||||
// nolint:unused
|
||||
func MockDashboardGuardian(mock *FakeDashboardGuardian) {
|
||||
New = func(dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
|
||||
New = func(_ context.Context, dashId int64, orgId int64, user *models.SignedInUser) DashboardGuardian {
|
||||
mock.OrgId = orgId
|
||||
mock.DashId = dashId
|
||||
mock.User = user
|
||||
|
@ -1,6 +1,7 @@
|
||||
package guardian
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
@ -701,7 +702,7 @@ func TestGuardianGetHiddenACL(t *testing.T) {
|
||||
UserId: 1,
|
||||
Login: "user1",
|
||||
}
|
||||
g := New(dashboardID, orgID, user)
|
||||
g := New(context.Background(), dashboardID, orgID, user)
|
||||
|
||||
hiddenACL, err := g.GetHiddenACL(cfg)
|
||||
So(err, ShouldBeNil)
|
||||
@ -717,7 +718,7 @@ func TestGuardianGetHiddenACL(t *testing.T) {
|
||||
Login: "user1",
|
||||
IsGrafanaAdmin: true,
|
||||
}
|
||||
g := New(dashboardID, orgID, user)
|
||||
g := New(context.Background(), dashboardID, orgID, user)
|
||||
|
||||
hiddenACL, err := g.GetHiddenACL(cfg)
|
||||
So(err, ShouldBeNil)
|
||||
@ -751,7 +752,7 @@ func TestGuardianGetAclWithoutDuplicates(t *testing.T) {
|
||||
UserId: 1,
|
||||
Login: "user1",
|
||||
}
|
||||
g := New(dashboardID, orgID, user)
|
||||
g := New(context.Background(), dashboardID, orgID, user)
|
||||
|
||||
acl, err := g.GetACLWithoutDuplicates()
|
||||
require.NoError(t, err)
|
||||
|
@ -2,6 +2,7 @@ package guardian
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -35,7 +36,7 @@ func orgRoleScenario(desc string, t *testing.T, role models.RoleType, fn scenari
|
||||
OrgId: orgID,
|
||||
OrgRole: role,
|
||||
}
|
||||
guard := New(dashboardID, orgID, user)
|
||||
guard := New(context.Background(), dashboardID, orgID, user)
|
||||
|
||||
sc := &scenarioContext{
|
||||
t: t,
|
||||
@ -56,7 +57,7 @@ func apiKeyScenario(desc string, t *testing.T, role models.RoleType, fn scenario
|
||||
OrgRole: role,
|
||||
ApiKeyId: 10,
|
||||
}
|
||||
guard := New(dashboardID, orgID, user)
|
||||
guard := New(context.Background(), dashboardID, orgID, user)
|
||||
sc := &scenarioContext{
|
||||
t: t,
|
||||
orgRoleScenario: desc,
|
||||
@ -107,7 +108,7 @@ func permissionScenario(desc string, dashboardID int64, sc *scenarioContext,
|
||||
})
|
||||
|
||||
sc.permissionScenario = desc
|
||||
sc.g = New(dashboardID, sc.givenUser.OrgId, sc.givenUser)
|
||||
sc.g = New(context.Background(), dashboardID, sc.givenUser.OrgId, sc.givenUser)
|
||||
sc.givenDashboardID = dashboardID
|
||||
sc.givenPermissions = permissions
|
||||
sc.givenTeams = teams
|
||||
|
@ -39,7 +39,7 @@ func (l *LibraryElementService) requirePermissionsOnFolder(ctx context.Context,
|
||||
return err
|
||||
}
|
||||
|
||||
g := guardian.New(folder.Id, user.OrgId, user)
|
||||
g := guardian.New(ctx, folder.Id, user.OrgId, user)
|
||||
|
||||
canEdit, err := g.CanEdit()
|
||||
if err != nil {
|
||||
|
@ -68,7 +68,7 @@ func (h *DashboardHandler) OnSubscribe(ctx context.Context, user *models.SignedI
|
||||
}
|
||||
|
||||
dash := query.Result
|
||||
guard := guardian.New(dash.Id, user.OrgId, user)
|
||||
guard := guardian.New(ctx, dash.Id, user.OrgId, user)
|
||||
if canView, err := guard.CanView(); err != nil || !canView {
|
||||
return models.SubscribeReply{}, backend.SubscribeStreamStatusPermissionDenied, nil
|
||||
}
|
||||
@ -114,7 +114,7 @@ func (h *DashboardHandler) OnPublish(ctx context.Context, user *models.SignedInU
|
||||
return models.PublishReply{}, backend.PublishStreamStatusNotFound, nil
|
||||
}
|
||||
|
||||
guard := guardian.New(query.Result.Id, user.OrgId, user)
|
||||
guard := guardian.New(ctx, query.Result.Id, user.OrgId, user)
|
||||
canEdit, err := guard.CanEdit()
|
||||
if err != nil {
|
||||
return models.PublishReply{}, backend.PublishStreamStatusNotFound, fmt.Errorf("internal error")
|
||||
|
@ -404,7 +404,7 @@ func (st DBstore) GetNamespaceByTitle(ctx context.Context, namespace string, org
|
||||
}
|
||||
|
||||
if withCanSave {
|
||||
g := guardian.New(folder.Id, orgID, user)
|
||||
g := guardian.New(ctx, folder.Id, orgID, user)
|
||||
if canSave, err := g.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
st.Logger.Error("checking can save permission has failed", "userId", user.UserId, "username", user.Login, "namespace", namespace, "orgId", orgID, "error", err)
|
||||
|
@ -8,12 +8,16 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetDashboardAclInfoList)
|
||||
func (ss *SQLStore) addDashboardACLQueryAndCommandHandlers() {
|
||||
bus.AddHandlerCtx("sql", ss.GetDashboardAclInfoList)
|
||||
}
|
||||
|
||||
func (ss *SQLStore) UpdateDashboardACL(dashboardID int64, items []*models.DashboardAcl) error {
|
||||
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
|
||||
return ss.UpdateDashboardACLCtx(context.TODO(), dashboardID, items)
|
||||
}
|
||||
|
||||
func (ss *SQLStore) UpdateDashboardACLCtx(ctx context.Context, dashboardID int64, items []*models.DashboardAcl) error {
|
||||
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
// delete existing items
|
||||
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", dashboardID)
|
||||
if err != nil {
|
||||
@ -47,13 +51,13 @@ func (ss *SQLStore) UpdateDashboardACL(dashboardID int64, items []*models.Dashbo
|
||||
// 1) Permissions for the dashboard
|
||||
// 2) permissions for its parent folder
|
||||
// 3) if no specific permissions have been set for the dashboard or its parent folder then get the default permissions
|
||||
func GetDashboardAclInfoList(query *models.GetDashboardAclInfoListQuery) error {
|
||||
var err error
|
||||
func (ss *SQLStore) GetDashboardAclInfoList(ctx context.Context, query *models.GetDashboardAclInfoListQuery) error {
|
||||
outerErr := ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
query.Result = make([]*models.DashboardAclInfoDTO, 0)
|
||||
falseStr := dialect.BooleanStr(false)
|
||||
|
||||
falseStr := dialect.BooleanStr(false)
|
||||
|
||||
if query.DashboardID == 0 {
|
||||
sql := `SELECT
|
||||
if query.DashboardID == 0 {
|
||||
sql := `SELECT
|
||||
da.id,
|
||||
da.org_id,
|
||||
da.dashboard_id,
|
||||
@ -69,13 +73,13 @@ func GetDashboardAclInfoList(query *models.GetDashboardAclInfoListQuery) error {
|
||||
'' as title,
|
||||
'' as slug,
|
||||
'' as uid,` +
|
||||
falseStr + ` AS is_folder,` +
|
||||
falseStr + ` AS inherited
|
||||
falseStr + ` AS is_folder,` +
|
||||
falseStr + ` AS inherited
|
||||
FROM dashboard_acl as da
|
||||
WHERE da.dashboard_id = -1`
|
||||
query.Result = make([]*models.DashboardAclInfoDTO, 0)
|
||||
err = x.SQL(sql).Find(&query.Result)
|
||||
} else {
|
||||
return dbSession.SQL(sql).Find(&query.Result)
|
||||
}
|
||||
|
||||
rawSQL := `
|
||||
-- get permissions for the dashboard and its parent folder
|
||||
SELECT
|
||||
@ -115,13 +119,16 @@ func GetDashboardAclInfoList(query *models.GetDashboardAclInfoListQuery) error {
|
||||
ORDER BY da.id ASC
|
||||
`
|
||||
|
||||
query.Result = make([]*models.DashboardAclInfoDTO, 0)
|
||||
err = x.SQL(rawSQL, query.OrgID, query.DashboardID).Find(&query.Result)
|
||||
return dbSession.SQL(rawSQL, query.OrgID, query.DashboardID).Find(&query.Result)
|
||||
})
|
||||
|
||||
if outerErr != nil {
|
||||
return outerErr
|
||||
}
|
||||
|
||||
for _, p := range query.Result {
|
||||
p.PermissionName = p.Permission.String()
|
||||
}
|
||||
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@ -32,7 +33,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading folder acl should include default acl", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 2)
|
||||
@ -48,7 +49,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should include acl for parent folder", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: childDash.Id, OrgID: 1}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 2)
|
||||
@ -69,7 +70,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should return no acl items", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: childDash.Id, OrgID: 1}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 0)
|
||||
@ -88,7 +89,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should include acl for parent folder", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: childDash.Id, OrgID: 1}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 1)
|
||||
@ -107,7 +108,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should include acl for parent folder and child", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{OrgID: 1, DashboardID: childDash.Id}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 2)
|
||||
@ -131,7 +132,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should include default acl for parent folder and the child acl", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{OrgID: 1, DashboardID: childDash.Id}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
defaultPermissionsId := -1
|
||||
@ -157,7 +158,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q1 := &models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
err = GetDashboardAclInfoList(q1)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), q1)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
@ -172,7 +173,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 0)
|
||||
})
|
||||
@ -192,7 +193,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q1 := &models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
err = GetDashboardAclInfoList(q1)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), q1)
|
||||
So(err, ShouldBeNil)
|
||||
So(q1.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
So(q1.Result[0].Permission, ShouldEqual, models.PERMISSION_EDIT)
|
||||
@ -209,7 +210,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
q3 := &models.GetDashboardAclInfoListQuery{DashboardID: savedFolder.Id, OrgID: 1}
|
||||
err = GetDashboardAclInfoList(q3)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), q3)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(q3.Result), ShouldEqual, 1)
|
||||
So(q3.Result[0].DashboardId, ShouldEqual, savedFolder.Id)
|
||||
@ -225,7 +226,7 @@ func TestDashboardAclDataAccess(t *testing.T) {
|
||||
Convey("When reading dashboard acl should return default permissions", func() {
|
||||
query := models.GetDashboardAclInfoListQuery{DashboardID: rootFolderId, OrgID: 1}
|
||||
|
||||
err := GetDashboardAclInfoList(&query)
|
||||
err := sqlStore.GetDashboardAclInfoList(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(query.Result), ShouldEqual, 2)
|
||||
|
@ -338,7 +338,7 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Should remove dependent permissions for deleted org user", func() {
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash1.Id, OrgID: ac1.OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(permQuery.Result), ShouldEqual, 0)
|
||||
@ -346,7 +346,7 @@ func TestAccountDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Should not remove dashboard permissions for same user in another org", func() {
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash2.Id, OrgID: ac3.OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(permQuery.Result), ShouldEqual, 1)
|
||||
|
@ -113,6 +113,7 @@ func newSQLStore(cfg *setting.Cfg, cacheService *localcache.CacheService, bus bu
|
||||
ss.addAlertNotificationUidByIdHandler()
|
||||
ss.addPreferencesQueryAndCommandHandlers()
|
||||
ss.addDashboardQueryAndCommandHandlers()
|
||||
ss.addDashboardACLQueryAndCommandHandlers()
|
||||
ss.addQuotaQueryAndCommandHandlers()
|
||||
|
||||
// if err := ss.Reset(); err != nil {
|
||||
|
@ -262,7 +262,7 @@ func TestTeamCommandsAndQueries(t *testing.T) {
|
||||
So(err, ShouldEqual, models.ErrTeamNotFound)
|
||||
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: testOrgID}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
err = sqlStore.GetDashboardAclInfoList(context.Background(), permQuery)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(len(permQuery.Result), ShouldEqual, 0)
|
||||
|
@ -261,7 +261,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
require.Len(t, query1.Result, 1)
|
||||
|
||||
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
err = ss.GetDashboardAclInfoList(context.Background(), permQuery)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Len(t, permQuery.Result, 0)
|
||||
@ -347,7 +347,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
require.Len(t, query2.Result, 1)
|
||||
|
||||
permQuery = &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgId}
|
||||
err = GetDashboardAclInfoList(permQuery)
|
||||
err = ss.GetDashboardAclInfoList(context.Background(), permQuery)
|
||||
require.Nil(t, err)
|
||||
|
||||
require.Len(t, permQuery.Result, 0)
|
||||
|
Loading…
Reference in New Issue
Block a user