mirror of https://github.com/usememos/memos
refactor: migrate storage to apiv1 (#1890)
* refactor: migrate storage to apiv1 * chore: update * chore: update * chore: updatepull/1895/head
parent
0af14fc81a
commit
5b6c98582e
@ -1,57 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LocalStorage means the storage service is local file system.
|
|
||||||
LocalStorage = -1
|
|
||||||
// DatabaseStorage means the storage service is database.
|
|
||||||
DatabaseStorage = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
type StorageType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
StorageS3 StorageType = "S3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StorageConfig struct {
|
|
||||||
S3Config *StorageS3Config `json:"s3Config"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StorageS3Config struct {
|
|
||||||
EndPoint string `json:"endPoint"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
Region string `json:"region"`
|
|
||||||
AccessKey string `json:"accessKey"`
|
|
||||||
SecretKey string `json:"secretKey"`
|
|
||||||
Bucket string `json:"bucket"`
|
|
||||||
URLPrefix string `json:"urlPrefix"`
|
|
||||||
URLSuffix string `json:"urlSuffix"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Storage struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type StorageType `json:"type"`
|
|
||||||
Config *StorageConfig `json:"config"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StorageCreate struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type StorageType `json:"type"`
|
|
||||||
Config *StorageConfig `json:"config"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StoragePatch struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
Type StorageType `json:"type"`
|
|
||||||
Name *string `json:"name"`
|
|
||||||
Config *StorageConfig `json:"config"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StorageFind struct {
|
|
||||||
ID *int `json:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StorageDelete struct {
|
|
||||||
ID int `json:"id"`
|
|
||||||
}
|
|
@ -1,8 +1,260 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// LocalStorage means the storage service is local file system.
|
// LocalStorage means the storage service is local file system.
|
||||||
LocalStorage = -1
|
LocalStorage = -1
|
||||||
// DatabaseStorage means the storage service is database.
|
// DatabaseStorage means the storage service is database.
|
||||||
DatabaseStorage = 0
|
DatabaseStorage = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type StorageType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
StorageS3 StorageType = "S3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t StorageType) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageConfig struct {
|
||||||
|
S3Config *StorageS3Config `json:"s3Config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorageS3Config struct {
|
||||||
|
EndPoint string `json:"endPoint"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
AccessKey string `json:"accessKey"`
|
||||||
|
SecretKey string `json:"secretKey"`
|
||||||
|
Bucket string `json:"bucket"`
|
||||||
|
URLPrefix string `json:"urlPrefix"`
|
||||||
|
URLSuffix string `json:"urlSuffix"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Storage struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type StorageType `json:"type"`
|
||||||
|
Config *StorageConfig `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateStorageRequest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type StorageType `json:"type"`
|
||||||
|
Config *StorageConfig `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateStorageRequest struct {
|
||||||
|
Type StorageType `json:"type"`
|
||||||
|
Name *string `json:"name"`
|
||||||
|
Config *StorageConfig `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *APIV1Service) registerStorageRoutes(g *echo.Group) {
|
||||||
|
g.POST("/storage", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||||
|
ID: &userID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||||
|
}
|
||||||
|
if user == nil || user.Role != store.RoleHost {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
create := &CreateStorageRequest{}
|
||||||
|
if err := json.NewDecoder(c.Request().Body).Decode(create); err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post storage request").SetInternal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
configString := ""
|
||||||
|
if create.Type == StorageS3 && create.Config.S3Config != nil {
|
||||||
|
configBytes, err := json.Marshal(create.Config.S3Config)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post storage request").SetInternal(err)
|
||||||
|
}
|
||||||
|
configString = string(configBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
storage, err := s.Store.CreateStorage(ctx, &store.Storage{
|
||||||
|
Name: create.Name,
|
||||||
|
Type: create.Type.String(),
|
||||||
|
Config: configString,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
storageMessage, err := ConvertStorageFromStore(storage)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to convert storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, storageMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.PATCH("/storage/:storageId", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||||
|
ID: &userID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||||
|
}
|
||||||
|
if user == nil || user.Role != store.RoleHost {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
storageID, err := strconv.Atoi(c.Param("storageId"))
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
update := &UpdateStorageRequest{}
|
||||||
|
if err := json.NewDecoder(c.Request().Body).Decode(update); err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch storage request").SetInternal(err)
|
||||||
|
}
|
||||||
|
storageUpdate := &store.UpdateStorage{
|
||||||
|
ID: storageID,
|
||||||
|
}
|
||||||
|
if update.Name != nil {
|
||||||
|
storageUpdate.Name = update.Name
|
||||||
|
}
|
||||||
|
if update.Config != nil {
|
||||||
|
if update.Type == StorageS3 {
|
||||||
|
configBytes, err := json.Marshal(update.Config.S3Config)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post storage request").SetInternal(err)
|
||||||
|
}
|
||||||
|
configString := string(configBytes)
|
||||||
|
storageUpdate.Config = &configString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storage, err := s.Store.UpdateStorage(ctx, storageUpdate)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
storageMessage, err := ConvertStorageFromStore(storage)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to convert storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, storageMessage)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.GET("/storage", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||||
|
ID: &userID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||||
|
}
|
||||||
|
// We should only show storage list to host user.
|
||||||
|
if user == nil || user.Role != store.RoleHost {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
list, err := s.Store.ListStorages(ctx, &store.FindStorage{})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage list").SetInternal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
storageList := []*Storage{}
|
||||||
|
for _, storage := range list {
|
||||||
|
storageMessage, err := ConvertStorageFromStore(storage)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to convert storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
storageList = append(storageList, storageMessage)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, storageList)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.DELETE("/storage/:storageId", func(c echo.Context) error {
|
||||||
|
ctx := c.Request().Context()
|
||||||
|
userID, ok := c.Get(getUserIDContextKey()).(int)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||||
|
ID: &userID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
||||||
|
}
|
||||||
|
if user == nil || user.Role != store.RoleHost {
|
||||||
|
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
storageID, err := strconv.Atoi(c.Param("storageId"))
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
systemSetting, err := s.Store.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingStorageServiceIDName.String()})
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
if systemSetting != nil {
|
||||||
|
storageServiceID := DatabaseStorage
|
||||||
|
err = json.Unmarshal([]byte(systemSetting.Value), &storageServiceID)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal storage service id").SetInternal(err)
|
||||||
|
}
|
||||||
|
if storageServiceID == storageID {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Storage service %d is using", storageID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.Store.DeleteStorage(ctx, &store.DeleteStorage{ID: storageID}); err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete storage").SetInternal(err)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertStorageFromStore(storage *store.Storage) (*Storage, error) {
|
||||||
|
storageMessage := &Storage{
|
||||||
|
ID: storage.ID,
|
||||||
|
Name: storage.Name,
|
||||||
|
Type: StorageType(storage.Type),
|
||||||
|
Config: &StorageConfig{},
|
||||||
|
}
|
||||||
|
if storageMessage.Type == StorageS3 {
|
||||||
|
s3Config := &StorageS3Config{}
|
||||||
|
if err := json.Unmarshal([]byte(storage.Config), s3Config); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
storageMessage.Config = &StorageConfig{
|
||||||
|
S3Config: s3Config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return storageMessage, nil
|
||||||
|
}
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/usememos/memos/api"
|
|
||||||
apiv1 "github.com/usememos/memos/api/v1"
|
|
||||||
"github.com/usememos/memos/common"
|
|
||||||
"github.com/usememos/memos/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Server) registerStorageRoutes(g *echo.Group) {
|
|
||||||
g.POST("/storage", func(c echo.Context) error {
|
|
||||||
ctx := c.Request().Context()
|
|
||||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
|
||||||
if !ok {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
|
||||||
ID: &userID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
|
||||||
}
|
|
||||||
if user == nil || user.Role != store.RoleHost {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
|
||||||
}
|
|
||||||
|
|
||||||
storageCreate := &api.StorageCreate{}
|
|
||||||
if err := json.NewDecoder(c.Request().Body).Decode(storageCreate); err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post storage request").SetInternal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
storage, err := s.Store.CreateStorage(ctx, storageCreate)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create storage").SetInternal(err)
|
|
||||||
}
|
|
||||||
return c.JSON(http.StatusOK, composeResponse(storage))
|
|
||||||
})
|
|
||||||
|
|
||||||
g.PATCH("/storage/:storageId", func(c echo.Context) error {
|
|
||||||
ctx := c.Request().Context()
|
|
||||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
|
||||||
if !ok {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
|
||||||
ID: &userID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
|
||||||
}
|
|
||||||
if user == nil || user.Role != store.RoleHost {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
|
||||||
}
|
|
||||||
|
|
||||||
storageID, err := strconv.Atoi(c.Param("storageId"))
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
storagePatch := &api.StoragePatch{
|
|
||||||
ID: storageID,
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(c.Request().Body).Decode(storagePatch); err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch storage request").SetInternal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
storage, err := s.Store.PatchStorage(ctx, storagePatch)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch storage").SetInternal(err)
|
|
||||||
}
|
|
||||||
return c.JSON(http.StatusOK, composeResponse(storage))
|
|
||||||
})
|
|
||||||
|
|
||||||
g.GET("/storage", func(c echo.Context) error {
|
|
||||||
ctx := c.Request().Context()
|
|
||||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
|
||||||
if !ok {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
|
||||||
ID: &userID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
|
||||||
}
|
|
||||||
// We should only show storage list to host user.
|
|
||||||
if user == nil || user.Role != store.RoleHost {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
|
||||||
}
|
|
||||||
|
|
||||||
storageList, err := s.Store.FindStorageList(ctx, &api.StorageFind{})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage list").SetInternal(err)
|
|
||||||
}
|
|
||||||
return c.JSON(http.StatusOK, composeResponse(storageList))
|
|
||||||
})
|
|
||||||
|
|
||||||
g.DELETE("/storage/:storageId", func(c echo.Context) error {
|
|
||||||
ctx := c.Request().Context()
|
|
||||||
userID, ok := c.Get(getUserIDContextKey()).(int)
|
|
||||||
if !ok {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
|
||||||
ID: &userID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
|
|
||||||
}
|
|
||||||
if user == nil || user.Role != store.RoleHost {
|
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
|
|
||||||
}
|
|
||||||
|
|
||||||
storageID, err := strconv.Atoi(c.Param("storageId"))
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("storageId"))).SetInternal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
systemSetting, err := s.Store.GetSystemSetting(ctx, &store.FindSystemSetting{Name: apiv1.SystemSettingStorageServiceIDName.String()})
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find storage").SetInternal(err)
|
|
||||||
}
|
|
||||||
if systemSetting != nil {
|
|
||||||
storageServiceID := api.DatabaseStorage
|
|
||||||
err = json.Unmarshal([]byte(systemSetting.Value), &storageServiceID)
|
|
||||||
if err != nil {
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal storage service id").SetInternal(err)
|
|
||||||
}
|
|
||||||
if storageServiceID == storageID {
|
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Storage service %d is using", storageID))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.Store.DeleteStorage(ctx, &api.StorageDelete{ID: storageID}); err != nil {
|
|
||||||
if common.ErrorCode(err) == common.NotFound {
|
|
||||||
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Storage ID not found: %d", storageID))
|
|
||||||
}
|
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to delete storage").SetInternal(err)
|
|
||||||
}
|
|
||||||
return c.JSON(http.StatusOK, true)
|
|
||||||
})
|
|
||||||
}
|
|
@ -0,0 +1,38 @@
|
|||||||
|
package teststore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/usememos/memos/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStorageStore(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ts := NewTestingStore(ctx, t)
|
||||||
|
storage, err := ts.CreateStorage(ctx, &store.Storage{
|
||||||
|
Name: "test_storage",
|
||||||
|
Type: "S3",
|
||||||
|
Config: "{}",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
newStorageName := "new_storage_name"
|
||||||
|
updatedStorage, err := ts.UpdateStorage(ctx, &store.UpdateStorage{
|
||||||
|
ID: storage.ID,
|
||||||
|
Name: &newStorageName,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, newStorageName, updatedStorage.Name)
|
||||||
|
storageList, err := ts.ListStorages(ctx, &store.FindStorage{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(storageList))
|
||||||
|
require.Equal(t, updatedStorage, storageList[0])
|
||||||
|
err = ts.DeleteStorage(ctx, &store.DeleteStorage{
|
||||||
|
ID: storage.ID,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
storageList, err = ts.ListStorages(ctx, &store.FindStorage{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 0, len(storageList))
|
||||||
|
}
|
Loading…
Reference in New Issue