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/sqlstore/dashboard_acl.go

200 lines
4.8 KiB

package sqlstore
import (
"time"
"github.com/grafana/grafana/pkg/bus"
m "github.com/grafana/grafana/pkg/models"
)
func init() {
bus.AddHandler("sql", SetDashboardAcl)
bus.AddHandler("sql", UpdateDashboardAcl)
bus.AddHandler("sql", RemoveDashboardAcl)
bus.AddHandler("sql", GetDashboardAclInfoList)
bus.AddHandler("sql", GetInheritedDashboardAcl)
}
func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
return inTransaction(func(sess *DBSession) error {
// delete existing items
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", cmd.DashboardId)
if err != nil {
return err
}
for _, item := range cmd.Items {
if item.UserId == 0 && item.UserGroupId == 0 && !item.Role.IsValid() {
return m.ErrDashboardAclInfoMissing
}
if item.DashboardId == 0 {
return m.ErrDashboardPermissionDashboardEmpty
}
sess.Nullable("user_id", "user_group_id")
if _, err := sess.Insert(item); err != nil {
return err
}
}
// Update dashboard HasAcl flag
dashboard := m.Dashboard{HasAcl: true}
if _, err := sess.Cols("has_acl").Where("id=? OR parent_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil {
return err
}
return nil
})
}
func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
return inTransaction(func(sess *DBSession) error {
if cmd.UserId == 0 && cmd.UserGroupId == 0 {
return m.ErrDashboardAclInfoMissing
}
if cmd.DashboardId == 0 {
return m.ErrDashboardPermissionDashboardEmpty
}
if res, err := sess.Query("SELECT 1 from "+dialect.Quote("dashboard_acl")+" WHERE dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId); err != nil {
return err
} else if len(res) == 1 {
entity := m.DashboardAcl{
Permission: cmd.Permission,
Updated: time.Now(),
}
if _, err := sess.Cols("updated", "permission").Where("dashboard_id =? and (user_group_id=? or user_id=?)", cmd.DashboardId, cmd.UserGroupId, cmd.UserId).Update(&entity); err != nil {
return err
}
return nil
}
entity := m.DashboardAcl{
OrgId: cmd.OrgId,
UserGroupId: cmd.UserGroupId,
UserId: cmd.UserId,
Created: time.Now(),
Updated: time.Now(),
DashboardId: cmd.DashboardId,
Permission: cmd.Permission,
}
cols := []string{"org_id", "created", "updated", "dashboard_id", "permission"}
if cmd.UserId != 0 {
cols = append(cols, "user_id")
}
if cmd.UserGroupId != 0 {
cols = append(cols, "user_group_id")
}
_, err := sess.Cols(cols...).Insert(&entity)
if err != nil {
return err
}
cmd.Result = entity
// Update dashboard HasAcl flag
dashboard := m.Dashboard{
HasAcl: true,
}
if _, err := sess.Cols("has_acl").Where("id=? OR parent_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil {
return err
}
return nil
})
}
func RemoveDashboardAcl(cmd *m.RemoveDashboardAclCommand) error {
return inTransaction(func(sess *DBSession) error {
var rawSQL = "DELETE FROM " + dialect.Quote("dashboard_acl") + " WHERE org_id =? and id=?"
_, err := sess.Exec(rawSQL, cmd.OrgId, cmd.AclId)
if err != nil {
return err
}
return err
})
}
func GetInheritedDashboardAcl(query *m.GetInheritedDashboardAclQuery) error {
rawSQL := `SELECT
da.id,
da.org_id,
da.dashboard_id,
da.user_id,
da.user_group_id,
da.role,
da.permission,
da.created,
da.updated
FROM dashboard_acl as da
WHERE da.dashboard_id IN (
SELECT id FROM dashboard where id = ?
UNION
SELECT parent_id from dashboard where id = ?
) AND org_id = ?`
query.Result = make([]*m.DashboardAcl, 0)
return x.SQL(rawSQL, query.DashboardId, query.DashboardId, query.OrgId).Find(&query.Result)
}
func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
rawSQL := `
SELECT
da.id,
da.org_id,
da.dashboard_id,
da.user_id,
da.user_group_id,
da.permission,
da.role,
da.created,
da.updated,
u.login AS user_login,
u.email AS user_email,
ug.name AS user_group
FROM` + dialect.Quote("dashboard_acl") + ` as da
LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id
LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
WHERE dashboard_id = ?
-- Also include default permission if has_acl = 0
UNION
SELECT
da.id,
da.org_id,
da.dashboard_id,
da.user_id,
da.user_group_id,
da.permission,
da.role,
da.created,
da.updated,
'' as user_login,
'' as user_email,
'' as user_group
FROM dashboard_acl as da, dashboard as dash
WHERE dash.id = ? AND dash.has_acl = 0 AND da.dashboard_id = -1
`
query.Result = make([]*m.DashboardAclInfoDTO, 0)
err := x.SQL(rawSQL, query.DashboardId, query.DashboardId).Find(&query.Result)
for _, p := range query.Result {
p.PermissionName = p.Permission.String()
}
return err
}