The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/guardian/guardian.go

99 lines
2.1 KiB

package guardian
import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
)
type DashboardGuardian struct {
user *m.SignedInUser
dashId int64
orgId int64
acl []*m.DashboardAcl
groups []*m.UserGroup
log log.Logger
}
func NewDashboardGuardian(dashId int64, orgId int64, user *m.SignedInUser) *DashboardGuardian {
return &DashboardGuardian{
user: user,
dashId: dashId,
orgId: orgId,
log: log.New("guardians.dashboard"),
}
}
func (g *DashboardGuardian) CanSave() (bool, error) {
return g.HasPermission(m.PERMISSION_EDIT, m.ROLE_EDITOR)
}
func (g *DashboardGuardian) CanEdit() (bool, error) {
return g.HasPermission(m.PERMISSION_READ_ONLY_EDIT, m.ROLE_READ_ONLY_EDITOR)
}
func (g *DashboardGuardian) CanView() (bool, error) {
return g.HasPermission(m.PERMISSION_VIEW, m.ROLE_VIEWER)
}
func (g *DashboardGuardian) HasPermission(permission m.PermissionType, fallbackRole m.RoleType) (bool, error) {
if g.user.OrgRole == m.ROLE_ADMIN {
return true, nil
}
acl, err := g.getAcl()
if err != nil {
return false, err
}
// if no acl use org role to determine permission
if len(acl) == 0 {
return g.user.HasRole(fallbackRole), nil
}
userGroups, err := g.getUserGroups()
if err != nil {
return false, err
}
for _, p := range acl {
if p.UserId == g.user.UserId && p.Permissions >= permission {
return true, nil
}
for _, ug := range userGroups {
if ug.Id == p.UserGroupId && p.Permissions >= permission {
return true, nil
}
}
}
return false, nil
}
// Returns dashboard acl
func (g *DashboardGuardian) getAcl() ([]*m.DashboardAcl, error) {
if g.acl != nil {
return g.acl, nil
}
query := m.GetInheritedDashboardAclQuery{DashboardId: g.dashId, OrgId: g.orgId}
if err := bus.Dispatch(&query); err != nil {
return nil, err
}
g.acl = query.Result
return g.acl, nil
}
func (g *DashboardGuardian) getUserGroups() ([]*m.UserGroup, error) {
if g.groups == nil {
return g.groups, nil
}
query := m.GetUserGroupsByUserQuery{UserId: g.user.UserId}
err := bus.Dispatch(&query)
g.groups = query.Result
return query.Result, err
}