folder.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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 GetFolder(c *middleware.Context) Response {
  32. folder, rsp := getFolderHelper(c.OrgId, c.ParamsInt64(":id"), c.Params(":uid"))
  33. if rsp != nil {
  34. return rsp
  35. }
  36. guardian := guardian.New(folder.Id, c.OrgId, c.SignedInUser)
  37. if canView, err := guardian.CanView(); err != nil || !canView {
  38. fmt.Printf("%v", err)
  39. return folderGuardianResponse(err)
  40. }
  41. return Json(200, toFolderDto(&guardian, folder))
  42. }
  43. func CreateFolder(c *middleware.Context, cmd m.CreateFolderCommand) Response {
  44. cmd.OrgId = c.OrgId
  45. cmd.UserId = c.UserId
  46. dashFolder := cmd.GetDashboardModel()
  47. guardian := guardian.New(0, c.OrgId, c.SignedInUser)
  48. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  49. return folderGuardianResponse(err)
  50. }
  51. if dashFolder.Title == "" {
  52. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  53. }
  54. limitReached, err := middleware.QuotaReached(c, "folder")
  55. if err != nil {
  56. return ApiError(500, "failed to get quota", err)
  57. }
  58. if limitReached {
  59. return ApiError(403, "Quota reached", nil)
  60. }
  61. saveDashboardDto := &dashboards.SaveDashboardDTO{
  62. Dashboard: dashFolder,
  63. OrgId: c.OrgId,
  64. UserId: c.UserId,
  65. }
  66. folder, err := dashboards.GetRepository().SaveDashboard(saveDashboardDto)
  67. if err != nil {
  68. return toFolderError(err)
  69. }
  70. return Json(200, toFolderDto(&guardian, folder))
  71. }
  72. func UpdateFolder(c *middleware.Context, cmd m.UpdateFolderCommand) Response {
  73. cmd.OrgId = c.OrgId
  74. cmd.UserId = c.UserId
  75. uid := c.Params(":uid")
  76. dashFolder, rsp := getFolderHelper(c.OrgId, 0, uid)
  77. if rsp != nil {
  78. return rsp
  79. }
  80. guardian := guardian.New(dashFolder.Id, c.OrgId, c.SignedInUser)
  81. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  82. return folderGuardianResponse(err)
  83. }
  84. cmd.UpdateDashboardModel(dashFolder)
  85. if dashFolder.Title == "" {
  86. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  87. }
  88. saveDashboardDto := &dashboards.SaveDashboardDTO{
  89. Dashboard: dashFolder,
  90. OrgId: c.OrgId,
  91. UserId: c.UserId,
  92. Overwrite: cmd.Overwrite,
  93. }
  94. folder, err := dashboards.GetRepository().SaveDashboard(saveDashboardDto)
  95. if err != nil {
  96. return toFolderError(err)
  97. }
  98. return Json(200, toFolderDto(&guardian, folder))
  99. }
  100. func DeleteFolder(c *middleware.Context) Response {
  101. dashFolder, rsp := getFolderHelper(c.OrgId, 0, c.Params(":uid"))
  102. if rsp != nil {
  103. return rsp
  104. }
  105. guardian := guardian.New(dashFolder.Id, c.OrgId, c.SignedInUser)
  106. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  107. return folderGuardianResponse(err)
  108. }
  109. deleteCmd := m.DeleteDashboardCommand{OrgId: c.OrgId, Id: dashFolder.Id}
  110. if err := bus.Dispatch(&deleteCmd); err != nil {
  111. return ApiError(500, "Failed to delete folder", err)
  112. }
  113. var resp = map[string]interface{}{"title": dashFolder.Title}
  114. return Json(200, resp)
  115. }
  116. func toFolderDto(g *guardian.DashboardGuardian, folder *m.Dashboard) dtos.Folder {
  117. canEdit, _ := g.CanEdit()
  118. canSave, _ := g.CanSave()
  119. canAdmin, _ := g.CanAdmin()
  120. // Finding creator and last updater of the folder
  121. updater, creator := "Anonymous", "Anonymous"
  122. if folder.CreatedBy > 0 {
  123. creator = getUserLogin(folder.CreatedBy)
  124. }
  125. if folder.UpdatedBy > 0 {
  126. updater = getUserLogin(folder.UpdatedBy)
  127. }
  128. return dtos.Folder{
  129. Id: folder.Id,
  130. Uid: folder.Uid,
  131. Title: folder.Title,
  132. Url: folder.GetUrl(),
  133. HasAcl: folder.HasAcl,
  134. CanSave: canSave,
  135. CanEdit: canEdit,
  136. CanAdmin: canAdmin,
  137. CreatedBy: creator,
  138. Created: folder.Created,
  139. UpdatedBy: updater,
  140. Updated: folder.Updated,
  141. Version: folder.Version,
  142. }
  143. }
  144. func toFolderError(err error) Response {
  145. if err == m.ErrDashboardTitleEmpty {
  146. return ApiError(400, m.ErrFolderTitleEmpty.Error(), nil)
  147. }
  148. if err == m.ErrDashboardWithSameNameInFolderExists {
  149. return Json(412, util.DynMap{"status": "name-exists", "message": m.ErrFolderSameNameExists.Error()})
  150. }
  151. if err == m.ErrDashboardWithSameUIDExists {
  152. return Json(412, util.DynMap{"status": "uid-exists", "message": m.ErrFolderWithSameUIDExists.Error()})
  153. }
  154. if err == m.ErrDashboardVersionMismatch {
  155. return Json(412, util.DynMap{"status": "version-mismatch", "message": m.ErrFolderVersionMismatch.Error()})
  156. }
  157. if err == m.ErrDashboardNotFound {
  158. return Json(404, util.DynMap{"status": "not-found", "message": m.ErrFolderNotFound.Error()})
  159. }
  160. if err == m.ErrDashboardFailedGenerateUniqueUid {
  161. err = m.ErrFolderFailedGenerateUniqueUid
  162. }
  163. return ApiError(500, "Failed to create folder", err)
  164. }