Access control: Use access control for dashboard and folder (#44702)

* Add actions and scopes

* add resource service for dashboard and folder

* Add dashboard guardian with fgac permission evaluation

* Add CanDelete function to guardian interface

* Add CanDelete property to folder and dashboard dto and set values

* change to correct function name

* Add accesscontrol to folder endpoints

* add access control to dashboard endpoints

* check access for nav links

* Add fixed roles for dashboard and folders

* use correct package

* add hack to override guardian Constructor if accesscontrol is enabled

* Add services

* Add function to handle api backward compatability

* Add permissionServices to HttpServer

* Set permission when new dashboard is created

* Add default permission when creating new dashboard

* Set default permission when creating folder and dashboard

* Add access control filter for dashboard search

* Add to accept list

* Add accesscontrol to dashboardimport

* Disable access control in tests

* Add check to see if user is allow to create a dashboard

* Use SetPermissions

* Use function to set several permissions at once

* remove permissions for folder and dashboard on delete

* update required permission

* set permission for provisioning

* Add CanCreate to dashboard guardian and set correct permisisons for
provisioning

* Dont set admin on folder / dashboard creation

* Add dashboard and folder permission migrations

* Add tests for CanCreate

* Add roles and update descriptions

* Solve uid to id for dashboard and folder permissions

* Add folder and dashboard actions to permission filter

* Handle viewer_can_edit flag

* set folder and dashboard permissions services

* Add dashboard permissions when importing a new dashboard

* Set access control permissions on provisioning

* Pass feature flags and only set permissions if access control is enabled

* only add default permissions for folders and dashboards without folders

* Batch create permissions in migrations


* Remove `dashboards:edit` action

* Remove unused function from interface

* Update pkg/services/guardian/accesscontrol_guardian_test.go

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Karl Persson
2022-03-03 15:05:47 +01:00
committed by GitHub
parent 4caf5dbbd9
commit 4982ca3b1d
49 changed files with 2074 additions and 319 deletions

View File

@ -11,6 +11,8 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"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/util"
@ -71,17 +73,36 @@ func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
return apierrors.ToFolderErrorResponse(err)
}
if hs.Cfg.EditorsCanAdmin {
if err := hs.folderService.MakeUserAdmin(c.Req.Context(), c.OrgId, c.SignedInUser.UserId, folder.Id, true); err != nil {
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
c.SignedInUser.UserId, "error", err)
}
if err := hs.setFolderPermission(c, folder.Id); err != nil {
hs.log.Error("Could not make user admin", "folder", folder.Title, "user",
c.SignedInUser.UserId, "error", err)
}
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
return response.JSON(200, hs.toFolderDto(c.Req.Context(), g, folder))
}
func (hs *HTTPServer) setFolderPermission(c *models.ReqContext, folderID int64) error {
if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
resourceID := strconv.FormatInt(folderID, 10)
svc := hs.permissionServices.GetFolderService()
_, err := svc.SetPermissions(c.Req.Context(), c.OrgId, resourceID, []accesscontrol.SetResourcePermissionCommand{
{UserID: c.UserId, Permission: models.PERMISSION_ADMIN.String()},
{BuiltinRole: string(models.ROLE_EDITOR), Permission: models.PERMISSION_EDIT.String()},
{BuiltinRole: string(models.ROLE_VIEWER), Permission: models.PERMISSION_VIEW.String()},
}...)
if err != nil {
return err
}
} else if hs.Cfg.EditorsCanAdmin {
if err := hs.folderService.MakeUserAdmin(c.Req.Context(), c.OrgId, c.UserId, folderID, true); err != nil {
return err
}
}
return nil
}
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
cmd := models.UpdateFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
@ -121,6 +142,7 @@ func (hs *HTTPServer) toFolderDto(ctx context.Context, g guardian.DashboardGuard
canEdit, _ := g.CanEdit()
canSave, _ := g.CanSave()
canAdmin, _ := g.CanAdmin()
canDelete, _ := g.CanDelete()
// Finding creator and last updater of the folder
updater, creator := anonString, anonString
@ -140,6 +162,7 @@ func (hs *HTTPServer) toFolderDto(ctx context.Context, g guardian.DashboardGuard
CanSave: canSave,
CanEdit: canEdit,
CanAdmin: canAdmin,
CanDelete: canDelete,
CreatedBy: creator,
Created: folder.Created,
UpdatedBy: updater,