dashboard_acl.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package sqlstore
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/grafana/grafana/pkg/bus"
  6. m "github.com/grafana/grafana/pkg/models"
  7. )
  8. func init() {
  9. bus.AddHandler("sql", SetDashboardAcl)
  10. bus.AddHandler("sql", UpdateDashboardAcl)
  11. bus.AddHandler("sql", RemoveDashboardAcl)
  12. bus.AddHandler("sql", GetDashboardAclInfoList)
  13. }
  14. func UpdateDashboardAcl(cmd *m.UpdateDashboardAclCommand) error {
  15. return inTransaction(func(sess *DBSession) error {
  16. // delete existing items
  17. _, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", cmd.DashboardId)
  18. if err != nil {
  19. return err
  20. }
  21. for _, item := range cmd.Items {
  22. if item.UserId == 0 && item.UserGroupId == 0 && !item.Role.IsValid() {
  23. return m.ErrDashboardAclInfoMissing
  24. }
  25. if item.DashboardId == 0 {
  26. return m.ErrDashboardPermissionDashboardEmpty
  27. }
  28. sess.Nullable("user_id", "user_group_id")
  29. if _, err := sess.Insert(item); err != nil {
  30. return err
  31. }
  32. }
  33. // Update dashboard HasAcl flag
  34. dashboard := m.Dashboard{HasAcl: true}
  35. if _, err := sess.Cols("has_acl").Where("id=? OR folder_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil {
  36. return err
  37. }
  38. return nil
  39. })
  40. }
  41. func SetDashboardAcl(cmd *m.SetDashboardAclCommand) error {
  42. return inTransaction(func(sess *DBSession) error {
  43. if cmd.UserId == 0 && cmd.UserGroupId == 0 {
  44. return m.ErrDashboardAclInfoMissing
  45. }
  46. if cmd.DashboardId == 0 {
  47. return m.ErrDashboardPermissionDashboardEmpty
  48. }
  49. 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 {
  50. return err
  51. } else if len(res) == 1 {
  52. entity := m.DashboardAcl{
  53. Permission: cmd.Permission,
  54. Updated: time.Now(),
  55. }
  56. 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 {
  57. return err
  58. }
  59. return nil
  60. }
  61. entity := m.DashboardAcl{
  62. OrgId: cmd.OrgId,
  63. UserGroupId: cmd.UserGroupId,
  64. UserId: cmd.UserId,
  65. Created: time.Now(),
  66. Updated: time.Now(),
  67. DashboardId: cmd.DashboardId,
  68. Permission: cmd.Permission,
  69. }
  70. cols := []string{"org_id", "created", "updated", "dashboard_id", "permission"}
  71. if cmd.UserId != 0 {
  72. cols = append(cols, "user_id")
  73. }
  74. if cmd.UserGroupId != 0 {
  75. cols = append(cols, "user_group_id")
  76. }
  77. _, err := sess.Cols(cols...).Insert(&entity)
  78. if err != nil {
  79. return err
  80. }
  81. cmd.Result = entity
  82. // Update dashboard HasAcl flag
  83. dashboard := m.Dashboard{
  84. HasAcl: true,
  85. }
  86. if _, err := sess.Cols("has_acl").Where("id=? OR folder_id=?", cmd.DashboardId, cmd.DashboardId).Update(&dashboard); err != nil {
  87. return err
  88. }
  89. return nil
  90. })
  91. }
  92. func RemoveDashboardAcl(cmd *m.RemoveDashboardAclCommand) error {
  93. return inTransaction(func(sess *DBSession) error {
  94. var rawSQL = "DELETE FROM " + dialect.Quote("dashboard_acl") + " WHERE org_id =? and id=?"
  95. _, err := sess.Exec(rawSQL, cmd.OrgId, cmd.AclId)
  96. if err != nil {
  97. return err
  98. }
  99. return err
  100. })
  101. }
  102. func GetDashboardAclInfoList(query *m.GetDashboardAclInfoListQuery) error {
  103. dashboardFilter := fmt.Sprintf(`IN (
  104. SELECT %d
  105. UNION
  106. SELECT folder_id from dashboard where id = %d
  107. )`, query.DashboardId, query.DashboardId)
  108. rawSQL := `
  109. SELECT
  110. da.id,
  111. da.org_id,
  112. da.dashboard_id,
  113. da.user_id,
  114. da.user_group_id,
  115. da.permission,
  116. da.role,
  117. da.created,
  118. da.updated,
  119. u.login AS user_login,
  120. u.email AS user_email,
  121. ug.name AS user_group
  122. FROM` + dialect.Quote("dashboard_acl") + ` as da
  123. LEFT OUTER JOIN ` + dialect.Quote("user") + ` AS u ON u.id = da.user_id
  124. LEFT OUTER JOIN user_group ug on ug.id = da.user_group_id
  125. WHERE dashboard_id ` + dashboardFilter + ` AND da.org_id = ?
  126. -- Also include default permission if has_acl = 0
  127. UNION
  128. SELECT
  129. da.id,
  130. da.org_id,
  131. da.dashboard_id,
  132. da.user_id,
  133. da.user_group_id,
  134. da.permission,
  135. da.role,
  136. da.created,
  137. da.updated,
  138. '' as user_login,
  139. '' as user_email,
  140. '' as user_group
  141. FROM dashboard_acl as da,
  142. dashboard as dash
  143. LEFT JOIN dashboard folder on dash.folder_id = folder.id
  144. WHERE dash.id = ? AND (dash.has_acl = 0 or folder.has_acl = 0) AND da.dashboard_id = -1
  145. `
  146. query.Result = make([]*m.DashboardAclInfoDTO, 0)
  147. err := x.SQL(rawSQL, query.OrgId, query.DashboardId).Find(&query.Result)
  148. for _, p := range query.Result {
  149. p.PermissionName = p.Permission.String()
  150. }
  151. return err
  152. }