feat: soft-delete for teamer accounts

addresses #869dv9br3
This commit is contained in:
Björn Fromme
2026-08-11 12:26:13 +02:00
parent 388ecf9603
commit d654ce77fb
45 changed files with 1151 additions and 7 deletions
+13
View File
@@ -140,6 +140,19 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
->findLocalUser($profileResponse)
;
// A deleted account is excluded from every process, and the CRM must not be able
// to undo that: no data is written back, no role is granted or revoked, not even
// lastLoginAt is bumped. It is returned untouched so the UserChecker can refuse
// the login and say why. Only an admin restores it.
if (true === $user?->isDeleted()) {
$this->logger->info('Skip CRM sync for deleted user', [
'user_id' => $user->getId(),
'user_email' => $email,
]);
return $user;
}
// BusPro knows this person but grants them nothing in this application, so they
// are no user of it: never create an account, block an existing one. Returning
// the blocked user lets the UserChecker explain why the login was refused.
+6
View File
@@ -15,6 +15,12 @@ class UserChecker implements UserCheckerInterface
return;
}
// checked before the block, as a deletion is the stronger statement and its
// message has to win when an account carries both
if (true === $user->isDeleted()) {
throw new CustomUserMessageAccountStatusException('Dein Account wurde gelöscht. Wende dich an das Team, wenn du ihn wiederherstellen möchtest.');
}
if (true === $user->isDisabled()) {
throw new CustomUserMessageAccountStatusException('Dein Account wurde gesperrt: '.$user->getDisabledReason());
}
@@ -44,6 +44,12 @@ class ImpersonationVoter extends Voter
return false;
}
// a deleted account is excluded from every process, so impersonating it must not
// become a way back into the teamer area
if (true === $targetUser->isDeleted()) {
return false;
}
// Admin is the only role allowed to impersonate
if (false === $this->security->isGranted('ROLE_ADMIN')) {
return false;