folder_service.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package dashboards
  2. import (
  3. "github.com/grafana/grafana/pkg/bus"
  4. "github.com/grafana/grafana/pkg/models"
  5. "github.com/grafana/grafana/pkg/services/guardian"
  6. "github.com/grafana/grafana/pkg/services/search"
  7. )
  8. // FolderService service for operating on folders
  9. type FolderService interface {
  10. GetFolders(limit int64) ([]*models.Folder, error)
  11. GetFolderByID(id int64) (*models.Folder, error)
  12. GetFolderByUID(uid string) (*models.Folder, error)
  13. CreateFolder(cmd *models.CreateFolderCommand) error
  14. UpdateFolder(uid string, cmd *models.UpdateFolderCommand) error
  15. DeleteFolder(uid string) (*models.Folder, error)
  16. }
  17. // NewFolderService factory for creating a new folder service
  18. var NewFolderService = func(orgId int64, user *models.SignedInUser) FolderService {
  19. return &dashboardServiceImpl{
  20. orgId: orgId,
  21. user: user,
  22. }
  23. }
  24. func (dr *dashboardServiceImpl) GetFolders(limit int64) ([]*models.Folder, error) {
  25. searchQuery := search.Query{
  26. SignedInUser: dr.user,
  27. DashboardIds: make([]int64, 0),
  28. FolderIds: make([]int64, 0),
  29. Limit: limit,
  30. OrgId: dr.orgId,
  31. Type: "dash-folder",
  32. Permission: models.PERMISSION_VIEW,
  33. }
  34. if err := bus.Dispatch(&searchQuery); err != nil {
  35. return nil, err
  36. }
  37. folders := make([]*models.Folder, 0)
  38. for _, hit := range searchQuery.Result {
  39. folders = append(folders, &models.Folder{
  40. Id: hit.Id,
  41. Uid: hit.Uid,
  42. Title: hit.Title,
  43. })
  44. }
  45. return folders, nil
  46. }
  47. func (dr *dashboardServiceImpl) GetFolderByID(id int64) (*models.Folder, error) {
  48. query := models.GetDashboardQuery{OrgId: dr.orgId, Id: id}
  49. dashFolder, err := getFolder(query)
  50. if err != nil {
  51. return nil, toFolderError(err)
  52. }
  53. g := guardian.New(dashFolder.Id, dr.orgId, dr.user)
  54. if canView, err := g.CanView(); err != nil || !canView {
  55. if err != nil {
  56. return nil, toFolderError(err)
  57. }
  58. return nil, models.ErrFolderAccessDenied
  59. }
  60. return dashToFolder(dashFolder), nil
  61. }
  62. func (dr *dashboardServiceImpl) GetFolderByUID(uid string) (*models.Folder, error) {
  63. query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: uid}
  64. dashFolder, err := getFolder(query)
  65. if err != nil {
  66. return nil, toFolderError(err)
  67. }
  68. g := guardian.New(dashFolder.Id, dr.orgId, dr.user)
  69. if canView, err := g.CanView(); err != nil || !canView {
  70. if err != nil {
  71. return nil, toFolderError(err)
  72. }
  73. return nil, models.ErrFolderAccessDenied
  74. }
  75. return dashToFolder(dashFolder), nil
  76. }
  77. func (dr *dashboardServiceImpl) CreateFolder(cmd *models.CreateFolderCommand) error {
  78. dashFolder := cmd.GetDashboardModel(dr.orgId, dr.user.UserId)
  79. dto := &SaveDashboardDTO{
  80. Dashboard: dashFolder,
  81. OrgId: dr.orgId,
  82. User: dr.user,
  83. }
  84. saveDashboardCmd, err := dr.buildSaveDashboardCommand(dto, false, false)
  85. if err != nil {
  86. return toFolderError(err)
  87. }
  88. err = bus.Dispatch(saveDashboardCmd)
  89. if err != nil {
  90. return toFolderError(err)
  91. }
  92. query := models.GetDashboardQuery{OrgId: dr.orgId, Id: saveDashboardCmd.Result.Id}
  93. dashFolder, err = getFolder(query)
  94. if err != nil {
  95. return toFolderError(err)
  96. }
  97. cmd.Result = dashToFolder(dashFolder)
  98. return nil
  99. }
  100. func (dr *dashboardServiceImpl) UpdateFolder(existingUid string, cmd *models.UpdateFolderCommand) error {
  101. query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: existingUid}
  102. dashFolder, err := getFolder(query)
  103. if err != nil {
  104. return toFolderError(err)
  105. }
  106. cmd.UpdateDashboardModel(dashFolder, dr.orgId, dr.user.UserId)
  107. dto := &SaveDashboardDTO{
  108. Dashboard: dashFolder,
  109. OrgId: dr.orgId,
  110. User: dr.user,
  111. Overwrite: cmd.Overwrite,
  112. }
  113. saveDashboardCmd, err := dr.buildSaveDashboardCommand(dto, false, false)
  114. if err != nil {
  115. return toFolderError(err)
  116. }
  117. err = bus.Dispatch(saveDashboardCmd)
  118. if err != nil {
  119. return toFolderError(err)
  120. }
  121. query = models.GetDashboardQuery{OrgId: dr.orgId, Id: saveDashboardCmd.Result.Id}
  122. dashFolder, err = getFolder(query)
  123. if err != nil {
  124. return toFolderError(err)
  125. }
  126. cmd.Result = dashToFolder(dashFolder)
  127. return nil
  128. }
  129. func (dr *dashboardServiceImpl) DeleteFolder(uid string) (*models.Folder, error) {
  130. query := models.GetDashboardQuery{OrgId: dr.orgId, Uid: uid}
  131. dashFolder, err := getFolder(query)
  132. if err != nil {
  133. return nil, toFolderError(err)
  134. }
  135. guardian := guardian.New(dashFolder.Id, dr.orgId, dr.user)
  136. if canSave, err := guardian.CanSave(); err != nil || !canSave {
  137. if err != nil {
  138. return nil, toFolderError(err)
  139. }
  140. return nil, models.ErrFolderAccessDenied
  141. }
  142. deleteCmd := models.DeleteDashboardCommand{OrgId: dr.orgId, Id: dashFolder.Id}
  143. if err := bus.Dispatch(&deleteCmd); err != nil {
  144. return nil, toFolderError(err)
  145. }
  146. return dashToFolder(dashFolder), nil
  147. }
  148. func getFolder(query models.GetDashboardQuery) (*models.Dashboard, error) {
  149. if err := bus.Dispatch(&query); err != nil {
  150. return nil, toFolderError(err)
  151. }
  152. if !query.Result.IsFolder {
  153. return nil, models.ErrFolderNotFound
  154. }
  155. return query.Result, nil
  156. }
  157. func dashToFolder(dash *models.Dashboard) *models.Folder {
  158. return &models.Folder{
  159. Id: dash.Id,
  160. Uid: dash.Uid,
  161. Title: dash.Title,
  162. HasAcl: dash.HasAcl,
  163. Url: dash.GetUrl(),
  164. Version: dash.Version,
  165. Created: dash.Created,
  166. CreatedBy: dash.CreatedBy,
  167. Updated: dash.Updated,
  168. UpdatedBy: dash.UpdatedBy,
  169. }
  170. }
  171. func toFolderError(err error) error {
  172. if err == models.ErrDashboardTitleEmpty {
  173. return models.ErrFolderTitleEmpty
  174. }
  175. if err == models.ErrDashboardUpdateAccessDenied {
  176. return models.ErrFolderAccessDenied
  177. }
  178. if err == models.ErrDashboardWithSameNameInFolderExists {
  179. return models.ErrFolderSameNameExists
  180. }
  181. if err == models.ErrDashboardWithSameUIDExists {
  182. return models.ErrFolderWithSameUIDExists
  183. }
  184. if err == models.ErrDashboardVersionMismatch {
  185. return models.ErrFolderVersionMismatch
  186. }
  187. if err == models.ErrDashboardNotFound {
  188. return models.ErrFolderNotFound
  189. }
  190. if err == models.ErrDashboardFailedGenerateUniqueUid {
  191. err = models.ErrFolderFailedGenerateUniqueUid
  192. }
  193. return err
  194. }