[MM-42194] Get file information from a deleted post (#20279)

* Introduced inlcude_deleted query parameter to allow admins to retrieve contents of post regardless of deletion status

* Introduced new client route and tests for getting file info of deleted posts

* Fixed tests due to caching of posts

* gofmt

* Small formatting updates

* Invalidating file infos cache on delete of post if post includes files

* Including deleted in migration flow

* Moved invalidating of cache

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Riccardo Santoni
2022-07-21 17:11:08 +02:00
коммит произвёл GitHub
родитель bc7f961d75
Коммит 3d7859396d
9 изменённых файлов: 75 добавлений и 16 удалений

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

@@ -898,7 +898,13 @@ func getFileInfosForPost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
infos, err := c.App.GetFileInfosForPostWithMigration(c.Params.PostId)
includeDeleted, _ := strconv.ParseBool(r.URL.Query().Get("include_deleted"))
if includeDeleted && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) {
c.SetPermissionError(model.PermissionManageSystem)
return
}
infos, err := c.App.GetFileInfosForPostWithMigration(c.Params.PostId, includeDeleted)
if err != nil {
c.Err = err
return

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

@@ -2623,6 +2623,39 @@ func TestGetFileInfosForPost(t *testing.T) {
require.Error(t, err)
CheckForbiddenStatus(t, resp)
// Delete post
th.SystemAdminClient.DeletePost(post.Id)
// Normal client should get 404 when trying to access deleted post normally
_, resp, err = client.GetFileInfosForPost(post.Id, "")
require.Error(t, err)
CheckNotFoundStatus(t, resp)
// Normal client should get unauthorized when trying to access deleted post
_, resp, err = client.GetFileInfosForPostIncludeDeleted(post.Id, "")
require.Error(t, err)
CheckForbiddenStatus(t, resp)
// System client should get 404 when trying to access deleted post normally
_, resp, err = th.SystemAdminClient.GetFileInfosForPost(post.Id, "")
require.Error(t, err)
CheckNotFoundStatus(t, resp)
// System client should be able to access deleted post with include_deleted param
infos, _, err = th.SystemAdminClient.GetFileInfosForPostIncludeDeleted(post.Id, "")
require.NoError(t, err)
require.Len(t, infos, 3, "missing file infos")
found = false
for _, info := range infos {
if info.Id == fileIds[0] {
found = true
}
}
require.True(t, found, "missing file info")
client.Logout()
_, resp, err = client.GetFileInfosForPost(model.NewId(), "")
require.Error(t, err)

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

@@ -630,8 +630,8 @@ type AppIface interface {
GetFile(fileID string) ([]byte, *model.AppError)
GetFileInfo(fileID string) (*model.FileInfo, *model.AppError)
GetFileInfos(page, perPage int, opt *model.GetFileInfosOptions) ([]*model.FileInfo, *model.AppError)
GetFileInfosForPost(postID string, fromMaster bool) ([]*model.FileInfo, *model.AppError)
GetFileInfosForPostWithMigration(postID string) ([]*model.FileInfo, *model.AppError)
GetFileInfosForPost(postID string, fromMaster bool, includeDeleted bool) ([]*model.FileInfo, *model.AppError)
GetFileInfosForPostWithMigration(postID string, includeDeleted bool) ([]*model.FileInfo, *model.AppError)
GetFlaggedPosts(userID string, offset int, limit int) (*model.PostList, *model.AppError)
GetFlaggedPostsForChannel(userID, channelID string, offset int, limit int) (*model.PostList, *model.AppError)
GetFlaggedPostsForTeam(userID, teamID string, offset int, limit int) (*model.PostList, *model.AppError)

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

@@ -1224,7 +1224,7 @@ func (a *App) importAttachment(c *request.Context, data *AttachmentImportData, p
// Go over existing files in the post and see if there already exists a file with the same name, size and hash. If so - skip it
if post.Id != "" {
oldFiles, err := a.GetFileInfosForPost(post.Id, true)
oldFiles, err := a.GetFileInfosForPost(post.Id, true, false)
if err != nil {
return nil, model.NewAppError("BulkImport", "app.import.attachment.file_upload.error", map[string]any{"FilePath": *data.Path}, "", http.StatusBadRequest)
}

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

@@ -5970,7 +5970,7 @@ func (a *OpenTracingAppLayer) GetFileInfos(page int, perPage int, opt *model.Get
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetFileInfosForPost(postID string, fromMaster bool) ([]*model.FileInfo, *model.AppError) {
func (a *OpenTracingAppLayer) GetFileInfosForPost(postID string, fromMaster bool, includeDeleted bool) ([]*model.FileInfo, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetFileInfosForPost")
@@ -5982,7 +5982,7 @@ func (a *OpenTracingAppLayer) GetFileInfosForPost(postID string, fromMaster bool
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetFileInfosForPost(postID, fromMaster)
resultVar0, resultVar1 := a.app.GetFileInfosForPost(postID, fromMaster, includeDeleted)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
@@ -5992,7 +5992,7 @@ func (a *OpenTracingAppLayer) GetFileInfosForPost(postID string, fromMaster bool
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetFileInfosForPostWithMigration(postID string) ([]*model.FileInfo, *model.AppError) {
func (a *OpenTracingAppLayer) GetFileInfosForPostWithMigration(postID string, includeDeleted bool) ([]*model.FileInfo, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetFileInfosForPostWithMigration")
@@ -6004,7 +6004,7 @@ func (a *OpenTracingAppLayer) GetFileInfosForPostWithMigration(postID string) ([
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetFileInfosForPostWithMigration(postID)
resultVar0, resultVar1 := a.app.GetFileInfosForPostWithMigration(postID, includeDeleted)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))

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

@@ -1269,6 +1269,8 @@ func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post,
a.Srv().Go(func() {
a.deletePostFiles(post.Id)
})
a.Srv().Store.FileInfo().InvalidateFileInfosForPostCache(postID, true)
a.Srv().Store.FileInfo().InvalidateFileInfosForPostCache(postID, false)
}
a.Srv().Go(func() {
a.deleteFlaggedPosts(post.Id)
@@ -1541,16 +1543,16 @@ func (a *App) GetRecentSearchesForUser(userID string) ([]*model.SearchParams, *m
return searchParams, nil
}
func (a *App) GetFileInfosForPostWithMigration(postID string) ([]*model.FileInfo, *model.AppError) {
func (a *App) GetFileInfosForPostWithMigration(postID string, includeDeleted bool) ([]*model.FileInfo, *model.AppError) {
pchan := make(chan store.StoreResult, 1)
go func() {
post, err := a.Srv().Store.Post().GetSingle(postID, false)
post, err := a.Srv().Store.Post().GetSingle(postID, includeDeleted)
pchan <- store.StoreResult{Data: post, NErr: err}
close(pchan)
}()
infos, err := a.GetFileInfosForPost(postID, false)
infos, err := a.GetFileInfosForPost(postID, false, includeDeleted)
if err != nil {
return nil, err
}
@@ -1580,8 +1582,8 @@ func (a *App) GetFileInfosForPostWithMigration(postID string) ([]*model.FileInfo
return infos, nil
}
func (a *App) GetFileInfosForPost(postID string, fromMaster bool) ([]*model.FileInfo, *model.AppError) {
fileInfos, err := a.Srv().Store.FileInfo().GetForPost(postID, fromMaster, false, true)
func (a *App) GetFileInfosForPost(postID string, fromMaster bool, includeDeleted bool) ([]*model.FileInfo, *model.AppError) {
fileInfos, err := a.Srv().Store.FileInfo().GetForPost(postID, fromMaster, includeDeleted, true)
if err != nil {
return nil, model.NewAppError("GetFileInfosForPost", "app.file_info.get_for_post.app_error", nil, err.Error(), http.StatusInternalServerError)
}

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

@@ -216,7 +216,7 @@ func (a *App) getFileMetadataForPost(post *model.Post, fromMaster bool) ([]*mode
return nil, nil
}
return a.GetFileInfosForPost(post.Id, fromMaster)
return a.GetFileInfosForPost(post.Id, fromMaster, false)
}
func (a *App) getEmojisAndReactionsForPost(post *model.Post) ([]*model.Emoji, []*model.Reaction, *model.AppError) {

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

@@ -219,7 +219,7 @@ func TestAttachFilesToPost(t *testing.T) {
appErr := th.App.attachFilesToPost(post)
assert.Nil(t, appErr)
infos, appErr := th.App.GetFileInfosForPost(post.Id, false)
infos, appErr := th.App.GetFileInfosForPost(post.Id, false, false)
assert.Nil(t, appErr)
assert.Len(t, infos, 2)
})
@@ -247,7 +247,7 @@ func TestAttachFilesToPost(t *testing.T) {
appErr := th.App.attachFilesToPost(post)
assert.Nil(t, appErr)
infos, appErr := th.App.GetFileInfosForPost(post.Id, false)
infos, appErr := th.App.GetFileInfosForPost(post.Id, false, false)
assert.Nil(t, appErr)
assert.Len(t, infos, 1)
assert.Equal(t, info2.Id, infos[0].Id)

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

@@ -4419,6 +4419,24 @@ func (c *Client4) GetFileInfosForPost(postId string, etag string) ([]*FileInfo,
return list, BuildResponse(r), nil
}
// GetFileInfosForPost gets all the file info objects attached to a post, including deleted
func (c *Client4) GetFileInfosForPostIncludeDeleted(postId string, etag string) ([]*FileInfo, *Response, error) {
r, err := c.DoAPIGet(c.postRoute(postId)+"/files/info"+"?include_deleted="+c.boolString(true), etag)
if err != nil {
return nil, BuildResponse(r), err
}
defer closeBody(r)
var list []*FileInfo
if r.StatusCode == http.StatusNotModified {
return list, BuildResponse(r), nil
}
if jsonErr := json.NewDecoder(r.Body).Decode(&list); jsonErr != nil {
return nil, nil, NewAppError("GetFileInfosForPostIncludeDeleted", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
}
return list, BuildResponse(r), nil
}
// General/System Section
// GenerateSupportPacket downloads the generated support packet