folder.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package api
  2. import (
  3. "fmt"
  4. "github.com/grafana/grafana/pkg/api/dtos"
  5. "github.com/grafana/grafana/pkg/bus"
  6. "github.com/grafana/grafana/pkg/middleware"
  7. m "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/services/dashboards"
  9. "github.com/grafana/grafana/pkg/services/guardian"
  10. "github.com/grafana/grafana/pkg/util"
  11. )
  12. func getFolderHelper(orgId int64, id int64, uid string) (*m.Dashboard, Response) {
  13. query := m.GetDashboardQuery{OrgId: orgId, Id: id, Uid: uid}
  14. if err := bus.Dispatch(&query); err != nil {
  15. if err == m.ErrDashboardNotFound {
  16. err = m.ErrFolderNotFound
  17. }
  18. return nil, ApiError(404, "Folder not found", err)
  19. }
  20. if !query.Result.IsFolder {
  21. return nil, ApiError(404, "Folder not found", m.ErrFolderNotFound)
  22. }
  23. return query.Result, nil
  24. }
  25. func folderGuardianResponse(err error) Response {
  26. if err != nil {
  27. return ApiError(500, "Error while checking folder permissions", err)
  28. }
  29. return ApiError(403, "Access denied to this folder", nil)
  30. }
  31. func GetFoldersForSignedInUser(c *middleware.Context) Response {
  32. title := c.Query("query")
  33. query := m.GetFoldersForSignedInUserQuery{
  34. OrgId: c.OrgId,
  35. SignedInUser: c.SignedInUser,
  36. Title: title,
  37. }
  38. err := bus.Dispatch(&query)
  39. if err != nil {
  40. return ApiError(500, "Failed to retrieve folders", err)
  41. }
  42. return Json(200, query.Result)
  43. }
  44. func GetFolder(c *middleware.Context) Response {
  45. folder, rsp := getFolderHelper(c.OrgId, c.ParamsInt64(":id"), c.Params(":uid"))
  46. if rsp != nil {
  47. return rsp
  48. }
  49. guardian := guardian.NewDashboardGuardian(folder.Id, c.OrgId, c.SignedInUser)
  50. if canView, err := guardian.CanView(); err != nil || !canView {
  51. fmt.Printf("%v", err)
  52. return folderGuardianResponse(err)
  53. }
  54. return Json(200, toDto(guardian, folder))
  55. }
  56. func CreateFolder(c *middleware.Context, cmd m.CreateFolderCommand) Response {
  57. cmd.OrgId = c.OrgId
  58. cmd.UserId = c.UserId
  59. dashFolder := cmd.GetDashboardModel()
  60. guardian := guardian.NewDashboardGuardian(0, c.OrgId, c.SignedInUser)
  61. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  62. return folderGuardianResponse(err)
  63. }
  64. if dashFolder.Title == "" {
  65. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  66. }
  67. limitReached, err := middleware.QuotaReached(c, "folder")
  68. if err != nil {
  69. return ApiError(500, "failed to get quota", err)
  70. }
  71. if limitReached {
  72. return ApiError(403, "Quota reached", nil)
  73. }
  74. dashItem := &dashboards.SaveDashboardItem{
  75. Dashboard: dashFolder,
  76. OrgId: c.OrgId,
  77. UserId: c.UserId,
  78. }
  79. folder, err := dashboards.GetRepository().SaveDashboard(dashItem)
  80. if err != nil {
  81. return toFolderError(err)
  82. }
  83. return Json(200, toDto(guardian, folder))
  84. }
  85. func UpdateFolder(c *middleware.Context, cmd m.UpdateFolderCommand) Response {
  86. cmd.OrgId = c.OrgId
  87. cmd.UserId = c.UserId
  88. uid := c.Params(":uid")
  89. dashFolder, rsp := getFolderHelper(c.OrgId, 0, uid)
  90. if rsp != nil {
  91. return rsp
  92. }
  93. guardian := guardian.NewDashboardGuardian(dashFolder.Id, c.OrgId, c.SignedInUser)
  94. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  95. return folderGuardianResponse(err)
  96. }
  97. cmd.UpdateDashboardModel(dashFolder)
  98. if dashFolder.Title == "" {
  99. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  100. }
  101. dashItem := &dashboards.SaveDashboardItem{
  102. Dashboard: dashFolder,
  103. OrgId: c.OrgId,
  104. UserId: c.UserId,
  105. }
  106. folder, err := dashboards.GetRepository().SaveDashboard(dashItem)
  107. if err != nil {
  108. return toFolderError(err)
  109. }
  110. return Json(200, toDto(guardian, folder))
  111. }
  112. func DeleteFolder(c *middleware.Context) Response {
  113. dashFolder, rsp := getFolderHelper(c.OrgId, 0, c.Params(":uid"))
  114. if rsp != nil {
  115. return rsp
  116. }
  117. guardian := guardian.NewDashboardGuardian(dashFolder.Id, c.OrgId, c.SignedInUser)
  118. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  119. return folderGuardianResponse(err)
  120. }
  121. deleteCmd := m.DeleteDashboardCommand{OrgId: c.OrgId, Id: dashFolder.Id}
  122. if err := bus.Dispatch(&deleteCmd); err != nil {
  123. return ApiError(500, "Failed to delete folder", err)
  124. }
  125. var resp = map[string]interface{}{"title": dashFolder.Title}
  126. return Json(200, resp)
  127. }
  128. func toDto(guardian *guardian.DashboardGuardian, folder *m.Dashboard) dtos.Folder {
  129. canEdit, _ := guardian.CanEdit()
  130. canSave, _ := guardian.CanSave()
  131. canAdmin, _ := guardian.CanAdmin()
  132. // Finding creator and last updater of the folder
  133. updater, creator := "Anonymous", "Anonymous"
  134. if folder.CreatedBy > 0 {
  135. creator = getUserLogin(folder.CreatedBy)
  136. }
  137. if folder.UpdatedBy > 0 {
  138. updater = getUserLogin(folder.UpdatedBy)
  139. }
  140. return dtos.Folder{
  141. Id: folder.Id,
  142. Uid: folder.Uid,
  143. Title: folder.Title,
  144. Url: folder.GetUrl(),
  145. HasAcl: folder.HasAcl,
  146. CanSave: canSave,
  147. CanEdit: canEdit,
  148. CanAdmin: canAdmin,
  149. CreatedBy: creator,
  150. Created: folder.Created,
  151. UpdatedBy: updater,
  152. Updated: folder.Updated,
  153. Version: folder.Version,
  154. }
  155. }
  156. func toFolderError(err error) Response {
  157. if err == m.ErrDashboardTitleEmpty {
  158. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  159. }
  160. if err == m.ErrDashboardWithSameNameInFolderExists {
  161. return Json(412, util.DynMap{"status": "name-exists", "message": m.ErrFolderSameNameExists.Error()})
  162. }
  163. if err == m.ErrDashboardWithSameUIDExists {
  164. return Json(412, util.DynMap{"status": "uid-exists", "message": m.ErrFolderWithSameUIDExists.Error()})
  165. }
  166. if err == m.ErrDashboardVersionMismatch {
  167. return Json(412, util.DynMap{"status": "version-mismatch", "message": m.ErrFolderVersionMismatch.Error()})
  168. }
  169. if err == m.ErrDashboardNotFound {
  170. return Json(404, util.DynMap{"status": "not-found", "message": m.ErrFolderNotFound.Error()})
  171. }
  172. if err == m.ErrDashboardFailedGenerateUniqueUid {
  173. err = m.ErrFolderFailedGenerateUniqueUid
  174. }
  175. return ApiError(500, "Failed to create folder", err)
  176. }