[MM-48523] Expose resumable uploads API to plugins (#21700)
* Expose resumable uploads API to plugins * Update translations
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a1e16f7b02
Коммит
0509e78744
@@ -1237,3 +1237,27 @@ func (api *PluginAPI) GetCloudLimits() (*model.ProductLimits, error) {
|
||||
func (api *PluginAPI) RegisterCollectionAndTopic(collectionType, topicType string) error {
|
||||
return api.app.registerCollectionAndTopic(api.id, collectionType, topicType)
|
||||
}
|
||||
|
||||
func (api *PluginAPI) CreateUploadSession(us *model.UploadSession) (*model.UploadSession, error) {
|
||||
us, err := api.app.CreateUploadSession(api.ctx, us)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return us, nil
|
||||
}
|
||||
|
||||
func (api *PluginAPI) UploadData(us *model.UploadSession, rd io.Reader) (*model.FileInfo, error) {
|
||||
fi, err := api.app.UploadData(api.ctx, us, rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fi, nil
|
||||
}
|
||||
|
||||
func (api *PluginAPI) GetUploadSession(uploadID string) (*model.UploadSession, error) {
|
||||
fi, err := api.app.GetUploadSession(uploadID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fi, nil
|
||||
}
|
||||
|
||||
@@ -2100,3 +2100,98 @@ func TestRegisterCollectionAndTopic(t *testing.T) {
|
||||
err = api.RegisterCollectionAndTopic("some other collection", "topicToBeRepeated")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestPluginUploadsAPI(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
pluginCode := fmt.Sprintf(`
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/plugin"
|
||||
)
|
||||
|
||||
type TestPlugin struct {
|
||||
plugin.MattermostPlugin
|
||||
}
|
||||
|
||||
func (p *TestPlugin) OnActivate() error {
|
||||
data := []byte("some content to upload")
|
||||
us, err := p.API.CreateUploadSession(&model.UploadSession{
|
||||
Id: "%s",
|
||||
UserId: "%s",
|
||||
ChannelId: "%s",
|
||||
Type: model.UploadTypeAttachment,
|
||||
FileSize: int64(len(data)),
|
||||
Filename: "upload.test",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create upload session: %%w", err)
|
||||
}
|
||||
|
||||
us2, err := p.API.GetUploadSession(us.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get upload session: %%w", err)
|
||||
}
|
||||
|
||||
if us.Id != us2.Id {
|
||||
return fmt.Errorf("upload sessions should match")
|
||||
}
|
||||
|
||||
fi, err := p.API.UploadData(us, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload data: %%w", err)
|
||||
}
|
||||
|
||||
if fi == nil || fi.Id == "" {
|
||||
return fmt.Errorf("fileinfo should be set")
|
||||
}
|
||||
|
||||
fileData, appErr := p.API.GetFile(fi.Id)
|
||||
if appErr != nil {
|
||||
return fmt.Errorf("failed to get file data: %%w", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(data, fileData) {
|
||||
return fmt.Errorf("file data should match")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
plugin.ClientMain(&TestPlugin{})
|
||||
}
|
||||
`, model.NewId(), th.BasicUser.Id, th.BasicChannel.Id)
|
||||
|
||||
pluginDir, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
webappPluginDir, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(pluginDir)
|
||||
defer os.RemoveAll(webappPluginDir)
|
||||
|
||||
newPluginAPI := func(manifest *model.Manifest) plugin.API {
|
||||
return th.App.NewPluginAPI(th.Context, manifest)
|
||||
}
|
||||
env, err := plugin.NewEnvironment(newPluginAPI, NewDriverImpl(th.App.Srv()), pluginDir, webappPluginDir, th.App.Log(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
th.App.ch.SetPluginsEnvironment(env)
|
||||
|
||||
pluginID := "testplugin"
|
||||
pluginManifest := `{"id": "testplugin", "server": {"executable": "backend.exe"}}`
|
||||
backend := filepath.Join(pluginDir, pluginID, "backend.exe")
|
||||
utils.CompileGo(t, pluginCode, backend)
|
||||
|
||||
os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(pluginManifest), 0600)
|
||||
manifest, activated, reterr := env.Activate(pluginID)
|
||||
require.NoError(t, reterr)
|
||||
require.NotNil(t, manifest)
|
||||
require.True(t, activated)
|
||||
}
|
||||
|
||||
@@ -127,11 +127,6 @@ func (a *App) runPluginsHook(c *request.Context, info *model.FileInfo, file io.R
|
||||
}
|
||||
|
||||
func (a *App) CreateUploadSession(c request.CTX, us *model.UploadSession) (*model.UploadSession, *model.AppError) {
|
||||
if us.FileSize > *a.Config().FileSettings.MaxFileSize {
|
||||
return nil, model.NewAppError("CreateUploadSession", "app.upload.create.upload_too_large.app_error",
|
||||
map[string]any{"channelId": us.ChannelId}, "", http.StatusRequestEntityTooLarge)
|
||||
}
|
||||
|
||||
us.FileOffset = 0
|
||||
now := time.Now()
|
||||
us.CreateAt = model.GetMillisForTime(now)
|
||||
|
||||
@@ -32,16 +32,6 @@ func TestCreateUploadSession(t *testing.T) {
|
||||
FileSize: 8 * 1024 * 1024,
|
||||
}
|
||||
|
||||
t.Run("FileSize over limit", func(t *testing.T) {
|
||||
maxFileSize := *th.App.Config().FileSettings.MaxFileSize
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.MaxFileSize = us.FileSize - 1 })
|
||||
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.MaxFileSize = maxFileSize })
|
||||
u, err := th.App.CreateUploadSession(th.Context, us)
|
||||
require.NotNil(t, err)
|
||||
require.Equal(t, "app.upload.create.upload_too_large.app_error", err.Id)
|
||||
require.Nil(t, u)
|
||||
})
|
||||
|
||||
t.Run("invalid Id", func(t *testing.T) {
|
||||
u, err := th.App.CreateUploadSession(th.Context, us)
|
||||
require.NotNil(t, err)
|
||||
|
||||
Ссылка в новой задаче
Block a user