storage.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package server
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "github.com/labstack/echo/v4"
  8. "github.com/usememos/memos/api"
  9. "github.com/usememos/memos/common"
  10. )
  11. func (s *Server) registerStorageRoutes(g *echo.Group) {
  12. g.POST("/storage", func(c echo.Context) error {
  13. ctx := c.Request().Context()
  14. userID, ok := c.Get(getUserIDContextKey()).(int)
  15. if !ok {
  16. return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
  17. }
  18. user, err := s.Store.FindUser(ctx, &api.UserFind{
  19. ID: &userID,
  20. })
  21. if err != nil {
  22. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
  23. }
  24. if user == nil || user.Role != api.Host {
  25. return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
  26. }
  27. storageCreate := &api.StorageCreate{}
  28. if err := json.NewDecoder(c.Request().Body).Decode(storageCreate); err != nil {
  29. return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post storage request").SetInternal(err)
  30. }
  31. storage, err := s.Store.CreateStorage(ctx, storageCreate)
  32. if err != nil {
  33. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create storage").SetInternal(err)
  34. }
  35. return c.JSON(http.StatusOK, composeResponse(storage))
  36. })
  37. g.PATCH("/storage/:storageId", func(c echo.Context) error {
  38. ctx := c.Request().Context()
  39. userID, ok := c.Get(getUserIDContextKey()).(int)
  40. if !ok {
  41. return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
  42. }
  43. user, err := s.Store.FindUser(ctx, &api.UserFind{
  44. ID: &userID,
  45. })
  46. if err != nil {
  47. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
  48. }
  49. if user == nil || user.Role != api.Host {
  50. return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
  51. }
  52. storageID, err := strconv.Atoi(c.Param("storageId"))
  53. if err != nil {
  54. return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
  55. }
  56. storagePatch := &api.StoragePatch{
  57. ID: storageID,
  58. }
  59. if err := json.NewDecoder(c.Request().Body).Decode(storagePatch); err != nil {
  60. return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch storage request").SetInternal(err)
  61. }
  62. storage, err := s.Store.PatchStorage(ctx, storagePatch)
  63. if err != nil {
  64. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch storage").SetInternal(err)
  65. }
  66. return c.JSON(http.StatusOK, composeResponse(storage))
  67. })
  68. g.GET("/storage", func(c echo.Context) error {
  69. ctx := c.Request().Context()
  70. userID, ok := c.Get(getUserIDContextKey()).(int)
  71. if !ok {
  72. return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
  73. }
  74. user, err := s.Store.FindUser(ctx, &api.UserFind{
  75. ID: &userID,
  76. })
  77. if err != nil {
  78. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
  79. }
  80. // We should only show storage list to host user.
  81. if user == nil || user.Role != api.Host {
  82. return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
  83. }
  84. storageList, err := s.Store.FindStorageList(ctx, &api.StorageFind{})
  85. if err != nil {
  86. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage list").SetInternal(err)
  87. }
  88. return c.JSON(http.StatusOK, composeResponse(storageList))
  89. })
  90. g.DELETE("/storage/:storageId", func(c echo.Context) error {
  91. ctx := c.Request().Context()
  92. userID, ok := c.Get(getUserIDContextKey()).(int)
  93. if !ok {
  94. return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
  95. }
  96. user, err := s.Store.FindUser(ctx, &api.UserFind{
  97. ID: &userID,
  98. })
  99. if err != nil {
  100. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
  101. }
  102. if user == nil || user.Role != api.Host {
  103. return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
  104. }
  105. storageID, err := strconv.Atoi(c.Param("storageId"))
  106. if err != nil {
  107. return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
  108. }
  109. systemSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{Name: api.SystemSettingStorageServiceIDName})
  110. if err != nil && common.ErrorCode(err) != common.NotFound {
  111. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage").SetInternal(err)
  112. }
  113. if systemSetting != nil {
  114. storageServiceID := api.DatabaseStorage
  115. err = json.Unmarshal([]byte(systemSetting.Value), &storageServiceID)
  116. if err != nil {
  117. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal storage service id").SetInternal(err)
  118. }
  119. if storageServiceID == storageID {
  120. return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Storage service %d is using", storageID))
  121. }
  122. }
  123. if err = s.Store.DeleteStorage(ctx, &api.StorageDelete{ID: storageID}); err != nil {
  124. if common.ErrorCode(err) == common.NotFound {
  125. return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Storage ID not found: %d", storageID))
  126. }
  127. return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete storage").SetInternal(err)
  128. }
  129. return c.JSON(http.StatusOK, true)
  130. })
  131. }