[MM-56073] MMCTL delete post command (#27539)

Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Этот коммит содержится в:
Ben Cooke
2024-10-08 10:45:31 -04:00
коммит произвёл GitHub
родитель a671f80d2c
Коммит b3c7ef0b97
39 изменённых файлов: 1246 добавлений и 152 удалений

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

@@ -491,6 +491,7 @@ type AppIface interface {
CheckUserPostflightAuthenticationCriteria(rctx request.CTX, user *model.User) *model.AppError
CheckUserPreflightAuthenticationCriteria(rctx request.CTX, user *model.User, mfaToken string) *model.AppError
CheckWebConn(userID, connectionID string) *platform.CheckConnResult
CleanUpAfterPostDeletion(c request.CTX, post *model.Post, deleteByID string) *model.AppError
CleanupReportChunks(format string, prefix string, numberOfChunks int) *model.AppError
ClearChannelMembersCache(c request.CTX, channelID string) error
ClearLatestVersionCache(rctx request.CTX)
@@ -579,7 +580,7 @@ type AppIface interface {
DeleteOAuthApp(rctx request.CTX, appID string) *model.AppError
DeleteOutgoingWebhook(hookID string) *model.AppError
DeletePluginKey(pluginID string, key string) *model.AppError
DeletePost(c request.CTX, postID, deleteByID string) (*model.Post, *model.AppError)
DeletePost(rctx request.CTX, postID, deleteByID string) (*model.Post, *model.AppError)
DeletePreferences(c request.CTX, userID string, preferences model.Preferences) *model.AppError
DeleteReactionForPost(c request.CTX, reaction *model.Reaction) *model.AppError
DeleteRemoteCluster(remoteClusterId string) (bool, *model.AppError)
@@ -986,9 +987,11 @@ type AppIface interface {
PatchUser(c request.CTX, userID string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError)
PermanentDeleteAllUsers(c request.CTX) *model.AppError
PermanentDeleteChannel(c request.CTX, channel *model.Channel) *model.AppError
PermanentDeleteFilesByPost(rctx request.CTX, postID string) *model.AppError
PermanentDeletePost(rctx request.CTX, postID, deleteByID string) *model.AppError
PermanentDeleteTeam(c request.CTX, team *model.Team) *model.AppError
PermanentDeleteTeamId(c request.CTX, teamID string) *model.AppError
PermanentDeleteUser(c request.CTX, user *model.User) *model.AppError
PermanentDeleteUser(rctx request.CTX, user *model.User) *model.AppError
PostActionCookieSecret() []byte
PostAddToChannelMessage(c request.CTX, user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError
PostPatchWithProxyRemovedFromImageURLs(patch *model.PostPatch) *model.PostPatch
@@ -1022,6 +1025,8 @@ type AppIface interface {
RemoveDirectory(path string) *model.AppError
RemoveExportFile(path string) *model.AppError
RemoveFile(path string) *model.AppError
RemoveFileFromFileStore(rctx request.CTX, path string)
RemoveFilesFromFileStore(rctx request.CTX, fileInfos []*model.FileInfo)
RemoveLdapPrivateCertificate() *model.AppError
RemoveLdapPublicCertificate() *model.AppError
RemoveNotifications(c request.CTX, post *model.Post, channel *model.Channel) error

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

@@ -1594,3 +1594,65 @@ func getFileExtFromMimeType(mimeType string) string {
}
return "jpg"
}
func (a *App) PermanentDeleteFilesByPost(rctx request.CTX, postID string) *model.AppError {
fileInfos, err := a.Srv().Store().FileInfo().GetForPost(postID, false, true, true)
if err != nil {
return model.NewAppError("PermanentDeleteFilesByPost", "app.file_info.get_by_post_id.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
if len(fileInfos) == 0 {
rctx.Logger().Debug("No files found for post", mlog.String("post_id", postID))
return nil
}
a.RemoveFilesFromFileStore(rctx, fileInfos)
err = a.Srv().Store().FileInfo().PermanentDeleteForPost(rctx, postID)
if err != nil {
return model.NewAppError("PermanentDeleteFilesByPost", "app.file_info.permanent_delete_for_post.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
a.Srv().Store().FileInfo().InvalidateFileInfosForPostCache(postID, true)
a.Srv().Store().FileInfo().InvalidateFileInfosForPostCache(postID, false)
return nil
}
func (a *App) RemoveFilesFromFileStore(rctx request.CTX, fileInfos []*model.FileInfo) {
for _, info := range fileInfos {
a.RemoveFileFromFileStore(rctx, info.Path)
if info.PreviewPath != "" {
a.RemoveFileFromFileStore(rctx, info.PreviewPath)
}
if info.ThumbnailPath != "" {
a.RemoveFileFromFileStore(rctx, info.ThumbnailPath)
}
}
}
func (a *App) RemoveFileFromFileStore(rctx request.CTX, path string) {
res, appErr := a.FileExists(path)
if appErr != nil {
rctx.Logger().Warn(
"Error checking existence of file",
mlog.String("path", path),
mlog.Err(appErr),
)
return
}
if !res {
rctx.Logger().Warn("File not found", mlog.String("path", path))
return
}
appErr = a.RemoveFile(path)
if appErr != nil {
rctx.Logger().Warn(
"Unable to remove file",
mlog.String("path", path),
mlog.Err(appErr),
)
return
}
}

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

@@ -730,3 +730,59 @@ func TestSetFileSearchableContent(t *testing.T) {
require.Nil(t, appErr)
assert.Equal(t, 1, len(result.Order))
}
func TestPermanentDeleteFilesByPost(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
t.Run("should delete files for post", func(t *testing.T) {
// Create a post with a file attachment.
teamID := th.BasicTeam.Id
channelID := th.BasicChannel.Id
userID := th.BasicUser.Id
filename := "test"
data := []byte("abcd")
info1, err := th.App.DoUploadFile(th.Context, time.Date(2007, 2, 4, 1, 2, 3, 4, time.Local), teamID, channelID, userID, filename, data, true)
require.Nil(t, err)
post := &model.Post{
Message: "asd",
ChannelId: channelID,
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
UserId: userID,
CreateAt: 0,
FileIds: []string{info1.Id},
}
post, err = th.App.CreatePost(th.Context, post, th.BasicChannel, false, true)
assert.Nil(t, err)
err = th.App.PermanentDeleteFilesByPost(th.Context, post.Id)
require.Nil(t, err)
_, err = th.App.GetFileInfo(th.Context, info1.Id)
require.NotNil(t, err)
})
t.Run("should not delete files for post that doesn't exist", func(t *testing.T) {
err := th.App.PermanentDeleteFilesByPost(th.Context, "postId1")
assert.Nil(t, err)
})
t.Run("should handle empty file list", func(t *testing.T) {
post := &model.Post{
Message: "asd",
ChannelId: th.BasicChannel.Id,
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
UserId: th.BasicUser.Id,
CreateAt: 0,
}
post, err := th.App.CreatePost(th.Context, post, th.BasicChannel, false, true)
assert.Nil(t, err)
err = th.App.PermanentDeleteFilesByPost(th.Context, post.Id)
assert.Nil(t, err)
})
}

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

@@ -1455,6 +1455,28 @@ func (a *OpenTracingAppLayer) CheckWebConn(userID string, connectionID string) *
return resultVar0
}
func (a *OpenTracingAppLayer) CleanUpAfterPostDeletion(c request.CTX, post *model.Post, deleteByID string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CleanUpAfterPostDeletion")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.CleanUpAfterPostDeletion(c, post, deleteByID)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) CleanupReportChunks(format string, prefix string, numberOfChunks int) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.CleanupReportChunks")
@@ -3588,7 +3610,7 @@ func (a *OpenTracingAppLayer) DeletePluginKey(pluginID string, key string) *mode
return resultVar0
}
func (a *OpenTracingAppLayer) DeletePost(c request.CTX, postID string, deleteByID string) (*model.Post, *model.AppError) {
func (a *OpenTracingAppLayer) DeletePost(rctx request.CTX, postID string, deleteByID string) (*model.Post, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.DeletePost")
@@ -3600,7 +3622,7 @@ func (a *OpenTracingAppLayer) DeletePost(c request.CTX, postID string, deleteByI
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.DeletePost(c, postID, deleteByID)
resultVar0, resultVar1 := a.app.DeletePost(rctx, postID, deleteByID)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))
@@ -13618,6 +13640,50 @@ func (a *OpenTracingAppLayer) PermanentDeleteChannel(c request.CTX, channel *mod
return resultVar0
}
func (a *OpenTracingAppLayer) PermanentDeleteFilesByPost(rctx request.CTX, postID string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PermanentDeleteFilesByPost")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.PermanentDeleteFilesByPost(rctx, postID)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) PermanentDeletePost(rctx request.CTX, postID string, deleteByID string) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PermanentDeletePost")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
resultVar0 := a.app.PermanentDeletePost(rctx, postID, deleteByID)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
ext.Error.Set(span, true)
}
return resultVar0
}
func (a *OpenTracingAppLayer) PermanentDeleteTeam(c request.CTX, team *model.Team) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PermanentDeleteTeam")
@@ -13662,7 +13728,7 @@ func (a *OpenTracingAppLayer) PermanentDeleteTeamId(c request.CTX, teamID string
return resultVar0
}
func (a *OpenTracingAppLayer) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppError {
func (a *OpenTracingAppLayer) PermanentDeleteUser(rctx request.CTX, user *model.User) *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.PermanentDeleteUser")
@@ -13674,7 +13740,7 @@ func (a *OpenTracingAppLayer) PermanentDeleteUser(c request.CTX, user *model.Use
}()
defer span.Finish()
resultVar0 := a.app.PermanentDeleteUser(c, user)
resultVar0 := a.app.PermanentDeleteUser(rctx, user)
if resultVar0 != nil {
span.LogFields(spanlog.Error(resultVar0))
@@ -14454,6 +14520,36 @@ func (a *OpenTracingAppLayer) RemoveFile(path string) *model.AppError {
return resultVar0
}
func (a *OpenTracingAppLayer) RemoveFileFromFileStore(rctx request.CTX, path string) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RemoveFileFromFileStore")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
a.app.RemoveFileFromFileStore(rctx, path)
}
func (a *OpenTracingAppLayer) RemoveFilesFromFileStore(rctx request.CTX, fileInfos []*model.FileInfo) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RemoveFilesFromFileStore")
a.ctx = newCtx
a.app.Srv().Store().SetContext(newCtx)
defer func() {
a.app.Srv().Store().SetContext(origCtx)
a.ctx = origCtx
}()
defer span.Finish()
a.app.RemoveFilesFromFileStore(rctx, fileInfos)
}
func (a *OpenTracingAppLayer) RemoveLdapPrivateCertificate() *model.AppError {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.RemoveLdapPrivateCertificate")

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

@@ -1361,23 +1361,22 @@ func (a *App) GetPostsForChannelAroundLastUnread(c request.CTX, channelID, userI
return postList, nil
}
func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post, *model.AppError) {
post, err := a.Srv().Store().Post().GetSingle(sqlstore.RequestContextWithMaster(c), postID, false)
func (a *App) DeletePost(rctx request.CTX, postID, deleteByID string) (*model.Post, *model.AppError) {
post, err := a.Srv().Store().Post().GetSingle(sqlstore.RequestContextWithMaster(rctx), postID, false)
if err != nil {
return nil, model.NewAppError("DeletePost", "app.post.get.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
channel, appErr := a.GetChannel(c, post.ChannelId)
channel, appErr := a.GetChannel(rctx, post.ChannelId)
if appErr != nil {
return nil, appErr
}
if channel.DeleteAt != 0 {
appErr := model.NewAppError("DeletePost", "api.post.delete_post.can_not_delete_post_in_deleted.error", nil, "", http.StatusBadRequest)
return nil, appErr
return nil, model.NewAppError("DeletePost", "api.post.delete_post.can_not_delete_post_in_deleted.error", nil, "", http.StatusBadRequest)
}
err = a.Srv().Store().Post().Delete(c, postID, model.GetMillis(), deleteByID)
err = a.Srv().Store().Post().Delete(rctx, postID, model.GetMillis(), deleteByID)
if err != nil {
var nfErr *store.ErrNotFound
switch {
@@ -1388,60 +1387,18 @@ func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post,
}
}
if post.RootId == "" {
if appErr := a.DeletePersistentNotification(c, post); appErr != nil {
return nil, appErr
}
}
postJSON, err := json.Marshal(post)
if err != nil {
return nil, model.NewAppError("DeletePost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
userMessage := model.NewWebSocketEvent(model.WebsocketEventPostDeleted, "", post.ChannelId, "", nil, "")
userMessage.Add("post", string(postJSON))
userMessage.GetBroadcast().ContainsSanitizedData = true
a.Publish(userMessage)
adminMessage := model.NewWebSocketEvent(model.WebsocketEventPostDeleted, "", post.ChannelId, "", nil, "")
adminMessage.Add("post", string(postJSON))
adminMessage.Add("delete_by", deleteByID)
adminMessage.GetBroadcast().ContainsSensitiveData = true
a.Publish(adminMessage)
if len(post.FileIds) > 0 {
a.Srv().Go(func() {
a.deletePostFiles(c, post.Id)
a.deletePostFiles(rctx, post.Id)
})
a.Srv().Store().FileInfo().InvalidateFileInfosForPostCache(postID, true)
a.Srv().Store().FileInfo().InvalidateFileInfosForPostCache(postID, false)
}
a.Srv().Go(func() {
a.deleteFlaggedPosts(c, post.Id)
})
pluginPost := post.ForPlugin()
pluginContext := pluginContext(c)
a.Srv().Go(func() {
a.ch.RunMultiHook(func(hooks plugin.Hooks) bool {
hooks.MessageHasBeenDeleted(pluginContext, pluginPost)
return true
}, plugin.MessageHasBeenDeletedID)
})
a.Srv().Go(func() {
if err = a.RemoveNotifications(c, post, channel); err != nil {
c.Logger().Error("DeletePost failed to delete notification", mlog.Err(err))
}
})
// delete drafts associated with the post when deleting the post
a.Srv().Go(func() {
a.deleteDraftsAssociatedWithPost(c, channel, post)
})
a.invalidateCacheForChannelPosts(post.ChannelId)
appErr = a.CleanUpAfterPostDeletion(rctx, post, deleteByID)
if appErr != nil {
return nil, appErr
}
return post, nil
}
@@ -2646,3 +2603,86 @@ func (a *App) MoveThread(c request.CTX, postID string, sourceChannelID, channelI
c.Logger().Info(msg)
return nil
}
func (a *App) PermanentDeletePost(rctx request.CTX, postID, deleteByID string) *model.AppError {
post, err := a.Srv().Store().Post().GetSingle(sqlstore.RequestContextWithMaster(rctx), postID, true)
if err != nil {
return model.NewAppError("DeletePost", "app.post.get.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if len(post.FileIds) > 0 {
appErr := a.PermanentDeleteFilesByPost(rctx, post.Id)
if appErr != nil {
return appErr
}
}
err = a.Srv().Store().Post().PermanentDelete(rctx, post.Id)
if err != nil {
return model.NewAppError("PermanentDeletePost", "app.post.permanent_delete_post.error", nil, "", http.StatusInternalServerError).Wrap(err)
}
appErr := a.CleanUpAfterPostDeletion(rctx, post, deleteByID)
if appErr != nil {
return appErr
}
return nil
}
func (a *App) CleanUpAfterPostDeletion(c request.CTX, post *model.Post, deleteByID string) *model.AppError {
channel, appErr := a.GetChannel(c, post.ChannelId)
if appErr != nil {
return appErr
}
if post.RootId == "" {
if appErr := a.DeletePersistentNotification(c, post); appErr != nil {
return appErr
}
}
postJSON, err := json.Marshal(post)
if err != nil {
return model.NewAppError("DeletePost", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
userMessage := model.NewWebSocketEvent(model.WebsocketEventPostDeleted, "", post.ChannelId, "", nil, "")
userMessage.Add("post", string(postJSON))
userMessage.GetBroadcast().ContainsSanitizedData = true
a.Publish(userMessage)
adminMessage := model.NewWebSocketEvent(model.WebsocketEventPostDeleted, "", post.ChannelId, "", nil, "")
adminMessage.Add("post", string(postJSON))
adminMessage.Add("delete_by", deleteByID)
adminMessage.GetBroadcast().ContainsSensitiveData = true
a.Publish(adminMessage)
a.Srv().Go(func() {
a.deleteFlaggedPosts(c, post.Id)
})
pluginPost := post.ForPlugin()
pluginContext := pluginContext(c)
a.Srv().Go(func() {
a.ch.RunMultiHook(func(hooks plugin.Hooks) bool {
hooks.MessageHasBeenDeleted(pluginContext, pluginPost)
return true
}, plugin.MessageHasBeenDeletedID)
})
a.Srv().Go(func() {
if err = a.RemoveNotifications(c, post, channel); err != nil {
c.Logger().Error("DeletePost failed to delete notification", mlog.Err(err))
}
})
// delete drafts associated with the post when deleting the post
a.Srv().Go(func() {
a.deleteDraftsAssociatedWithPost(c, channel, post)
})
a.invalidateCacheForChannelPosts(post.ChannelId)
return nil
}

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

@@ -3569,3 +3569,94 @@ func TestValidateMoveOrCopy(t *testing.T) {
require.Equal(t, "the thread is 2 posts long, but this command is configured to only move threads of up to 1 posts", e.Error())
})
}
func TestPermanentDeletePost(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
t.Run("should permanently delete a post and its file attachment", func(t *testing.T) {
// Create a post with a file attachment.
teamID := th.BasicTeam.Id
channelID := th.BasicChannel.Id
userID := th.BasicUser.Id
filename := "test"
data := []byte("abcd")
info1, err := th.App.DoUploadFile(th.Context, time.Date(2007, 2, 4, 1, 2, 3, 4, time.Local), teamID, channelID, userID, filename, data, true)
assert.Nil(t, err)
post := &model.Post{
Message: "asd",
ChannelId: channelID,
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
UserId: userID,
CreateAt: 0,
FileIds: []string{info1.Id},
}
post, err = th.App.CreatePost(th.Context, post, th.BasicChannel, false, true)
assert.Nil(t, err)
// Delete the post.
err = th.App.PermanentDeletePost(th.Context, post.Id, userID)
assert.Nil(t, err)
// Wait for the cleanup routine to finish.
time.Sleep(time.Millisecond * 100)
// Check that the post can no longer be reached.
_, err = th.App.GetSinglePost(th.Context, post.Id, true)
assert.NotNil(t, err)
// Check that the file can no longer be reached.
_, err = th.App.GetFileInfo(th.Context, info1.Id)
assert.NotNil(t, err)
})
t.Run("should permanently delete a post that is soft deleted", func(t *testing.T) {
// Create a post with a file attachment.
teamID := th.BasicTeam.Id
channelID := th.BasicChannel.Id
userID := th.BasicUser.Id
filename := "test"
data := []byte("abcd")
info1, err := th.App.DoUploadFile(th.Context, time.Date(2007, 2, 4, 1, 2, 3, 4, time.Local), teamID, channelID, userID, filename, data, true)
require.Nil(t, err)
post := &model.Post{
Message: "asd",
ChannelId: channelID,
PendingPostId: model.NewId() + ":" + fmt.Sprint(model.GetMillis()),
UserId: userID,
CreateAt: 0,
FileIds: []string{info1.Id},
}
post, err = th.App.CreatePost(th.Context, post, th.BasicChannel, false, true)
assert.Nil(t, err)
infos, sErr := th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, true, false)
require.NoError(t, sErr)
assert.Len(t, infos, 1)
// Soft delete the post.
_, err = th.App.DeletePost(th.Context, post.Id, userID)
assert.Nil(t, err)
// Wait for the cleanup routine to finish.
time.Sleep(time.Millisecond * 100)
// Delete the post.
err = th.App.PermanentDeletePost(th.Context, post.Id, userID)
assert.Nil(t, err)
// Check that the post can no longer be reached.
_, err = th.App.GetSinglePost(th.Context, post.Id, true)
assert.NotNil(t, err)
infos, sErr = th.App.Srv().Store().FileInfo().GetForPost(post.Id, true, true, false)
require.NoError(t, sErr)
assert.Len(t, infos, 0)
})
}

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

@@ -1759,13 +1759,13 @@ func (a *App) UpdateUserRolesWithUser(c request.CTX, user *model.User, newRoles
return ruser, nil
}
func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppError {
c.Logger().Warn("Attempting to permanently delete account", mlog.String("user_id", user.Id), mlog.String("user_email", user.Email))
func (a *App) PermanentDeleteUser(rctx request.CTX, user *model.User) *model.AppError {
rctx.Logger().Warn("Attempting to permanently delete account", mlog.String("user_id", user.Id), mlog.String("user_email", user.Email))
if user.IsInRole(model.SystemAdminRoleId) {
c.Logger().Warn("You are deleting a user that is a system administrator. You may need to set another account as the system administrator using the command line tools.", mlog.String("user_email", user.Email))
rctx.Logger().Warn("You are deleting a user that is a system administrator. You may need to set another account as the system administrator using the command line tools.", mlog.String("user_email", user.Email))
}
if _, err := a.UpdateActive(c, user, false); err != nil {
if _, err := a.UpdateActive(rctx, user, false); err != nil {
return err
}
@@ -1797,7 +1797,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
return model.NewAppError("PermanentDeleteUser", "app.preference.permanent_delete_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
if err := a.Srv().Store().Channel().PermanentDeleteMembersByUser(c, user.Id); err != nil {
if err := a.Srv().Store().Channel().PermanentDeleteMembersByUser(rctx, user.Id); err != nil {
return model.NewAppError("PermanentDeleteUser", "app.channel.permanent_delete_members_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
@@ -1805,7 +1805,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
return model.NewAppError("PermanentDeleteUser", "app.group.permanent_delete_members_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
if err := a.Srv().Store().Post().PermanentDeleteByUser(c, user.Id); err != nil {
if err := a.Srv().Store().Post().PermanentDeleteByUser(rctx, user.Id); err != nil {
return model.NewAppError("PermanentDeleteUser", "app.post.permanent_delete_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
@@ -1825,35 +1825,10 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
infos, err := a.Srv().Store().FileInfo().GetForUser(user.Id)
if err != nil {
c.Logger().Warn("Error getting file list for user from FileInfoStore", mlog.Err(err))
rctx.Logger().Warn("Error getting file list for user from FileInfoStore", mlog.Err(err))
}
for _, info := range infos {
res, err := a.FileExists(info.Path)
if err != nil {
c.Logger().Warn(
"Error checking existence of file",
mlog.String("path", info.Path),
mlog.Err(err),
)
continue
}
if !res {
c.Logger().Warn("File not found", mlog.String("path", info.Path))
continue
}
err = a.RemoveFile(info.Path)
if err != nil {
c.Logger().Warn(
"Unable to remove file",
mlog.String("path", info.Path),
mlog.Err(err),
)
}
}
a.RemoveFilesFromFileStore(rctx, infos)
// delete directory containing user's profile image
profileImageDirectory := getProfileImageDirectory(user.Id)
@@ -1864,7 +1839,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
if errProfileImageExists != nil {
fileHandlingErrorsFound = true
c.Logger().Warn(
rctx.Logger().Warn(
"Error checking existence of profile image.",
mlog.String("path", profileImagePath),
mlog.Err(errProfileImageExists),
@@ -1876,7 +1851,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
if errRemoveDirectory != nil {
fileHandlingErrorsFound = true
c.Logger().Warn(
rctx.Logger().Warn(
"Unable to remove profile image directory",
mlog.String("path", profileImageDirectory),
mlog.Err(errRemoveDirectory),
@@ -1884,11 +1859,11 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
}
}
if _, err := a.Srv().Store().FileInfo().PermanentDeleteByUser(c, user.Id); err != nil {
if _, err := a.Srv().Store().FileInfo().PermanentDeleteByUser(rctx, user.Id); err != nil {
return model.NewAppError("PermanentDeleteUser", "app.file_info.permanent_delete_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
if err := a.Srv().Store().User().PermanentDelete(c, user.Id); err != nil {
if err := a.Srv().Store().User().PermanentDelete(rctx, user.Id); err != nil {
return model.NewAppError("PermanentDeleteUser", "app.user.permanent_delete.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
@@ -1896,7 +1871,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
return model.NewAppError("PermanentDeleteUser", "app.audit.permanent_delete_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
if err := a.Srv().Store().Team().RemoveAllMembersByUser(c, user.Id); err != nil {
if err := a.Srv().Store().Team().RemoveAllMembersByUser(rctx, user.Id); err != nil {
return model.NewAppError("PermanentDeleteUser", "app.team.remove_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
@@ -1906,7 +1881,7 @@ func (a *App) PermanentDeleteUser(c request.CTX, user *model.User) *model.AppErr
return model.NewAppError("PermanentDeleteUser", "app.file_info.permanent_delete_by_user.app_error", nil, "Couldn't delete profile image of the user.", http.StatusAccepted)
}
c.Logger().Warn("Permanently deleted account", mlog.String("user_email", user.Email), mlog.String("user_id", user.Id))
rctx.Logger().Warn("Permanently deleted account", mlog.String("user_email", user.Email), mlog.String("user_id", user.Id))
return nil
}