[MM-10621] Set createAt timestamp on file upload api call to secure upload order of files (#9170)

* set createAt timestamp on file upload api call to secure upload order of files

* fix test on plugin hooks
Этот коммит содержится в:
Saturnino Abril
2018-07-28 14:27:55 +08:00
коммит произвёл GitHub
родитель 6ac82d5171
Коммит 51dc5fa36e
3 изменённых файлов: 18 добавлений и 5 удалений

Просмотреть файл

@@ -10,6 +10,7 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
@@ -69,6 +70,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
now := time.Now()
var resStruct *model.FileUploadResponse var resStruct *model.FileUploadResponse
var appErr *model.AppError var appErr *model.AppError
@@ -100,6 +102,7 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
[]io.ReadCloser{r.Body}, []io.ReadCloser{r.Body},
[]string{filename}, []string{filename},
[]string{}, []string{},
now,
) )
} else { } else {
m := r.MultipartForm m := r.MultipartForm
@@ -120,7 +123,14 @@ func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
resStruct, appErr = c.App.UploadMultipartFiles(FILE_TEAM_ID, channelId, c.Session.UserId, m.File["files"], m.Value["client_ids"]) resStruct, appErr = c.App.UploadMultipartFiles(
FILE_TEAM_ID,
channelId,
c.Session.UserId,
m.File["files"],
m.Value["client_ids"],
now,
)
} }
if appErr != nil { if appErr != nil {

Просмотреть файл

@@ -321,7 +321,7 @@ func GeneratePublicLinkHash(fileId, salt string) string {
return base64.RawURLEncoding.EncodeToString(hash.Sum(nil)) return base64.RawURLEncoding.EncodeToString(hash.Sum(nil))
} }
func (a *App) UploadMultipartFiles(teamId string, channelId string, userId string, fileHeaders []*multipart.FileHeader, clientIds []string) (*model.FileUploadResponse, *model.AppError) { func (a *App) UploadMultipartFiles(teamId string, channelId string, userId string, fileHeaders []*multipart.FileHeader, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) {
files := make([]io.ReadCloser, len(fileHeaders)) files := make([]io.ReadCloser, len(fileHeaders))
filenames := make([]string, len(fileHeaders)) filenames := make([]string, len(fileHeaders))
@@ -338,13 +338,13 @@ func (a *App) UploadMultipartFiles(teamId string, channelId string, userId strin
filenames[i] = fileHeader.Filename filenames[i] = fileHeader.Filename
} }
return a.UploadFiles(teamId, channelId, userId, files, filenames, clientIds) return a.UploadFiles(teamId, channelId, userId, files, filenames, clientIds, now)
} }
// Uploads some files to the given team and channel as the given user. files and filenames should have // Uploads some files to the given team and channel as the given user. files and filenames should have
// the same length. clientIds should either not be provided or have the same length as files and filenames. // the same length. clientIds should either not be provided or have the same length as files and filenames.
// The provided files should be closed by the caller so that they are not leaked. // The provided files should be closed by the caller so that they are not leaked.
func (a *App) UploadFiles(teamId string, channelId string, userId string, files []io.ReadCloser, filenames []string, clientIds []string) (*model.FileUploadResponse, *model.AppError) { func (a *App) UploadFiles(teamId string, channelId string, userId string, files []io.ReadCloser, filenames []string, clientIds []string, now time.Time) (*model.FileUploadResponse, *model.AppError) {
if len(*a.Config().FileSettings.DriverName) == 0 { if len(*a.Config().FileSettings.DriverName) == 0 {
return nil, model.NewAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "", http.StatusNotImplemented) return nil, model.NewAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "", http.StatusNotImplemented)
} }
@@ -367,7 +367,7 @@ func (a *App) UploadFiles(teamId string, channelId string, userId string, files
io.Copy(buf, file) io.Copy(buf, file)
data := buf.Bytes() data := buf.Bytes()
info, data, err := a.DoUploadFileExpectModification(time.Now(), teamId, channelId, userId, filenames[i], data) info, data, err := a.DoUploadFileExpectModification(now, teamId, channelId, userId, filenames[i], data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -417,6 +417,7 @@ func (a *App) DoUploadFileExpectModification(now time.Time, rawTeamId string, ra
info.Id = model.NewId() info.Id = model.NewId()
info.CreatorId = userId info.CreatorId = userId
info.CreateAt = now.UnixNano() / int64(time.Millisecond)
pathPrefix := now.Format("20060102") + "/teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + info.Id + "/" pathPrefix := now.Format("20060102") + "/teams/" + teamId + "/channels/" + channelId + "/users/" + userId + "/" + info.Id + "/"
info.Path = pathPrefix + filename info.Path = pathPrefix + filename

Просмотреть файл

@@ -11,6 +11,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"testing" "testing"
"time"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin" "github.com/mattermost/mattermost-server/plugin"
@@ -352,6 +353,7 @@ func TestHookFileWillBeUploaded(t *testing.T) {
[]io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))}, []io.ReadCloser{ioutil.NopCloser(bytes.NewBufferString("inputfile"))},
[]string{"testhook.txt"}, []string{"testhook.txt"},
[]string{}, []string{},
time.Now(),
) )
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, response) assert.NotNil(t, response)