Plugins: Add backend check for app page role access (#78269)
* add backend check for roles * tidy * fix tests * incorporate rbac * fix linter * apply PR feedback * add tests * fix logic * add comment * apply PR feedback
This commit is contained in:
@@ -4,17 +4,21 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/middleware/cookies"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/authn"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
@@ -97,6 +101,54 @@ func CanAdminPlugins(cfg *setting.Cfg, accessControl ac.AccessControl) func(c *c
|
||||
}
|
||||
}
|
||||
|
||||
func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, features featuremgmt.FeatureToggles,
|
||||
logger log.Logger) func(c *contextmodel.ReqContext) {
|
||||
return func(c *contextmodel.ReqContext) {
|
||||
pluginID := web.Params(c.Req)[":id"]
|
||||
p, exists := ps.Plugin(c.Req.Context(), pluginID)
|
||||
if !exists {
|
||||
// The frontend will handle app not found appropriately
|
||||
return
|
||||
}
|
||||
|
||||
permitted := true
|
||||
path := normalizeIncludePath(c.Req.URL.Path)
|
||||
hasAccess := ac.HasAccess(accessControl, c)
|
||||
for _, i := range p.Includes {
|
||||
if i.Type != "page" {
|
||||
continue
|
||||
}
|
||||
|
||||
u, err := url.Parse(i.Path)
|
||||
if err != nil {
|
||||
logger.Error("failed to parse include path", "pluginId", pluginID, "include", i.Name, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if normalizeIncludePath(u.Path) == path {
|
||||
useRBAC := features.IsEnabledGlobally(featuremgmt.FlagAccessControlOnCall) && i.RequiresRBACAction()
|
||||
if useRBAC && !hasAccess(ac.EvalPermission(i.Action)) {
|
||||
logger.Debug("Plugin include is covered by RBAC, user doesn't have access", "plugin", pluginID, "include", i.Name)
|
||||
permitted = false
|
||||
break
|
||||
} else if !useRBAC && !c.HasUserRole(i.Role) {
|
||||
permitted = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !permitted {
|
||||
accessForbidden(c)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeIncludePath(p string) string {
|
||||
return strings.TrimPrefix(filepath.Clean(p), "/")
|
||||
}
|
||||
|
||||
func RoleAuth(roles ...org.RoleType) web.Handler {
|
||||
return func(c *contextmodel.ReqContext) {
|
||||
ok := false
|
||||
|
||||
Reference in New Issue
Block a user