167 lines
5.3 KiB
PHP
167 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Compliance;
|
|
|
|
use App\Models\CheckoutSession;
|
|
use App\Models\Event;
|
|
use App\Models\EventJoinToken;
|
|
use App\Models\EventMediaAsset;
|
|
use App\Models\EventMember;
|
|
use App\Models\PackagePurchase;
|
|
use App\Models\Photo;
|
|
use App\Models\Tenant;
|
|
use App\Models\TenantPackage;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class AccountAnonymizer
|
|
{
|
|
public function anonymize(User $user): void
|
|
{
|
|
DB::transaction(function () use ($user) {
|
|
$tenant = $user->tenant;
|
|
|
|
if ($tenant) {
|
|
$this->purgeTenantMedia($tenant);
|
|
$this->scrubTenantData($tenant);
|
|
}
|
|
|
|
$this->scrubUser($user);
|
|
});
|
|
}
|
|
|
|
public function anonymizeTenantOnly(Tenant $tenant): void
|
|
{
|
|
DB::transaction(function () use ($tenant) {
|
|
$this->purgeTenantMedia($tenant);
|
|
$this->scrubTenantData($tenant);
|
|
});
|
|
}
|
|
|
|
protected function purgeTenantMedia(Tenant $tenant): void
|
|
{
|
|
EventMediaAsset::query()
|
|
->whereHas('event', fn ($query) => $query->where('tenant_id', $tenant->id))
|
|
->chunkById(100, function ($assets) {
|
|
foreach ($assets as $asset) {
|
|
if ($asset->disk && $asset->path) {
|
|
Storage::disk($asset->disk)->delete($asset->path);
|
|
}
|
|
|
|
$asset->delete();
|
|
}
|
|
});
|
|
|
|
Photo::query()
|
|
->where(function ($query) use ($tenant) {
|
|
$query->where('tenant_id', $tenant->id)
|
|
->orWhereHas('event', fn ($inner) => $inner->where('tenant_id', $tenant->id));
|
|
})
|
|
->chunkById(200, function ($photos) {
|
|
foreach ($photos as $photo) {
|
|
$photo->delete();
|
|
}
|
|
});
|
|
}
|
|
|
|
protected function scrubTenantData(Tenant $tenant): void
|
|
{
|
|
$eventIds = Event::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->pluck('id');
|
|
|
|
EventJoinToken::query()->whereIn('event_id', $eventIds)->delete();
|
|
EventMember::query()->where('tenant_id', $tenant->id)->delete();
|
|
|
|
Event::query()
|
|
->whereIn('id', $eventIds)
|
|
->chunkById(100, function ($events) {
|
|
foreach ($events as $event) {
|
|
$event->forceFill([
|
|
'name' => ['de' => 'Anonymisiertes Event', 'en' => 'Anonymized Event'],
|
|
'description' => null,
|
|
'location' => null,
|
|
'slug' => 'anonymized-event-'.$event->id,
|
|
'status' => 'archived',
|
|
])->save();
|
|
|
|
$event->loadMissing('photoboothSetting');
|
|
|
|
if ($event->photoboothSetting) {
|
|
$event->photoboothSetting->forceFill([
|
|
'enabled' => false,
|
|
'status' => 'inactive',
|
|
'username' => null,
|
|
'password' => null,
|
|
'path' => null,
|
|
'expires_at' => null,
|
|
'last_deprovisioned_at' => now(),
|
|
'last_upload_at' => null,
|
|
'uploads_last_24h' => 0,
|
|
'uploads_total' => 0,
|
|
])->save();
|
|
}
|
|
}
|
|
});
|
|
|
|
PackagePurchase::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->update([
|
|
'ip_address' => null,
|
|
'user_agent' => null,
|
|
]);
|
|
|
|
CheckoutSession::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->update([
|
|
'tenant_id' => null,
|
|
'user_id' => null,
|
|
'provider_metadata' => [],
|
|
]);
|
|
|
|
TenantPackage::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->update(['active' => false]);
|
|
|
|
$tenant->forceFill([
|
|
'name' => 'Anonymisierter Tenant #'.$tenant->id,
|
|
'slug' => 'anonymized-tenant-'.$tenant->id,
|
|
'contact_name' => null,
|
|
'contact_email' => null,
|
|
'contact_phone' => null,
|
|
'email' => null,
|
|
'domain' => null,
|
|
'custom_domain' => null,
|
|
'user_id' => null,
|
|
'anonymized_at' => now(),
|
|
'pending_deletion_at' => null,
|
|
'deletion_warning_sent_at' => null,
|
|
'subscription_status' => 'deleted',
|
|
'is_active' => 0,
|
|
'is_suspended' => 1,
|
|
])->save();
|
|
}
|
|
|
|
protected function scrubUser(User $user): void
|
|
{
|
|
$placeholderEmail = sprintf('deleted+%s@fotospiel.app', $user->id);
|
|
|
|
$user->forceFill([
|
|
'name' => 'Anonymisierter Benutzer',
|
|
'email' => $placeholderEmail,
|
|
'username' => null,
|
|
'first_name' => null,
|
|
'last_name' => null,
|
|
'address' => null,
|
|
'phone' => null,
|
|
'password' => Str::random(40),
|
|
'remember_token' => null,
|
|
'pending_purchase' => false,
|
|
'email_verified_at' => null,
|
|
'role' => 'user',
|
|
])->save();
|
|
}
|
|
}
|