2017-06-16 20:25:24 -05:00
|
|
|
package guardian
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
2017-06-19 12:47:44 -05:00
|
|
|
"github.com/grafana/grafana/pkg/log"
|
2017-06-16 20:25:24 -05:00
|
|
|
m "github.com/grafana/grafana/pkg/models"
|
2017-12-15 07:19:49 -06:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2017-06-16 20:25:24 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type DashboardGuardian struct {
|
2017-06-19 10:54:37 -05:00
|
|
|
user *m.SignedInUser
|
|
|
|
dashId int64
|
|
|
|
orgId int64
|
2017-06-22 16:10:43 -05:00
|
|
|
acl []*m.DashboardAclInfoDTO
|
2017-12-08 09:25:45 -06:00
|
|
|
groups []*m.Team
|
2017-06-19 12:47:44 -05:00
|
|
|
log log.Logger
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
2017-06-19 10:54:37 -05:00
|
|
|
func NewDashboardGuardian(dashId int64, orgId int64, user *m.SignedInUser) *DashboardGuardian {
|
2017-06-16 20:25:24 -05:00
|
|
|
return &DashboardGuardian{
|
2017-06-19 10:54:37 -05:00
|
|
|
user: user,
|
|
|
|
dashId: dashId,
|
|
|
|
orgId: orgId,
|
2017-06-19 12:47:44 -05:00
|
|
|
log: log.New("guardians.dashboard"),
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *DashboardGuardian) CanSave() (bool, error) {
|
2017-06-21 18:23:24 -05:00
|
|
|
return g.HasPermission(m.PERMISSION_EDIT)
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *DashboardGuardian) CanEdit() (bool, error) {
|
2017-12-15 07:19:49 -06:00
|
|
|
if setting.ViewersCanEdit {
|
|
|
|
return g.HasPermission(m.PERMISSION_VIEW)
|
|
|
|
}
|
|
|
|
|
2017-06-21 18:23:24 -05:00
|
|
|
return g.HasPermission(m.PERMISSION_EDIT)
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *DashboardGuardian) CanView() (bool, error) {
|
2017-06-21 18:23:24 -05:00
|
|
|
return g.HasPermission(m.PERMISSION_VIEW)
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
2017-06-22 16:01:04 -05:00
|
|
|
func (g *DashboardGuardian) CanAdmin() (bool, error) {
|
|
|
|
return g.HasPermission(m.PERMISSION_ADMIN)
|
|
|
|
}
|
|
|
|
|
2017-06-21 18:23:24 -05:00
|
|
|
func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, error) {
|
2017-06-19 12:47:44 -05:00
|
|
|
if g.user.OrgRole == m.ROLE_ADMIN {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 16:10:43 -05:00
|
|
|
acl, err := g.GetAcl()
|
2017-06-16 20:25:24 -05:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2018-01-18 07:30:04 -06:00
|
|
|
return g.checkAcl(permission, acl)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *DashboardGuardian) checkAcl(permission m.PermissionType, acl []*m.DashboardAclInfoDTO) (bool, error) {
|
2017-06-22 16:43:55 -05:00
|
|
|
orgRole := g.user.OrgRole
|
2017-12-08 09:25:45 -06:00
|
|
|
teamAclItems := []*m.DashboardAclInfoDTO{}
|
2017-06-22 16:43:55 -05:00
|
|
|
|
2017-06-16 20:25:24 -05:00
|
|
|
for _, p := range acl {
|
2017-06-22 16:43:55 -05:00
|
|
|
// user match
|
2017-12-15 07:19:49 -06:00
|
|
|
if !g.user.IsAnonymous {
|
|
|
|
if p.UserId == g.user.UserId && p.Permission >= permission {
|
|
|
|
return true, nil
|
|
|
|
}
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
2017-06-22 16:43:55 -05:00
|
|
|
// role match
|
|
|
|
if p.Role != nil {
|
|
|
|
if *p.Role == orgRole && p.Permission >= permission {
|
2017-06-16 20:25:24 -05:00
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
}
|
2017-06-21 18:23:24 -05:00
|
|
|
|
2017-06-22 16:43:55 -05:00
|
|
|
// remember this rule for later
|
2017-12-08 09:25:45 -06:00
|
|
|
if p.TeamId > 0 {
|
|
|
|
teamAclItems = append(teamAclItems, p)
|
2017-06-22 16:43:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-29 06:56:12 -06:00
|
|
|
// do we have team rules?
|
2017-12-08 09:25:45 -06:00
|
|
|
if len(teamAclItems) == 0 {
|
2017-06-22 16:43:55 -05:00
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
2018-01-29 06:56:12 -06:00
|
|
|
// load teams
|
2017-12-08 09:25:45 -06:00
|
|
|
teams, err := g.getTeams()
|
2017-06-22 16:43:55 -05:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
2018-01-29 06:56:12 -06:00
|
|
|
// evalute team rules
|
2017-06-22 16:43:55 -05:00
|
|
|
for _, p := range acl {
|
2017-12-08 09:25:45 -06:00
|
|
|
for _, ug := range teams {
|
|
|
|
if ug.Id == p.TeamId && p.Permission >= permission {
|
2017-06-21 18:23:24 -05:00
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
}
|
2017-06-16 20:25:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
2018-01-18 07:30:04 -06:00
|
|
|
func (g *DashboardGuardian) CheckPermissionBeforeRemove(permission m.PermissionType, aclIdToRemove int64) (bool, error) {
|
|
|
|
if g.user.OrgRole == m.ROLE_ADMIN {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
acl, err := g.GetAcl()
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, p := range acl {
|
|
|
|
if p.Id == aclIdToRemove {
|
|
|
|
acl = append(acl[:i], acl[i+1:]...)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return g.checkAcl(permission, acl)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *DashboardGuardian) CheckPermissionBeforeUpdate(permission m.PermissionType, updatePermissions []*m.DashboardAcl) (bool, error) {
|
|
|
|
if g.user.OrgRole == m.ROLE_ADMIN {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
acl := []*m.DashboardAclInfoDTO{}
|
|
|
|
|
|
|
|
for _, p := range updatePermissions {
|
|
|
|
acl = append(acl, &m.DashboardAclInfoDTO{UserId: p.UserId, TeamId: p.TeamId, Role: p.Role, Permission: p.Permission})
|
|
|
|
}
|
|
|
|
|
|
|
|
return g.checkAcl(permission, acl)
|
|
|
|
}
|
|
|
|
|
2018-01-29 06:56:12 -06:00
|
|
|
// GetAcl returns dashboard acl
|
2017-06-22 16:10:43 -05:00
|
|
|
func (g *DashboardGuardian) GetAcl() ([]*m.DashboardAclInfoDTO, error) {
|
2017-06-16 20:25:24 -05:00
|
|
|
if g.acl != nil {
|
|
|
|
return g.acl, nil
|
|
|
|
}
|
|
|
|
|
2017-06-22 16:10:43 -05:00
|
|
|
query := m.GetDashboardAclInfoListQuery{DashboardId: g.dashId, OrgId: g.orgId}
|
2017-06-16 20:25:24 -05:00
|
|
|
if err := bus.Dispatch(&query); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
g.acl = query.Result
|
|
|
|
return g.acl, nil
|
|
|
|
}
|
|
|
|
|
2017-12-08 09:25:45 -06:00
|
|
|
func (g *DashboardGuardian) getTeams() ([]*m.Team, error) {
|
2017-06-19 14:22:42 -05:00
|
|
|
if g.groups != nil {
|
2017-06-16 20:25:24 -05:00
|
|
|
return g.groups, nil
|
|
|
|
}
|
|
|
|
|
2018-02-09 10:26:15 -06:00
|
|
|
query := m.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId}
|
2017-06-16 20:25:24 -05:00
|
|
|
err := bus.Dispatch(&query)
|
|
|
|
|
|
|
|
g.groups = query.Result
|
|
|
|
return query.Result, err
|
|
|
|
}
|