mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 04:02:41 +08:00

* remove api key endpoints * generate openapi specs * remove methods from mock service * remove ApiKeyDTO * generate openapi specs * remove apikey migration endpoints * remove unused function
214 lines
8.2 KiB
Go
214 lines
8.2 KiB
Go
package navtreeimpl
|
|
|
|
import (
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
"github.com/grafana/grafana/pkg/login/social"
|
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ssoutils"
|
|
"github.com/grafana/grafana/pkg/services/cloudmigration"
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
|
"github.com/grafana/grafana/pkg/services/correlations"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
"github.com/grafana/grafana/pkg/services/navtree"
|
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
// nolint: gocyclo
|
|
func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink, error) {
|
|
var configNodes []*navtree.NavLink
|
|
ctx := c.Req.Context()
|
|
hasAccess := ac.HasAccess(s.accessControl, c)
|
|
hasGlobalAccess := ac.HasGlobalAccess(s.accessControl, s.authnService, c)
|
|
orgsAccessEvaluator := ac.EvalPermission(ac.ActionOrgsRead)
|
|
authConfigUIAvailable := s.license.FeatureEnabled(social.SAMLProviderName) || s.cfg.LDAPAuthEnabled
|
|
|
|
generalNodeLinks := []*navtree.NavLink{}
|
|
if hasAccess(ac.OrgPreferencesAccessEvaluator) {
|
|
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
|
Text: "Default preferences",
|
|
Id: "org-settings",
|
|
SubTitle: "Manage preferences across an organization",
|
|
Icon: "sliders-v-alt",
|
|
Url: s.cfg.AppSubURL + "/org",
|
|
})
|
|
}
|
|
if hasAccess(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsAll)) {
|
|
generalNodeLinks = append(generalNodeLinks, &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",
|
|
})
|
|
}
|
|
if hasGlobalAccess(orgsAccessEvaluator) {
|
|
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
|
Text: "Organizations", SubTitle: "Isolated instances of Grafana running on the same server", Id: "global-orgs", Url: s.cfg.AppSubURL + "/admin/orgs", Icon: "building",
|
|
})
|
|
}
|
|
if s.features.IsEnabled(ctx, featuremgmt.FlagFeatureToggleAdminPage) && hasAccess(ac.EvalPermission(ac.ActionFeatureManagementRead)) {
|
|
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
|
Text: "Feature toggles",
|
|
SubTitle: "View and edit feature toggles",
|
|
Id: "feature-toggles",
|
|
Url: s.cfg.AppSubURL + "/admin/featuretoggles",
|
|
Icon: "toggle-on",
|
|
})
|
|
}
|
|
if hasAccess(cloudmigration.MigrationAssistantAccess) && s.features.IsEnabled(ctx, featuremgmt.FlagOnPremToCloudMigrations) {
|
|
generalNodeLinks = append(generalNodeLinks, &navtree.NavLink{
|
|
Text: "Migrate to Grafana Cloud",
|
|
Id: "migrate-to-cloud",
|
|
SubTitle: "Copy resources from your self-managed installation to a cloud stack",
|
|
Url: s.cfg.AppSubURL + "/admin/migrate-to-cloud",
|
|
})
|
|
}
|
|
if c.HasRole(identity.RoleAdmin) &&
|
|
(s.cfg.StackID == "" || // show OnPrem even when provisioning is disabled
|
|
s.features.IsEnabledGlobally(featuremgmt.FlagProvisioning)) {
|
|
configNodes = append(configNodes, &navtree.NavLink{
|
|
Text: "Provisioning",
|
|
Id: "provisioning",
|
|
SubTitle: "View and manage your provisioning connections",
|
|
Url: s.cfg.AppSubURL + "/admin/provisioning",
|
|
})
|
|
}
|
|
|
|
generalNode := &navtree.NavLink{
|
|
Text: "General",
|
|
SubTitle: "Manage default preferences and settings across Grafana",
|
|
Id: navtree.NavIDCfgGeneral,
|
|
Url: "/admin/general",
|
|
Icon: "shield",
|
|
Children: generalNodeLinks,
|
|
}
|
|
|
|
if len(generalNode.Children) > 0 {
|
|
configNodes = append(configNodes, generalNode)
|
|
}
|
|
|
|
pluginsNodeLinks := []*navtree.NavLink{}
|
|
// FIXME: If plugin admin is disabled or externally managed, server admins still need to access the page, this is why
|
|
// 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.AdminAccessEvaluator) {
|
|
pluginsNodeLinks = append(pluginsNodeLinks, &navtree.NavLink{
|
|
Text: "Plugins",
|
|
Id: "plugins",
|
|
SubTitle: "Extend the Grafana experience with plugins",
|
|
Icon: "plug",
|
|
Url: s.cfg.AppSubURL + "/plugins",
|
|
})
|
|
}
|
|
if s.features.IsEnabled(ctx, featuremgmt.FlagCorrelations) && hasAccess(correlations.ConfigurationPageAccess) {
|
|
pluginsNodeLinks = append(pluginsNodeLinks, &navtree.NavLink{
|
|
Text: "Correlations",
|
|
Icon: "gf-glue",
|
|
SubTitle: "Add and configure correlations",
|
|
Id: "correlations",
|
|
Url: s.cfg.AppSubURL + "/datasources/correlations",
|
|
})
|
|
}
|
|
|
|
if (s.cfg.Env == setting.Dev) || s.features.IsEnabled(ctx, featuremgmt.FlagEnableExtensionsAdminPage) && hasAccess(pluginaccesscontrol.AdminAccessEvaluator) {
|
|
pluginsNodeLinks = append(pluginsNodeLinks, &navtree.NavLink{
|
|
Text: "Extensions",
|
|
Icon: "plug",
|
|
SubTitle: "Extend the UI of plugins and Grafana",
|
|
Id: "extensions",
|
|
Url: s.cfg.AppSubURL + "/admin/extensions",
|
|
})
|
|
}
|
|
|
|
pluginsNode := &navtree.NavLink{
|
|
Text: "Plugins and data",
|
|
SubTitle: "Install plugins and define the relationships between data",
|
|
Id: navtree.NavIDCfgPlugins,
|
|
Url: "/admin/plugins",
|
|
Icon: "shield",
|
|
Children: pluginsNodeLinks,
|
|
}
|
|
|
|
if len(pluginsNode.Children) > 0 {
|
|
configNodes = append(configNodes, pluginsNode)
|
|
}
|
|
|
|
accessNodeLinks := []*navtree.NavLink{}
|
|
if hasAccess(ac.EvalAny(ac.EvalPermission(ac.ActionOrgUsersRead), ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll))) {
|
|
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
|
Text: "Users", SubTitle: "Manage users in Grafana", Id: "global-users", Url: s.cfg.AppSubURL + "/admin/users", Icon: "user",
|
|
})
|
|
}
|
|
if hasAccess(ac.TeamsAccessEvaluator) {
|
|
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
|
Text: "Teams",
|
|
Id: "teams",
|
|
SubTitle: "Groups of users that have common dashboard and permission needs",
|
|
Icon: "users-alt",
|
|
Url: s.cfg.AppSubURL + "/org/teams",
|
|
})
|
|
}
|
|
if enableServiceAccount(s, c) {
|
|
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
|
Text: "Service accounts",
|
|
Id: "serviceaccounts",
|
|
SubTitle: "Use service accounts to run automated workloads in Grafana",
|
|
Icon: "gf-service-account",
|
|
Url: s.cfg.AppSubURL + "/org/serviceaccounts",
|
|
})
|
|
}
|
|
|
|
if s.license.FeatureEnabled("groupsync") &&
|
|
s.features.IsEnabled(ctx, featuremgmt.FlagGroupAttributeSync) &&
|
|
hasAccess(ac.EvalAny(
|
|
ac.EvalPermission("groupsync.mappings:read"),
|
|
ac.EvalPermission("groupsync.mappings:write"),
|
|
)) {
|
|
accessNodeLinks = append(accessNodeLinks, &navtree.NavLink{
|
|
Text: "External group sync",
|
|
Id: "groupsync",
|
|
SubTitle: "Manage mappings of Identity Provider groups to Grafana Roles",
|
|
Icon: "",
|
|
Url: s.cfg.AppSubURL + "/admin/access/groupsync",
|
|
})
|
|
}
|
|
|
|
usersNode := &navtree.NavLink{
|
|
Text: "Users and access",
|
|
SubTitle: "Configure access for individual users, teams, and service accounts",
|
|
Id: navtree.NavIDCfgAccess,
|
|
Url: "/admin/access",
|
|
Icon: "shield",
|
|
Children: accessNodeLinks,
|
|
}
|
|
|
|
// Always append admin access as it's injected by grafana-auth-app.
|
|
configNodes = append(configNodes, usersNode)
|
|
|
|
if authConfigUIAvailable && hasAccess(ssoutils.EvalAuthenticationSettings(s.cfg)) ||
|
|
(hasAccess(ssoutils.OauthSettingsEvaluator(s.cfg)) && s.features.IsEnabled(ctx, featuremgmt.FlagSsoSettingsApi)) {
|
|
configNodes = append(configNodes, &navtree.NavLink{
|
|
Text: "Authentication",
|
|
Id: "authentication",
|
|
SubTitle: "Manage your auth settings and configure single sign-on",
|
|
Icon: "signin",
|
|
IsSection: true,
|
|
Url: s.cfg.AppSubURL + "/admin/authentication",
|
|
})
|
|
}
|
|
|
|
configNode := &navtree.NavLink{
|
|
Id: navtree.NavIDCfg,
|
|
Text: "Administration",
|
|
SubTitle: "Organization: " + c.GetOrgName(),
|
|
Icon: "cog",
|
|
SortWeight: navtree.WeightConfig,
|
|
Children: configNodes,
|
|
Url: "/admin",
|
|
}
|
|
|
|
return configNode, nil
|
|
}
|
|
|
|
func enableServiceAccount(s *ServiceImpl, c *contextmodel.ReqContext) bool {
|
|
hasAccess := ac.HasAccess(s.accessControl, c)
|
|
return hasAccess(serviceaccounts.AccessEvaluator)
|
|
}
|