From 868a83cb655fe4fe2b59103f656d4084ebd5029b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Thu, 20 Dec 2018 23:15:20 -0700 Subject: [PATCH] Update DeleteAccountPipeline job, add db transactions to prevent race conditions --- .../DeletePipeline/DeleteAccountPipeline.php | 175 +++++++----------- 1 file changed, 63 insertions(+), 112 deletions(-) diff --git a/app/Jobs/DeletePipeline/DeleteAccountPipeline.php b/app/Jobs/DeletePipeline/DeleteAccountPipeline.php index 553eaa118..c0d0a6000 100644 --- a/app/Jobs/DeletePipeline/DeleteAccountPipeline.php +++ b/app/Jobs/DeletePipeline/DeleteAccountPipeline.php @@ -7,6 +7,7 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; +use DB; use App\{ AccountLog, Activity, @@ -57,126 +58,76 @@ class DeleteAccountPipeline implements ShouldQueue public function handle() { $user = $this->user; - $this->deleteAccountLogs($user); - $this->deleteActivities($user); - $this->deleteAvatar($user); - $this->deleteBookmarks($user); - $this->deleteEmailVerification($user); - $this->deleteFollowRequests($user); - $this->deleteFollowers($user); - $this->deleteLikes($user); - $this->deleteMedia($user); - $this->deleteMentions($user); - $this->deleteNotifications($user); - $this->deleteStatuses($user); - $this->deleteReports($user); - $this->deleteProfile($user); - $this->deleteUser($user); - - // TODO: send Delete to every known instance sharedInbox - } - - public function deleteAccountLogs($user) - { - AccountLog::chunk(200, function($logs) use ($user) { - foreach($logs as $log) { - if($log->user_id == $user->id) { - $log->forceDelete(); + DB::transaction(function() use ($user) { + AccountLog::chunk(200, function($logs) use ($user) { + foreach($logs as $log) { + if($log->user_id == $user->id) { + $log->forceDelete(); + } } + }); + + if($user->profile) { + $avatar = $user->profile->avatar; + + if(is_file($avatar->media_path)) { + unlink($avatar->media_path); + } + + if(is_file($avatar->thumb_path)) { + unlink($avatar->thumb_path); + } + $avatar->forceDelete(); } + + Bookmark::whereProfileId($user->profile->id)->forceDelete(); + + EmailVerification::whereUserId($user->id)->forceDelete(); + + $id = $user->profile->id; + FollowRequest::whereFollowingId($id)->orWhere('follower_id', $id)->forceDelete(); + + Follower::whereProfileId($id)->orWhere('following_id', $id)->forceDelete(); + + Like::whereProfileId($id)->forceDelete(); + + $medias = Media::whereUserId($user->id)->get(); + foreach($medias as $media) { + $path = $media->media_path; + $thumb = $media->thumbnail_path; + if(is_file($path)) { + unlink($path); + } + if(is_file($thumb)) { + unlink($thumb); + } + $media->forceDelete(); + } + + Mention::whereProfileId($user->profile->id)->forceDelete(); + + Notification::whereProfileId($id)->orWhere('actor_id', $id)->forceDelete(); + + Status::whereProfileId($user->profile->id)->forceDelete(); + + Report::whereUserId($user->id)->forceDelete(); + $this->deleteProfile($user); }); } - public function deleteActivities($user) - { - // deprecated, removed inbox activity logger - } - - public function deleteAvatar($user) - { - $avatar = $user->profile->avatar; - - if(is_file($avatar->media_path)) { - unlink($avatar->media_path); - } - - if(is_file($avatar->thumb_path)) { - unlink($avatar->thumb_path); - } - - $avatar->forceDelete(); - } - - public function deleteBookmarks($user) - { - Bookmark::whereProfileId($user->profile->id)->forceDelete(); - } - - public function deleteEmailVerification($user) - { - EmailVerification::whereUserId($user->id)->forceDelete(); - } - - public function deleteFollowRequests($user) - { - $id = $user->profile->id; - FollowRequest::whereFollowingId($id)->orWhere('follower_id', $id)->forceDelete(); - } - - public function deleteFollowers($user) - { - $id = $user->profile->id; - Follower::whereProfileId($id)->orWhere('following_id', $id)->forceDelete(); - } - - public function deleteLikes($user) - { - $id = $user->profile->id; - Like::whereProfileId($id)->forceDelete(); - } - - public function deleteMedia($user) - { - $medias = Media::whereUserId($user->id)->get(); - foreach($medias as $media) { - $path = $media->media_path; - $thumb = $media->thumbnail_path; - if(is_file($path)) { - unlink($path); - } - if(is_file($thumb)) { - unlink($thumb); - } - $media->forceDelete(); - } - } - - public function deleteMentions($user) - { - Mention::whereProfileId($user->profile->id)->forceDelete(); - } - - public function deleteNotifications($user) - { - $id = $user->profile->id; - Notification::whereProfileId($id)->orWhere('actor_id', $id)->forceDelete(); - } - - public function deleteStatuses($user) { - Status::whereProfileId($user->profile->id)->forceDelete(); - } - public function deleteProfile($user) { - Profile::whereUserId($user->id)->delete(); - } - - public function deleteReports($user) { - Report::whereUserId($user->id)->forceDelete(); + DB::transaction(function() use ($user) { + Profile::whereUserId($user->id)->delete(); + $this->deleteUser($user); + }); } public function deleteUser($user) { - UserFilter::find($user->id)->forceDelete(); - UserSetting::find($user->id)->forceDelete(); - User::find($user->id)->forceDelete(); + + DB::transaction(function() use ($user) { + UserFilter::whereUserId($user->id)->forceDelete(); + UserSetting::whereUserId($user->id)->forceDelete(); + $user->forceDelete(); + }); } }