-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2366 from codeeu/transmission-personal-data
Transmission personal data
- Loading branch information
Showing
5 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
namespace App\Console\Commands; | ||
|
||
use App\Jobs\ProcessUserDeletion; | ||
use App\User; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\Hash; | ||
|
||
class SoftDeleteUsersWithoutConsent extends Command | ||
{ | ||
protected $signature = 'users:delete-without-consent'; | ||
protected $description = 'Delete users who have not given consent and transfer their data to legacy user'; | ||
|
||
public function handle() | ||
{ | ||
$this->info('Creating or verifying legacy user...'); | ||
|
||
// Create legacy user if it doesn't exist | ||
User::firstOrCreate( | ||
['id' => 1000000], | ||
[ | ||
'firstname' => 'Codeweek Legacy User', | ||
'lastname' => 'Codeweek Legacy', | ||
'username' => 'codeweek-legacy', | ||
'password' => Hash::make('some-secure-password-' . time()), | ||
'email' => '[email protected]', | ||
'country_iso' => 'BE', | ||
'remember_token' => '5Pb4APP0CkOmQFzDtR960OlkdreLev2tvfUiywDawyJOmKDvFb3bmOAWlUL6', | ||
'privacy' => 1, | ||
'email_display' => '[email protected]', | ||
'receive_emails' => 0, | ||
'approved' => 1, | ||
'magic_key' => 2520090911, | ||
'consent_given_at' => now(), | ||
'future_consent_given_at' => now(), | ||
'email_verified_at' => now(), | ||
'created_at' => now(), | ||
'updated_at' => now() | ||
] | ||
); | ||
|
||
$this->info('Starting to process users without consent...'); | ||
|
||
// Get users without consent in chunks to avoid memory issues | ||
User::whereNull('consent_given_at') | ||
->where('id', '!=', 1000000) // Exclude the legacy user | ||
->chunkById(100, function ($users) { | ||
foreach ($users as $user) { | ||
ProcessUserDeletion::dispatch($user->id); | ||
$this->info("Dispatched deletion job for user ID: {$user->id}"); | ||
} | ||
}); | ||
|
||
$this->info('All deletion jobs have been dispatched. Check the queue worker logs for progress.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
namespace App\Jobs; | ||
|
||
use App\Excellence; | ||
use App\Participation; | ||
use App\User; | ||
use App\Event; | ||
use Illuminate\Bus\Queueable; | ||
use Illuminate\Contracts\Queue\ShouldQueue; | ||
use Illuminate\Foundation\Bus\Dispatchable; | ||
use Illuminate\Queue\InteractsWithQueue; | ||
use Illuminate\Queue\SerializesModels; | ||
use Illuminate\Support\Facades\DB; | ||
use Illuminate\Support\Facades\Log; | ||
|
||
class ProcessUserDeletion implements ShouldQueue | ||
{ | ||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||
|
||
protected $userId; | ||
protected $legacyUserId = 1000000; | ||
|
||
public function __construct($userId) | ||
{ | ||
$this->userId = $userId; | ||
} | ||
|
||
/** | ||
* @throws \Exception | ||
*/ | ||
public function handle() | ||
{ | ||
try { | ||
DB::beginTransaction(); | ||
|
||
Log::info("Processing deletion for user ID: {$this->userId}"); | ||
|
||
// Update events creator_id | ||
Event::where('creator_id', $this->userId) | ||
->update(['creator_id' => $this->legacyUserId]); | ||
|
||
// Update events approved_by | ||
Event::where('approved_by', $this->userId) | ||
->update(['approved_by' => $this->legacyUserId]); | ||
|
||
// Hard delete the user | ||
User::where('id', $this->userId)->forceDelete(); | ||
|
||
DB::commit(); | ||
Log::info("Successfully deleted user ID: {$this->userId}"); | ||
|
||
} catch (\Exception $e) { | ||
DB::rollBack(); | ||
Log::error("Error processing user ID: {$this->userId}", [ | ||
'error' => $e->getMessage(), | ||
'trace' => $e->getTraceAsString() | ||
]); | ||
throw $e; | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
database/migrations/2024_01_15_000000_create_failed_jobs_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
return new class extends Migration { | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
if (!Schema::hasTable('failed_jobs')) { | ||
Schema::create('failed_jobs', function (Blueprint $table) { | ||
$table->id(); | ||
$table->string('uuid')->unique(); | ||
$table->text('connection'); | ||
$table->text('queue'); | ||
$table->longText('payload'); | ||
$table->longText('exception'); | ||
$table->timestamp('failed_at')->useCurrent(); | ||
}); | ||
}; | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
*/ | ||
public function down(): void | ||
{ | ||
Schema::dropIfExists('failed_jobs'); | ||
} | ||
}; |
29 changes: 29 additions & 0 deletions
29
database/migrations/2024_12_13_120000_add_approved_by_index_to_events.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
return new class extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
Schema::table('events', function (Blueprint $table) { | ||
$table->index('approved_by'); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
*/ | ||
public function down(): void | ||
{ | ||
|
||
Schema::table('events', function (Blueprint $table) { | ||
$table->dropIndex(['approved_by']); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
-- INSERT INTO `codeweek_prod`.`users` (`id`, `firstname`, `lastname`, `username`, `password`, `email`, `country_iso`, `remember_token`, `created_at`, `updated_at`, `privacy`, `email_display`, `receive_emails`, `approved`, `magic_key`, `consent_given_at`, `future_consent_given_at`, `email_verified_at`) VALUES (1000000, 'Codeweek Legacy User', 'Codeweek Legacy', 'codeweek-legacy', '$2y$10$zcr85hlNx0U1aKpLtpsoKeAuPeSh1U9TxDY/A045m0y.5eXARsFg6', '[email protected]', 'BE', '5Pb4APP0CkOmQFzDtR960OlkdreLev2tvfUiywDawyJOmKDvFb3bmOAWlUL6', now(), now(), 1, '[email protected]', 0, 1, 2520090911, now(), now(), now()); | ||
|
||
DROP TABLE IF EXISTS users_to_delete; | ||
-- Create temporary table with users to process | ||
CREATE TEMPORARY TABLE users_to_delete AS | ||
SELECT id | ||
FROM users | ||
WHERE consent_given_at IS NULL | ||
LIMIT 1000; -- Process in chunks of 1000 | ||
|
||
-- Add index to improve performance | ||
ALTER TABLE users_to_delete ADD INDEX (id); | ||
|
||
START TRANSACTION; | ||
-- Update events creator_id | ||
UPDATE events e | ||
INNER JOIN users_to_delete u ON e.creator_id = u.id | ||
SET e.creator_id = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Update events approved_by | ||
UPDATE events e | ||
INNER JOIN users_to_delete u ON e.approved_by = u.id | ||
SET e.approved_by = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Update participations | ||
UPDATE participations p | ||
INNER JOIN users_to_delete u ON p.user_id = u.id | ||
SET p.user_id = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Update excellences | ||
UPDATE excellences e | ||
INNER JOIN users_to_delete u ON e.user_id = u.id | ||
SET e.user_id = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Update model_has_roles | ||
UPDATE model_has_roles m | ||
INNER JOIN users_to_delete u ON m.model_id = u.id | ||
SET m.model_id = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Update leading_teacher_expertise_user | ||
UPDATE leading_teacher_expertise_user l | ||
INNER JOIN users_to_delete u ON l.user_id = u.id | ||
SET l.user_id = 1000000; | ||
COMMIT; | ||
|
||
START TRANSACTION; | ||
-- Soft delete the users | ||
UPDATE users u | ||
INNER JOIN users_to_delete d ON u.id = d.id | ||
SET u.deleted_at = '2024-12-13 17:07:24', | ||
u.updated_at = '2024-12-13 17:07:24'; | ||
COMMIT; | ||
|
||
-- Delete processed users | ||
DELETE FROM users | ||
WHERE id IN (SELECT id FROM users_to_delete); | ||
|
||
-- Clean up | ||
DROP TABLE IF EXISTS users_to_delete; | ||
|
||
-- Repeat the process for the next batch by running this script again until no more users are found |