Feat: Updating the Privacy Providers, moving them into the appropriate Modules, Updating Privacy views
This commit is contained in:
@@ -5,19 +5,23 @@ namespace Modules\Core\Privacy\Services;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Lunar\Base\LunarUser;
|
||||
use Lunar\Models\Customer;
|
||||
use Modules\Core\Auth\Models\Staff;
|
||||
use Modules\Core\Privacy\Contracts\PersonalDataProvider;
|
||||
use Modules\Core\Privacy\DTOs\CustomerSubject;
|
||||
use Modules\Core\Privacy\DTOs\ErasureReport;
|
||||
use Modules\Core\Privacy\DTOs\ProviderErasureResult;
|
||||
use Modules\Core\Privacy\DTOs\UserSubject;
|
||||
use Modules\Core\Privacy\Enums\ErasureOutcome;
|
||||
use Modules\Core\Privacy\Enums\ErasureRequestStatus;
|
||||
use Modules\Core\Privacy\Enums\ExportRequestStatus;
|
||||
use Modules\Core\Privacy\Events\UserErasureRequested;
|
||||
use Modules\Core\Privacy\Jobs\ExportDataSubjectJob;
|
||||
use Modules\Core\Privacy\Models\DataErasureRequest;
|
||||
use Modules\Core\Privacy\Models\DataExportRequest;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Entry point for right-of-access and right-of-erasure requests, split into two
|
||||
@@ -244,15 +248,30 @@ class PrivacyService
|
||||
* called directly for a request that hasn't passed its grace period, since
|
||||
* that defeats the point of the window; ProcessErasureRequestsCommand
|
||||
* enforces isDue() before calling this.
|
||||
*
|
||||
* Each provider call is caught individually — a provider throwing (a bug,
|
||||
* an unexpected DB state) converts to ErasureOutcome::Failed rather than
|
||||
* aborting the whole array_map, so one broken provider never discards
|
||||
* every OTHER provider's already-completed erasure for this same request.
|
||||
* Without this, the $request->update() below would never run at all on a
|
||||
* throw, silently leaving providers that already succeeded unrecorded and
|
||||
* the request stuck Pending forever. Logged via Log::error() so a thrown
|
||||
* provider is still visible to staff, not just swallowed into "Failed."
|
||||
*/
|
||||
public function completeErasure(DataErasureRequest $request): ErasureReport
|
||||
{
|
||||
if ($request->isForCustomer()) {
|
||||
$subject = new CustomerSubject(customerId: $request->subject_id);
|
||||
$results = array_map(fn ($provider) => $provider->eraseForCustomer($subject), $this->manager->providers());
|
||||
$results = array_map(
|
||||
fn (PersonalDataProvider $provider) => $this->safeErase($provider, 'eraseForCustomer', $subject),
|
||||
$this->manager->providers()
|
||||
);
|
||||
} else {
|
||||
$subject = new UserSubject(userId: $request->subject_id, email: $request->email);
|
||||
$results = array_map(fn ($provider) => $provider->eraseForUser($subject), $this->manager->providers());
|
||||
$results = array_map(
|
||||
fn (PersonalDataProvider $provider) => $this->safeErase($provider, 'eraseForUser', $subject),
|
||||
$this->manager->providers()
|
||||
);
|
||||
}
|
||||
|
||||
$report = new ErasureReport($subject, $results);
|
||||
@@ -282,4 +301,21 @@ class PrivacyService
|
||||
'deactivated_at' => $deactivated ? now() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param 'eraseForCustomer'|'eraseForUser' $method
|
||||
*/
|
||||
private function safeErase(PersonalDataProvider $provider, string $method, CustomerSubject|UserSubject $subject): ProviderErasureResult
|
||||
{
|
||||
try {
|
||||
return $provider->{$method}($subject);
|
||||
} catch (Throwable $e) {
|
||||
Log::error("Privacy provider {$provider->name()}::{$method}() threw during erasure", [
|
||||
'provider' => $provider->name(),
|
||||
'exception' => $e,
|
||||
]);
|
||||
|
||||
return new ProviderErasureResult($provider->name(), ErasureOutcome::Failed, $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user