2022-09-22 15:04:48 -05:00
package navtreeimpl
import (
"github.com/grafana/grafana/pkg/plugins"
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"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
)
2023-01-27 01:50:36 -06:00
func ( s * ServiceImpl ) getOrgAdminNode ( c * contextmodel . ReqContext ) ( * navtree . NavLink , error ) {
2022-09-22 15:04:48 -05:00
var configNodes [ ] * navtree . NavLink
hasAccess := ac . HasAccess ( s . accessControl , c )
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
} )
}
if s . features . IsEnabled ( featuremgmt . FlagCorrelations ) && hasAccess ( ac . ReqOrgAdmin , correlations . ConfigurationPageAccess ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Correlations" ,
Icon : "gf-glue" ,
SubTitle : "Add and configure correlations" ,
Id : "correlations" ,
Url : s . cfg . AppSubURL + "/datasources/correlations" ,
2022-09-22 15:04:48 -05:00
} )
}
2022-11-30 07:24:53 -06:00
if ! s . features . IsEnabled ( featuremgmt . FlagTopnav ) {
if hasAccess ( ac . ReqOrgAdmin , ac . EvalPermission ( ac . ActionOrgUsersRead ) ) {
configNodes = append ( configNodes , & navtree . NavLink {
Text : "Users" ,
Id : "users" ,
SubTitle : "Invite and assign roles to users" ,
Icon : "user" ,
Url : s . cfg . AppSubURL + "/org/users" ,
} )
}
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
} )
}
// FIXME: while we don't have a permissions for listing plugins the legacy check has to stay as a default
if plugins . ReqCanAdminPlugins ( s . cfg ) ( c ) || hasAccess ( plugins . ReqCanAdminPlugins ( s . cfg ) , plugins . AdminAccessEvaluator ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Plugins" ,
Id : "plugins" ,
SubTitle : "Extend the Grafana experience with plugins" ,
Icon : "plug" ,
Url : s . cfg . AppSubURL + "/plugins" ,
2022-09-22 15:04:48 -05:00
} )
}
if hasAccess ( ac . ReqOrgAdmin , ac . OrgPreferencesAccessEvaluator ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Preferences" ,
Id : "org-settings" ,
SubTitle : "Manage preferences across an organization" ,
Icon : "sliders-v-alt" ,
Url : s . cfg . AppSubURL + "/org" ,
2022-09-22 15:04:48 -05:00
} )
}
hideApiKeys , _ , _ := s . kvStore . Get ( c . Req . Context ( ) , c . OrgID , "serviceaccounts" , "hideApiKeys" )
2023-03-01 09:34:53 -06:00
apiKeys , err := s . apiKeyService . CountAPIKeys ( c . Req . Context ( ) , c . OrgID )
2022-09-22 15:04:48 -05:00
if err != nil {
return nil , err
}
2023-03-01 09:34:53 -06:00
// Hide API keys if the global setting is set or if the org setting is set and there are no API keys
apiKeysHidden := hideApiKeys == "1" && apiKeys == 0
2022-09-22 15:04:48 -05:00
if hasAccess ( ac . ReqOrgAdmin , ac . ApiKeyAccessEvaluator ) && ! apiKeysHidden {
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
} )
}
if enableServiceAccount ( s , c ) {
configNodes = append ( configNodes , & navtree . NavLink {
2022-10-03 04:09:32 -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
} )
}
2022-09-28 01:29:35 -05:00
configNode := & navtree . NavLink {
Id : navtree . NavIDCfg ,
Text : "Configuration" ,
SubTitle : "Organization: " + c . OrgName ,
Icon : "cog" ,
Section : navtree . NavSectionConfig ,
SortWeight : navtree . WeightConfig ,
Children : configNodes ,
}
return configNode , nil
}
2023-01-27 01:50:36 -06:00
func ( s * ServiceImpl ) getServerAdminNode ( c * contextmodel . ReqContext ) * navtree . NavLink {
2022-09-28 01:29:35 -05:00
hasAccess := ac . HasAccess ( s . accessControl , c )
hasGlobalAccess := ac . HasGlobalAccess ( s . accessControl , s . accesscontrolService , c )
orgsAccessEvaluator := ac . EvalPermission ( ac . ActionOrgsRead )
adminNavLinks := [ ] * navtree . NavLink { }
2022-11-30 07:24:53 -06:00
if s . features . IsEnabled ( featuremgmt . FlagTopnav ) {
if hasAccess ( ac . ReqSignedIn , ac . EvalAny ( ac . EvalPermission ( ac . ActionOrgUsersRead ) , ac . EvalPermission ( ac . ActionUsersRead , ac . ScopeGlobalUsersAll ) ) ) {
adminNavLinks = append ( adminNavLinks , & navtree . NavLink {
Text : "Users" , SubTitle : "Manage users in Grafana" , Id : "global-users" , Url : s . cfg . AppSubURL + "/admin/users" , Icon : "user" ,
} )
}
} else {
if hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionUsersRead , ac . ScopeGlobalUsersAll ) ) {
adminNavLinks = append ( adminNavLinks , & navtree . NavLink {
Text : "Users" , SubTitle : "Manage and create users across the whole Grafana server" , Id : "global-users" , Url : s . cfg . AppSubURL + "/admin/users" , Icon : "user" ,
} )
}
2022-09-28 01:29:35 -05:00
}
if hasGlobalAccess ( ac . ReqGrafanaAdmin , orgsAccessEvaluator ) {
adminNavLinks = append ( adminNavLinks , & 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
} )
}
if hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionSettingsRead ) ) {
adminNavLinks = append ( adminNavLinks , & navtree . NavLink {
2022-10-03 04:09:32 -05:00
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 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
}
adminNavLinks = append ( adminNavLinks , storage )
2022-09-28 01:29:35 -05:00
}
if s . cfg . LDAPEnabled && hasAccess ( ac . ReqGrafanaAdmin , ac . EvalPermission ( ac . ActionLDAPStatusRead ) ) {
adminNavLinks = append ( adminNavLinks , & navtree . NavLink {
Text : "LDAP" , Id : "ldap" , Url : s . cfg . AppSubURL + "/admin/ldap" , Icon : "book" ,
} )
}
adminNode := & navtree . NavLink {
2022-10-03 04:09:32 -05:00
Text : "Server admin" ,
Id : navtree . NavIDAdmin ,
Icon : "shield" ,
SortWeight : navtree . WeightAdmin ,
Section : navtree . NavSectionConfig ,
Children : adminNavLinks ,
}
2022-09-28 01:29:35 -05:00
if len ( adminNavLinks ) > 0 {
2022-11-18 09:11:59 -06:00
adminNode . Url = adminNavLinks [ 0 ] . Url
2022-09-28 01:29:35 -05:00
}
return adminNode
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 )
}