mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: Remove legacy AC from HasAccess permission check (#68995)
* remove unused HasAdmin and HasEdit permission methods * remove legacy AC from HasAccess method * remove unused function * update alerting tests to work with RBAC
This commit is contained in:
@@ -6,5 +6,5 @@ import (
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, prefs *pref.Preference) (*NavTreeRoot, error)
|
||||
GetNavTree(c *contextmodel.ReqContext, prefs *pref.Preference) (*NavTreeRoot, error)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/navtree"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
)
|
||||
@@ -19,7 +18,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
orgsAccessEvaluator := ac.EvalPermission(ac.ActionOrgsRead)
|
||||
authConfigUIAvailable := s.license.FeatureEnabled("saml") && s.features.IsEnabled(featuremgmt.FlagAuthenticationConfigUI)
|
||||
|
||||
if hasAccess(ac.ReqOrgAdmin, datasources.ConfigurationPageAccess) {
|
||||
if hasAccess(datasources.ConfigurationPageAccess) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Data sources",
|
||||
Icon: "database",
|
||||
@@ -30,7 +29,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
}
|
||||
|
||||
// FIXME: while we don't have a permissions for listing plugins the legacy check has to stay as a default
|
||||
if pluginaccesscontrol.ReqCanAdminPlugins(s.cfg)(c) || hasAccess(pluginaccesscontrol.ReqCanAdminPlugins(s.cfg), pluginaccesscontrol.AdminAccessEvaluator) {
|
||||
if pluginaccesscontrol.ReqCanAdminPlugins(s.cfg)(c) || hasAccess(pluginaccesscontrol.AdminAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Plugins",
|
||||
Id: "plugins",
|
||||
@@ -40,13 +39,13 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqSignedIn, ac.EvalAny(ac.EvalPermission(ac.ActionOrgUsersRead), ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll))) {
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionOrgUsersRead), ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll))) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Users", SubTitle: "Manage users in Grafana", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(s.ReqCanAdminTeams, ac.TeamsAccessEvaluator) {
|
||||
if hasAccess(ac.TeamsAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Teams",
|
||||
Id: "teams",
|
||||
@@ -70,7 +69,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasAccess(ac.ReqOrgAdmin, ac.ApiKeyAccessEvaluator) && !disabled {
|
||||
if hasAccess(ac.ApiKeyAccessEvaluator) && !disabled {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "API keys",
|
||||
Id: "apikeys",
|
||||
@@ -80,7 +79,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqOrgAdmin, ac.OrgPreferencesAccessEvaluator) {
|
||||
if hasAccess(ac.OrgPreferencesAccessEvaluator) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Default preferences",
|
||||
Id: "org-settings",
|
||||
@@ -90,7 +89,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if authConfigUIAvailable && hasAccess(ac.ReqGrafanaAdmin, evalAuthenticationSettings()) {
|
||||
if authConfigUIAvailable && hasAccess(evalAuthenticationSettings()) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Authentication",
|
||||
Id: "authentication",
|
||||
@@ -100,7 +99,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqGrafanaAdmin, ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) {
|
||||
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Settings", SubTitle: "View the settings defined in your Grafana config", Id: "server-settings", Url: s.cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt",
|
||||
})
|
||||
@@ -112,7 +111,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if s.features.IsEnabled(featuremgmt.FlagCorrelations) && hasAccess(ac.ReqOrgAdmin, correlations.ConfigurationPageAccess) {
|
||||
if s.features.IsEnabled(featuremgmt.FlagCorrelations) && hasAccess(correlations.ConfigurationPageAccess) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "Correlations",
|
||||
Icon: "gf-glue",
|
||||
@@ -122,13 +121,13 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
})
|
||||
}
|
||||
|
||||
if s.cfg.LDAPAuthEnabled && hasAccess(ac.ReqGrafanaAdmin, ac.EvalPermission(ac.ActionLDAPStatusRead)) {
|
||||
if s.cfg.LDAPAuthEnabled && hasAccess(ac.EvalPermission(ac.ActionLDAPStatusRead)) {
|
||||
configNodes = append(configNodes, &navtree.NavLink{
|
||||
Text: "LDAP", Id: "ldap", Url: s.cfg.AppSubURL + "/admin/ldap", Icon: "book",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqGrafanaAdmin, ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) && s.features.IsEnabled(featuremgmt.FlagStorage) {
|
||||
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) && s.features.IsEnabled(featuremgmt.FlagStorage) {
|
||||
storage := &navtree.NavLink{
|
||||
Text: "Storage",
|
||||
Id: "storage",
|
||||
@@ -152,13 +151,9 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
||||
return configNode, nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) ReqCanAdminTeams(c *contextmodel.ReqContext) bool {
|
||||
return c.OrgRole == org.RoleAdmin || (s.cfg.EditorsCanAdmin && c.OrgRole == org.RoleEditor)
|
||||
}
|
||||
|
||||
func enableServiceAccount(s *ServiceImpl, c *contextmodel.ReqContext) bool {
|
||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||
return hasAccess(ac.ReqOrgAdmin, serviceaccounts.AccessEvaluator)
|
||||
return hasAccess(serviceaccounts.AccessEvaluator)
|
||||
}
|
||||
|
||||
func evalAuthenticationSettings() ac.Evaluator {
|
||||
|
||||
@@ -41,8 +41,7 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel
|
||||
continue
|
||||
}
|
||||
|
||||
if !hasAccess(ac.ReqSignedIn,
|
||||
ac.EvalPermission(pluginaccesscontrol.ActionAppAccess, pluginaccesscontrol.ScopeProvider.GetResourceScope(plugin.ID))) {
|
||||
if !hasAccess(ac.EvalPermission(pluginaccesscontrol.ActionAppAccess, pluginaccesscontrol.ScopeProvider.GetResourceScope(plugin.ID))) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -240,7 +239,7 @@ func (s *ServiceImpl) hasAccessToInclude(c *contextmodel.ReqContext, pluginID st
|
||||
return func(include *plugins.Includes) bool {
|
||||
useRBAC := s.features.IsEnabled(featuremgmt.FlagAccessControlOnCall) &&
|
||||
!s.accessControl.IsDisabled() && include.RequiresRBACAction()
|
||||
if useRBAC && !hasAccess(ac.ReqHasRole(include.Role), ac.EvalPermission(include.Action)) {
|
||||
if useRBAC && !hasAccess(ac.EvalPermission(include.Action)) {
|
||||
s.log.Debug("plugin include is covered by RBAC, user doesn't have access",
|
||||
"plugin", pluginID,
|
||||
"include", include.Name)
|
||||
|
||||
@@ -72,13 +72,13 @@ func ProvideService(cfg *setting.Cfg, accessControl ac.AccessControl, pluginStor
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, prefs *pref.Preference) (*navtree.NavTreeRoot, error) {
|
||||
func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Preference) (*navtree.NavTreeRoot, error) {
|
||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||
treeRoot := &navtree.NavTreeRoot{}
|
||||
|
||||
treeRoot.AddSection(s.getHomeNode(c, prefs))
|
||||
|
||||
if hasAccess(ac.ReqSignedIn, ac.EvalPermission(dashboards.ActionDashboardsRead)) {
|
||||
if hasAccess(ac.EvalPermission(dashboards.ActionDashboardsRead)) {
|
||||
starredItemsLinks, err := s.buildStarredItemsNavLinks(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -95,11 +95,11 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, p
|
||||
})
|
||||
}
|
||||
|
||||
if c.IsPublicDashboardView || hasAccess(ac.ReqSignedIn, ac.EvalAny(
|
||||
if c.IsPublicDashboardView || hasAccess(ac.EvalAny(
|
||||
ac.EvalPermission(dashboards.ActionFoldersRead), ac.EvalPermission(dashboards.ActionFoldersCreate),
|
||||
ac.EvalPermission(dashboards.ActionDashboardsRead), ac.EvalPermission(dashboards.ActionDashboardsCreate)),
|
||||
) {
|
||||
dashboardChildLinks := s.buildDashboardNavLinks(c, hasEditPerm)
|
||||
dashboardChildLinks := s.buildDashboardNavLinks(c)
|
||||
|
||||
dashboardLink := &navtree.NavLink{
|
||||
Text: "Dashboards",
|
||||
@@ -114,11 +114,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, p
|
||||
treeRoot.AddSection(dashboardLink)
|
||||
}
|
||||
|
||||
canExplore := func(context *contextmodel.ReqContext) bool {
|
||||
return c.OrgRole == org.RoleAdmin || c.OrgRole == org.RoleEditor || s.cfg.ViewersCanEdit
|
||||
}
|
||||
|
||||
if setting.ExploreEnabled && hasAccess(canExplore, ac.EvalPermission(ac.ActionDatasourcesExplore)) {
|
||||
if setting.ExploreEnabled && hasAccess(ac.EvalPermission(ac.ActionDatasourcesExplore)) {
|
||||
treeRoot.AddSection(&navtree.NavLink{
|
||||
Text: "Explore",
|
||||
Id: "explore",
|
||||
@@ -141,7 +137,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, hasEditPerm bool, p
|
||||
treeRoot.AddSection(legacyAlertSection)
|
||||
}
|
||||
} else if uaVisibleForOrg {
|
||||
if alertingSection := s.buildAlertNavLinks(c, hasEditPerm); alertingSection != nil {
|
||||
if alertingSection := s.buildAlertNavLinks(c); alertingSection != nil {
|
||||
treeRoot.AddSection(alertingSection)
|
||||
}
|
||||
}
|
||||
@@ -220,7 +216,7 @@ func (s *ServiceImpl) addHelpLinks(treeRoot *navtree.NavTreeRoot, c *contextmode
|
||||
ac.EvalPermission(supportbundlesimpl.ActionCreate),
|
||||
)
|
||||
|
||||
if isSupportBundlesEnabled(s) && hasAccess(ac.ReqGrafanaAdmin, supportBundleAccess) {
|
||||
if isSupportBundlesEnabled(s) && hasAccess(supportBundleAccess) {
|
||||
supportBundleNode := &navtree.NavLink{
|
||||
Text: "Support bundles",
|
||||
Id: "support-bundles",
|
||||
@@ -324,11 +320,8 @@ func (s *ServiceImpl) buildStarredItemsNavLinks(c *contextmodel.ReqContext) ([]*
|
||||
return starredItemsChildNavs, nil
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext, hasEditPerm bool) []*navtree.NavLink {
|
||||
func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext) []*navtree.NavLink {
|
||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||
hasEditPermInAnyFolder := func(c *contextmodel.ReqContext) bool {
|
||||
return hasEditPerm
|
||||
}
|
||||
|
||||
dashboardChildNavs := []*navtree.NavLink{}
|
||||
|
||||
@@ -374,17 +367,15 @@ func (s *ServiceImpl) buildDashboardNavLinks(c *contextmodel.ReqContext, hasEdit
|
||||
})
|
||||
}
|
||||
|
||||
if hasEditPerm {
|
||||
if hasAccess(hasEditPermInAnyFolder, ac.EvalPermission(dashboards.ActionDashboardsCreate)) {
|
||||
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
||||
Text: "New dashboard", Icon: "plus", Url: s.cfg.AppSubURL + "/dashboard/new", HideFromTabs: true, Id: "dashboards/new", IsCreateAction: true,
|
||||
})
|
||||
if hasAccess(ac.EvalPermission(dashboards.ActionDashboardsCreate)) {
|
||||
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
||||
Text: "New dashboard", Icon: "plus", Url: s.cfg.AppSubURL + "/dashboard/new", HideFromTabs: true, Id: "dashboards/new", IsCreateAction: true,
|
||||
})
|
||||
|
||||
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
||||
Text: "Import dashboard", SubTitle: "Import dashboard from file or Grafana.com", Id: "dashboards/import", Icon: "plus",
|
||||
Url: s.cfg.AppSubURL + "/dashboard/import", HideFromTabs: true, IsCreateAction: true,
|
||||
})
|
||||
}
|
||||
dashboardChildNavs = append(dashboardChildNavs, &navtree.NavLink{
|
||||
Text: "Import dashboard", SubTitle: "Import dashboard from file or Grafana.com", Id: "dashboards/import", Icon: "plus",
|
||||
Url: s.cfg.AppSubURL + "/dashboard/import", HideFromTabs: true, IsCreateAction: true,
|
||||
})
|
||||
}
|
||||
|
||||
return dashboardChildNavs
|
||||
@@ -416,17 +407,17 @@ func (s *ServiceImpl) buildLegacyAlertNavLinks(c *contextmodel.ReqContext) *navt
|
||||
return &alertNav
|
||||
}
|
||||
|
||||
func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext, hasEditPerm bool) *navtree.NavLink {
|
||||
func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext) *navtree.NavLink {
|
||||
hasAccess := ac.HasAccess(s.accessControl, c)
|
||||
var alertChildNavs []*navtree.NavLink
|
||||
|
||||
if hasAccess(ac.ReqViewer, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleRead), ac.EvalPermission(ac.ActionAlertingRuleExternalRead))) {
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleRead), ac.EvalPermission(ac.ActionAlertingRuleExternalRead))) {
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
||||
Text: "Alert rules", SubTitle: "Rules that determine whether an alert will fire", Id: "alert-list", Url: s.cfg.AppSubURL + "/alerting/list", Icon: "list-ul",
|
||||
})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqOrgAdminOrEditor, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsRead), ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead))) {
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionAlertingNotificationsRead), ac.EvalPermission(ac.ActionAlertingNotificationsExternalRead))) {
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
||||
Text: "Contact points", SubTitle: "Choose how to notify your contact points when an alert instance fires", Id: "receivers", Url: s.cfg.AppSubURL + "/alerting/notifications",
|
||||
Icon: "comment-alt-share",
|
||||
@@ -434,7 +425,7 @@ func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext, hasEditPerm
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Notification policies", SubTitle: "Determine how alerts are routed to contact points", Id: "am-routes", Url: s.cfg.AppSubURL + "/alerting/routes", Icon: "sitemap"})
|
||||
}
|
||||
|
||||
if hasAccess(ac.ReqViewer, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingInstanceRead), ac.EvalPermission(ac.ActionAlertingInstancesExternalRead))) {
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionAlertingInstanceRead), ac.EvalPermission(ac.ActionAlertingInstancesExternalRead))) {
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Silences", SubTitle: "Stop notifications from one or more alerting rules", Id: "silences", Url: s.cfg.AppSubURL + "/alerting/silences", Icon: "bell-slash"})
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{Text: "Alert groups", SubTitle: "See grouped alerts from an Alertmanager instance", Id: "groups", Url: s.cfg.AppSubURL + "/alerting/groups", Icon: "layer-group"})
|
||||
}
|
||||
@@ -446,9 +437,7 @@ func (s *ServiceImpl) buildAlertNavLinks(c *contextmodel.ReqContext, hasEditPerm
|
||||
})
|
||||
}
|
||||
|
||||
fallbackHasEditPerm := func(*contextmodel.ReqContext) bool { return hasEditPerm }
|
||||
|
||||
if hasAccess(fallbackHasEditPerm, ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleCreate), ac.EvalPermission(ac.ActionAlertingRuleExternalWrite))) {
|
||||
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionAlertingRuleCreate), ac.EvalPermission(ac.ActionAlertingRuleExternalWrite))) {
|
||||
alertChildNavs = append(alertChildNavs, &navtree.NavLink{
|
||||
Text: "Create alert rule", SubTitle: "Create an alert rule", Id: "alert",
|
||||
Icon: "plus", Url: s.cfg.AppSubURL + "/alerting/new", HideFromTabs: true, IsCreateAction: true,
|
||||
@@ -480,7 +469,7 @@ func (s *ServiceImpl) buildDataConnectionsNavLink(c *contextmodel.ReqContext) *n
|
||||
|
||||
baseUrl := s.cfg.AppSubURL + "/connections"
|
||||
|
||||
if hasAccess(ac.ReqOrgAdmin, datasources.ConfigurationPageAccess) {
|
||||
if hasAccess(datasources.ConfigurationPageAccess) {
|
||||
// Add new connection
|
||||
children = append(children, &navtree.NavLink{
|
||||
Id: "connections-add-new-connection",
|
||||
|
||||
Reference in New Issue
Block a user