* 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>
99 lines
3.3 KiB
Go
99 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/grafana/grafana/pkg/api/apierrors"
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/middleware"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/plugins"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
|
|
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
|
"github.com/grafana/grafana/pkg/web"
|
|
)
|
|
|
|
type ImportDashboardAPI struct {
|
|
dashboardImportService dashboardimport.Service
|
|
quotaService QuotaService
|
|
schemaLoaderService SchemaLoaderService
|
|
pluginStore plugins.Store
|
|
ac accesscontrol.AccessControl
|
|
}
|
|
|
|
func New(dashboardImportService dashboardimport.Service, quotaService QuotaService,
|
|
schemaLoaderService SchemaLoaderService, pluginStore plugins.Store, ac accesscontrol.AccessControl) *ImportDashboardAPI {
|
|
return &ImportDashboardAPI{
|
|
dashboardImportService: dashboardImportService,
|
|
quotaService: quotaService,
|
|
schemaLoaderService: schemaLoaderService,
|
|
pluginStore: pluginStore,
|
|
ac: ac,
|
|
}
|
|
}
|
|
|
|
func (api *ImportDashboardAPI) RegisterAPIEndpoints(routeRegister routing.RouteRegister) {
|
|
authorize := acmiddleware.Middleware(api.ac)
|
|
routeRegister.Group("/api/dashboards", func(route routing.RouteRegister) {
|
|
route.Post(
|
|
"/import",
|
|
authorize(middleware.ReqSignedIn, accesscontrol.EvalPermission(accesscontrol.ActionDashboardsCreate)),
|
|
routing.Wrap(api.ImportDashboard),
|
|
)
|
|
}, middleware.ReqSignedIn)
|
|
}
|
|
|
|
func (api *ImportDashboardAPI) ImportDashboard(c *models.ReqContext) response.Response {
|
|
req := dashboardimport.ImportDashboardRequest{}
|
|
if err := web.Bind(c.Req, &req); err != nil {
|
|
return response.Error(http.StatusBadRequest, "bad request data", err)
|
|
}
|
|
|
|
if req.PluginId == "" && req.Dashboard == nil {
|
|
return response.Error(http.StatusUnprocessableEntity, "Dashboard must be set", nil)
|
|
}
|
|
|
|
limitReached, err := api.quotaService.QuotaReached(c, "dashboard")
|
|
if err != nil {
|
|
return response.Error(500, "failed to get quota", err)
|
|
}
|
|
|
|
if limitReached {
|
|
return response.Error(403, "Quota reached", nil)
|
|
}
|
|
|
|
trimDefaults := c.QueryBoolWithDefault("trimdefaults", true)
|
|
if trimDefaults && !api.schemaLoaderService.IsDisabled() {
|
|
req.Dashboard, err = api.schemaLoaderService.DashboardApplyDefaults(req.Dashboard)
|
|
if err != nil {
|
|
return response.Error(http.StatusInternalServerError, "Error while applying default value to the dashboard json", err)
|
|
}
|
|
}
|
|
|
|
req.User = c.SignedInUser
|
|
resp, err := api.dashboardImportService.ImportDashboard(c.Req.Context(), &req)
|
|
if err != nil {
|
|
return apierrors.ToDashboardErrorResponse(c.Req.Context(), api.pluginStore, err)
|
|
}
|
|
|
|
return response.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
type QuotaService interface {
|
|
QuotaReached(c *models.ReqContext, target string) (bool, error)
|
|
}
|
|
|
|
type quotaServiceFunc func(c *models.ReqContext, target string) (bool, error)
|
|
|
|
func (fn quotaServiceFunc) QuotaReached(c *models.ReqContext, target string) (bool, error) {
|
|
return fn(c, target)
|
|
}
|
|
|
|
type SchemaLoaderService interface {
|
|
IsDisabled() bool
|
|
DashboardApplyDefaults(input *simplejson.Json) (*simplejson.Json, error)
|
|
}
|