mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactoring: Dashboard guardian
This commit is contained in:
parent
d9dca72ee4
commit
3fe031d25d
pkg
api
models
services
@ -46,13 +46,11 @@ func GetDashboard(c *middleware.Context) Response {
|
||||
}
|
||||
|
||||
dash := query.Result
|
||||
guardian := guardian.NewDashboardGuardian(dash, c.SignedInUser)
|
||||
|
||||
canView, canEdit, canSave, err := getPermissions(dash, c.OrgRole, c.IsGrafanaAdmin, c.UserId)
|
||||
if err != nil {
|
||||
if canView, err := guardian.CanView(); err != nil {
|
||||
return ApiError(500, "Error while checking dashboard permissions", err)
|
||||
}
|
||||
|
||||
if !canView {
|
||||
} else if !canView {
|
||||
return ApiError(403, "Access denied to this dashboard", nil)
|
||||
}
|
||||
|
||||
@ -162,12 +160,11 @@ func DeleteDashboard(c *middleware.Context) Response {
|
||||
return ApiError(404, "Dashboard not found", err)
|
||||
}
|
||||
|
||||
_, _, canSave, err := getPermissions(query.Result, c.OrgRole, c.IsGrafanaAdmin, c.UserId)
|
||||
if err != nil {
|
||||
return ApiError(500, "Error while checking dashboard permissions", err)
|
||||
}
|
||||
guardian := guardian.NewDashboardGuardian(query.Result, c.SignedInUser)
|
||||
|
||||
if !canSave {
|
||||
if canSave, err := guardian.CanSave(); err != nil {
|
||||
return ApiError(500, "Error while checking dashboard permissions", err)
|
||||
} else if !canSave {
|
||||
return ApiError(403, "Does not have permission to delete this dashboard", nil)
|
||||
}
|
||||
|
||||
@ -301,6 +298,8 @@ func GetHomeDashboard(c *middleware.Context) Response {
|
||||
dash := dtos.DashboardFullWithMeta{}
|
||||
dash.Meta.IsHome = true
|
||||
dash.Meta.CanEdit = canEditDashboard(c.OrgRole)
|
||||
dash.Meta.FolderTitle = "Root"
|
||||
|
||||
jsonParser := json.NewDecoder(file)
|
||||
if err := jsonParser.Decode(&dash.Dashboard); err != nil {
|
||||
return ApiError(500, "Failed to load home dashboard", err)
|
||||
|
@ -54,8 +54,8 @@ type DashboardAclInfoDTO struct {
|
||||
UserEmail string `json:"userEmail"`
|
||||
UserGroupId int64 `json:"userGroupId"`
|
||||
UserGroup string `json:"userGroup"`
|
||||
PermissionType PermissionType `json:"permissionType"`
|
||||
Permissions string `json:"permissions"`
|
||||
Permissions PermissionType `json:"permissions"`
|
||||
PermissionName string `json:"permissionName"`
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -162,6 +162,14 @@ type SignedInUser struct {
|
||||
HelpFlags1 HelpFlags1
|
||||
}
|
||||
|
||||
func (user *SignedInUser) HasRole(role RoleType) bool {
|
||||
if user.IsGrafanaAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
return user.OrgRole.Includes(role)
|
||||
}
|
||||
|
||||
type UserProfileDTO struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
|
@ -17,7 +17,6 @@ func FilterRestrictedDashboards(dashList []int64, orgId int64, userId int64) ([]
|
||||
}
|
||||
|
||||
filteredList, err := getAllowedDashboards(dashList, orgId, userId)
|
||||
|
||||
return filteredList, err
|
||||
}
|
||||
|
||||
@ -101,12 +100,12 @@ func checkPermission(minimumPermission m.PermissionType, permissions []*m.Dashbo
|
||||
}
|
||||
|
||||
for _, p := range permissions {
|
||||
if p.UserId == userId && p.PermissionType >= minimumPermission {
|
||||
if p.UserId == userId && p.Permissions >= minimumPermission {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
for _, ug := range userGroups {
|
||||
if ug.Id == p.UserGroupId && p.PermissionType >= minimumPermission {
|
||||
if ug.Id == p.UserGroupId && p.Permissions >= minimumPermission {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
96
pkg/services/guardian/models.go
Normal file
96
pkg/services/guardian/models.go
Normal file
@ -0,0 +1,96 @@
|
||||
package guardian
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
type DashboardGuardian struct {
|
||||
user *m.SignedInUser
|
||||
dashboard *m.Dashboard
|
||||
acl []*m.DashboardAclInfoDTO
|
||||
groups []*m.UserGroup
|
||||
}
|
||||
|
||||
func NewDashboardGuardian(dash *m.Dashboard, user *m.SignedInUser) *DashboardGuardian {
|
||||
return &DashboardGuardian{
|
||||
user: user,
|
||||
dashboard: dash,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *DashboardGuardian) CanSave() (bool, error) {
|
||||
if !g.dashboard.HasAcl {
|
||||
return g.user.HasRole(m.ROLE_EDITOR), nil
|
||||
}
|
||||
|
||||
return g.HasPermission(m.PERMISSION_EDIT)
|
||||
}
|
||||
|
||||
func (g *DashboardGuardian) CanEdit() (bool, error) {
|
||||
if !g.dashboard.HasAcl {
|
||||
return g.user.HasRole(m.ROLE_READ_ONLY_EDITOR), nil
|
||||
}
|
||||
|
||||
return g.HasPermission(m.PERMISSION_READ_ONLY_EDIT)
|
||||
}
|
||||
|
||||
func (g *DashboardGuardian) CanView() (bool, error) {
|
||||
if !g.dashboard.HasAcl {
|
||||
return g.user.HasRole(m.ROLE_VIEWER), nil
|
||||
}
|
||||
|
||||
return g.HasPermission(m.PERMISSION_VIEW)
|
||||
}
|
||||
|
||||
func (g *DashboardGuardian) HasPermission(permission m.PermissionType) (bool, error) {
|
||||
userGroups, err := g.getUserGroups()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
acl, err := g.getAcl()
|
||||
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
|
||||
}
|
||||
|
||||
func (g *DashboardGuardian) getAcl() ([]*m.DashboardAclInfoDTO, error) {
|
||||
if g.acl != nil {
|
||||
return g.acl, nil
|
||||
}
|
||||
|
||||
query := m.GetDashboardPermissionsQuery{DashboardId: g.dashboard.Id}
|
||||
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
|
||||
}
|
@ -3,8 +3,6 @@ package sqlstore
|
||||
import (
|
||||
"time"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
@ -94,7 +92,7 @@ func GetDashboardPermissions(query *m.GetDashboardPermissionsQuery) error {
|
||||
da.dashboard_id,
|
||||
da.user_id,
|
||||
da.user_group_id,
|
||||
da.permissions as permission_type,
|
||||
da.permissions,
|
||||
da.created,
|
||||
da.updated,
|
||||
u.login AS user_login,
|
||||
@ -110,7 +108,7 @@ func GetDashboardPermissions(query *m.GetDashboardPermissionsQuery) error {
|
||||
err := x.SQL(rawSQL, query.DashboardId).Find(&query.Result)
|
||||
|
||||
for _, p := range query.Result {
|
||||
p.Permissions = fmt.Sprint(p.PermissionType)
|
||||
p.PermissionName = p.Permissions.String()
|
||||
}
|
||||
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user