mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Access control: Build navigation links with access control (#33024)
* Build nav links with access control * Break up getNavTree (reduce cyclomatic complexity) * Fix tests * Use only ActionUsersRead permissions * Remove unused permissions definitions * Chore: remove unused fallbacks * Fix linter error
This commit is contained in:
parent
381e4a51cd
commit
41f6af96c4
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -299,20 +299,9 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.IsGrafanaAdmin {
|
adminNavLinks := hs.buildAdminNavLinks(c)
|
||||||
adminNavLinks := []*dtos.NavLink{
|
|
||||||
{Text: "Users", Id: "global-users", Url: hs.Cfg.AppSubURL + "/admin/users", Icon: "user"},
|
|
||||||
{Text: "Orgs", Id: "global-orgs", Url: hs.Cfg.AppSubURL + "/admin/orgs", Icon: "building"},
|
|
||||||
{Text: "Settings", Id: "server-settings", Url: hs.Cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt"},
|
|
||||||
{Text: "Stats", Id: "server-stats", Url: hs.Cfg.AppSubURL + "/admin/stats", Icon: "graph-bar"},
|
|
||||||
}
|
|
||||||
|
|
||||||
if hs.Cfg.LDAPEnabled {
|
|
||||||
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
|
||||||
Text: "LDAP", Id: "ldap", Url: hs.Cfg.AppSubURL + "/admin/ldap", Icon: "book",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if len(adminNavLinks) > 0 {
|
||||||
navTree = append(navTree, &dtos.NavLink{
|
navTree = append(navTree, &dtos.NavLink{
|
||||||
Text: "Server Admin",
|
Text: "Server Admin",
|
||||||
SubTitle: "Manage all users and orgs",
|
SubTitle: "Manage all users and orgs",
|
||||||
@ -344,6 +333,36 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
|||||||
return navTree, nil
|
return navTree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hs *HTTPServer) buildAdminNavLinks(c *models.ReqContext) []*dtos.NavLink {
|
||||||
|
hasAccess := ac.HasAccess(hs.AccessControl, c)
|
||||||
|
adminNavLinks := []*dtos.NavLink{}
|
||||||
|
|
||||||
|
if hasAccess(ac.ReqGrafanaAdmin, ac.ActionUsersRead, ac.ScopeUsersAll) {
|
||||||
|
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
||||||
|
Text: "Users", Id: "global-users", Url: hs.Cfg.AppSubURL + "/admin/users", Icon: "user",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsGrafanaAdmin {
|
||||||
|
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
||||||
|
Text: "Orgs", Id: "global-orgs", Url: hs.Cfg.AppSubURL + "/admin/orgs", Icon: "building",
|
||||||
|
})
|
||||||
|
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
||||||
|
Text: "Settings", Id: "server-settings", Url: hs.Cfg.AppSubURL + "/admin/settings", Icon: "sliders-v-alt",
|
||||||
|
})
|
||||||
|
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
||||||
|
Text: "Stats", Id: "server-stats", Url: hs.Cfg.AppSubURL + "/admin/stats", Icon: "graph-bar",
|
||||||
|
})
|
||||||
|
if hs.Cfg.LDAPEnabled {
|
||||||
|
adminNavLinks = append(adminNavLinks, &dtos.NavLink{
|
||||||
|
Text: "LDAP", Id: "ldap", Url: hs.Cfg.AppSubURL + "/admin/ldap", Icon: "book",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adminNavLinks
|
||||||
|
}
|
||||||
|
|
||||||
func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewData, error) {
|
func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewData, error) {
|
||||||
hasEditPermissionInFoldersQuery := models.HasEditPermissionInFoldersQuery{SignedInUser: c.SignedInUser}
|
hasEditPermissionInFoldersQuery := models.HasEditPermissionInFoldersQuery{SignedInUser: c.SignedInUser}
|
||||||
if err := bus.Dispatch(&hasEditPermissionInFoldersQuery); err != nil {
|
if err := bus.Dispatch(&hasEditPermissionInFoldersQuery); err != nil {
|
||||||
@ -434,7 +453,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data.User.Permissions = accesscontrol.BuildPermissionsMap(userPermissions)
|
data.User.Permissions = ac.BuildPermissionsMap(userPermissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.DisableGravatar {
|
if setting.DisableGravatar {
|
||||||
|
@ -17,6 +17,26 @@ type AccessControl interface {
|
|||||||
IsDisabled() bool
|
IsDisabled() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasAccess(ac AccessControl, c *models.ReqContext) func(fallback func(*models.ReqContext) bool, permission string, scopes ...string) bool {
|
||||||
|
return func(fallback func(*models.ReqContext) bool, permission string, scopes ...string) bool {
|
||||||
|
if ac.IsDisabled() {
|
||||||
|
return fallback(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
hasAccess, err := ac.Evaluate(c.Req.Context(), c.SignedInUser, permission, scopes...)
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Error("Error from access control system", "error", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasAccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ReqGrafanaAdmin = func(c *models.ReqContext) bool {
|
||||||
|
return c.IsGrafanaAdmin
|
||||||
|
}
|
||||||
|
|
||||||
func BuildPermissionsMap(permissions []*Permission) map[string]map[string]string {
|
func BuildPermissionsMap(permissions []*Permission) map[string]map[string]string {
|
||||||
permissionsMap := make(map[string]map[string]string)
|
permissionsMap := make(map[string]map[string]string)
|
||||||
for _, p := range permissions {
|
for _, p := range permissions {
|
||||||
|
Loading…
Reference in New Issue
Block a user