2022-09-22 15:04:48 -05:00
package navtreeimpl
import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
2023-01-27 01:50:36 -06:00
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
2022-09-22 15:04:48 -05:00
"github.com/grafana/grafana/pkg/services/correlations"
"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"
2023-03-27 04:15:37 -05:00
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
2022-09-22 15:04:48 -05:00
"github.com/grafana/grafana/pkg/services/serviceaccounts"
)
2023-04-20 05:10:12 -05:00
func ( s * ServiceImpl ) getAdminNode ( c * contextmodel . ReqContext ) ( * navtree . NavLink , error ) {
2022-09-22 15:04:48 -05:00
var configNodes [ ] * navtree . NavLink
hasAccess := ac . HasAccess ( s . accessControl , c )
2023-04-20 05:10:12 -05:00
hasGlobalAccess := ac . HasGlobalAccess ( s . accessControl , s . accesscontrolService , c )
orgsAccessEvaluator := ac . EvalPermission ( ac . ActionOrgsRead )
authConfigUIAvailable := s . license . FeatureEnabled ( "saml" ) && s . features . IsEnabled ( featuremgmt . FlagAuthenticationConfigUI )
2022-09-22 15:04:48 -05:00
if hasAccess ( ac . ReqOrgAdmin , datasources . ConfigurationPageAccess ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Data sources" ,
Icon : "database" ,
SubTitle : "Add and configure data sources" ,
Id : "datasources" ,
Url : s . cfg . AppSubURL + "/datasources" ,
2022-09-22 15:04:48 -05:00
} )
}
2023-04-20 05:10:12 -05:00
// 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 ) {
2022-09-22 15:04:48 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2023-04-20 05:10:12 -05:00
Text : "Plugins" ,
Id : "plugins" ,
SubTitle : "Extend the Grafana experience with plugins" ,
Icon : "plug" ,
Url : s . cfg . AppSubURL + "/plugins" ,
} )
}
if hasAccess ( ac . ReqSignedIn , 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" ,
2022-09-22 15:04:48 -05:00
} )
}
if hasAccess ( s . ReqCanAdminTeams , ac . TeamsAccessEvaluator ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Teams" ,
Id : "teams" ,
SubTitle : "Groups of users that have common dashboard and permission needs" ,
Icon : "users-alt" ,
Url : s . cfg . AppSubURL + "/org/teams" ,
2022-09-22 15:04:48 -05:00
} )
}
2023-04-20 05:10:12 -05:00
if enableServiceAccount ( s , c ) {
2022-09-22 15:04:48 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2023-04-20 05:10:12 -05:00
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" ,
2022-09-22 15:04:48 -05:00
} )
}
2023-03-03 10:12:34 -06:00
disabled , err := s . apiKeyService . IsDisabled ( c . Req . Context ( ) , c . OrgID )
2022-09-22 15:04:48 -05:00
if err != nil {
return nil , err
}
2023-03-03 10:12:34 -06:00
if hasAccess ( ac . ReqOrgAdmin , ac . ApiKeyAccessEvaluator ) && ! disabled {
2022-09-22 15:04:48 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "API keys" ,
Id : "apikeys" ,
SubTitle : "Manage and create API keys that are used to interact with Grafana HTTP APIs" ,
Icon : "key-skeleton-alt" ,
Url : s . cfg . AppSubURL + "/org/apikeys" ,
2022-09-22 15:04:48 -05:00
} )
}
2023-04-20 05:10:12 -05:00
if hasAccess ( ac . ReqOrgAdmin , ac . OrgPreferencesAccessEvaluator ) {
2022-09-22 15:04:48 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2023-04-20 05:10:12 -05:00
Text : "Default preferences" ,
Id : "org-settings" ,
SubTitle : "Manage preferences across an organization" ,
Icon : "sliders-v-alt" ,
Url : s . cfg . AppSubURL + "/org" ,
2023-04-14 03:43:11 -05:00
} )
2022-09-28 01:29:35 -05:00
}
2023-04-13 09:07:43 -05:00
if authConfigUIAvailable && hasAccess ( ac . ReqGrafanaAdmin , evalAuthenticationSettings ( ) ) {
2023-04-20 05:10:12 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2023-04-13 09:07:43 -05:00
Text : "Authentication" ,
Id : "authentication" ,
SubTitle : "Manage your auth settings and configure single sign-on" ,
Icon : "signin" ,
Url : s . cfg . AppSubURL + "/admin/authentication" ,
} )
}
2023-04-20 11:37:50 -05:00
if hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionSettingsRead , ac . ScopeSettingsAll ) ) {
2023-04-20 05:10:12 -05:00
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" ,
} )
}
2022-09-28 01:29:35 -05:00
if hasGlobalAccess ( ac . ReqGrafanaAdmin , orgsAccessEvaluator ) {
2023-04-20 05:10:12 -05:00
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Organizations" , SubTitle : "Isolated instances of Grafana running on the same server" , Id : "global-orgs" , Url : s . cfg . AppSubURL + "/admin/orgs" , Icon : "building" ,
2022-09-28 01:29:35 -05:00
} )
}
2023-04-20 05:10:12 -05:00
if s . features . IsEnabled ( featuremgmt . FlagCorrelations ) && hasAccess ( ac . ReqOrgAdmin , correlations . ConfigurationPageAccess ) {
configNodes = append ( configNodes , & navtree . NavLink {
Text : "Correlations" ,
Icon : "gf-glue" ,
SubTitle : "Add and configure correlations" ,
Id : "correlations" ,
Url : s . cfg . AppSubURL + "/datasources/correlations" ,
} )
}
if s . cfg . LDAPAuthEnabled && hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionLDAPStatusRead ) ) {
configNodes = append ( configNodes , & navtree . NavLink {
Text : "LDAP" , Id : "ldap" , Url : s . cfg . AppSubURL + "/admin/ldap" , Icon : "book" ,
2022-09-28 01:29:35 -05:00
} )
}
if hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionSettingsRead ) ) && s . features . IsEnabled ( featuremgmt . FlagStorage ) {
2022-12-13 09:41:16 -06:00
storage := & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Storage" ,
Id : "storage" ,
SubTitle : "Manage file storage" ,
Icon : "cube" ,
Url : s . cfg . AppSubURL + "/admin/storage" ,
2022-12-13 09:41:16 -06:00
}
2023-04-20 05:10:12 -05:00
configNodes = append ( configNodes , storage )
2022-09-28 01:29:35 -05:00
}
2023-04-20 05:10:12 -05:00
configNode := & navtree . NavLink {
Id : navtree . NavIDCfg ,
Text : "Administration" ,
SubTitle : "Organization: " + c . OrgName ,
Icon : "cog" ,
SortWeight : navtree . WeightConfig ,
Children : configNodes ,
Url : "/admin" ,
2022-09-28 01:29:35 -05:00
}
2023-04-20 05:10:12 -05:00
return configNode , nil
2022-09-22 15:04:48 -05:00
}
2023-01-27 01:50:36 -06:00
func ( s * ServiceImpl ) ReqCanAdminTeams ( c * contextmodel . ReqContext ) bool {
2022-09-22 15:04:48 -05:00
return c . OrgRole == org . RoleAdmin || ( s . cfg . EditorsCanAdmin && c . OrgRole == org . RoleEditor )
}
2023-01-27 01:50:36 -06:00
func enableServiceAccount ( s * ServiceImpl , c * contextmodel . ReqContext ) bool {
2022-09-22 15:04:48 -05:00
hasAccess := ac . HasAccess ( s . accessControl , c )
return hasAccess ( ac . ReqOrgAdmin , serviceaccounts . AccessEvaluator )
}
2023-04-13 09:07:43 -05:00
func evalAuthenticationSettings ( ) ac . Evaluator {
return ac . EvalAll (
ac . EvalPermission ( ac . ActionSettingsWrite , ac . ScopeSettingsAuth ) ,
ac . EvalPermission ( ac . ActionSettingsWrite , ac . ScopeSettingsSAML ) ,
ac . EvalPermission ( ac . ActionSettingsRead , ac . ScopeSettingsAuth ) ,
ac . EvalPermission ( ac . ActionSettingsRead , ac . ScopeSettingsSAML ) ,
)
}