diff --git a/app/user.go b/app/user.go index 37caba1891..2a70c3c0a5 100644 --- a/app/user.go +++ b/app/user.go @@ -1627,6 +1627,35 @@ func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.A } } + // delete directory containing user's profile image + profileImageDirectory := getProfileImageDirectory(user.Id) + profileImagePath := getProfileImagePath(user.Id) + resProfileImageExists, errProfileImageExists := a.FileExists(profileImagePath) + + fileHandlingErrorsFound := false + + if errProfileImageExists != nil { + fileHandlingErrorsFound = true + mlog.Warn( + "Error checking existence of profile image.", + mlog.String("path", profileImagePath), + mlog.Err(errProfileImageExists), + ) + } + + if resProfileImageExists { + errRemoveDirectory := a.RemoveDirectory(profileImageDirectory) + + if errRemoveDirectory != nil { + fileHandlingErrorsFound = true + mlog.Warn( + "Unable to remove profile image directory", + mlog.String("path", profileImageDirectory), + mlog.Err(errRemoveDirectory), + ) + } + } + if _, err := a.Srv().Store.FileInfo().PermanentDeleteByUser(user.Id); err != nil { return model.NewAppError("PermanentDeleteUser", "app.file_info.permanent_delete_by_user.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } @@ -1643,6 +1672,12 @@ func (a *App) PermanentDeleteUser(c *request.Context, user *model.User) *model.A return model.NewAppError("PermanentDeleteUser", "app.team.remove_member.app_error", nil, "", http.StatusInternalServerError).Wrap(err) } + a.InvalidateCacheForUser(user.Id) + + if fileHandlingErrorsFound { + 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)) return nil @@ -2612,3 +2647,7 @@ func (a *App) GetUsersWithInvalidEmails(page int, perPage int) ([]*model.User, * func getProfileImagePath(userID string) string { return filepath.Join("users", userID, "profile.png") } + +func getProfileImageDirectory(userID string) string { + return filepath.Join("users", userID) +} diff --git a/app/user_test.go b/app/user_test.go index 75d5fa80f3..d485b51bd4 100644 --- a/app/user_test.go +++ b/app/user_test.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "os" + "path/filepath" "strings" "testing" "time" @@ -1036,6 +1037,12 @@ func TestPermanentDeleteUser(t *testing.T) { require.Nil(t, err, "Unable to upload file. err=%v", err) + // upload profile image + user := th.BasicUser + + err = th.App.SetDefaultProfileImage(th.Context, user) + require.Nil(t, err) + bot, err := th.App.CreateBot(th.Context, &model.Bot{ Username: "botname", Description: "a bot", @@ -1076,6 +1083,11 @@ func TestPermanentDeleteUser(t *testing.T) { require.Nil(t, finfo, "Unable to find finfo. err=%v", err) require.NotNil(t, err, "GetFileInfo after DeleteUser is nil. err=%v", err) + + // test deletion of profile picture + exists, err := th.App.FileExists(filepath.Join("users", user.Id)) + require.Nil(t, err, "Unable to stat finfo. err=%v", err) + require.False(t, exists, "Profile image wasn't deleted. err=%v", err) } func TestPasswordRecovery(t *testing.T) {