Skip to content

Commit ad83840

Browse files
authored
Merge pull request #521 from OpenConext/bugfix/fix-deprovision-anonymisation
Fix missing deprovision data
2 parents a0d26b1 + 0a3d7e4 commit ad83840

34 files changed

Lines changed: 284 additions & 39 deletions

src/Surfnet/Stepup/Identity/Identity.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,8 +1003,6 @@ public function expressPreferredLocale(Locale $preferredLocale): void
10031003

10041004
public function forget(): void
10051005
{
1006-
$this->assertNotForgotten();
1007-
10081006
if ($this->registrationAuthorities->count() !== 0) {
10091007
throw new DomainException('Cannot forget an identity that is currently accredited as an RA(A)');
10101008
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2025 SURFnet B.V.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
namespace Surfnet\Stepup\Projector;
20+
21+
use Broadway\EventHandling\EventListener;
22+
use Broadway\ReadModel\Projector as BroadwayProjector;
23+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
24+
25+
/**
26+
* @SuppressWarnings(PHPMD.NumberOfChildren) we simply have a lot of projectors
27+
*/
28+
abstract class Projector extends BroadwayProjector implements EventListener
29+
{
30+
abstract protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void;
31+
}

src/Surfnet/StepupMiddleware/ApiBundle/Configuration/Projector/AllowedSecondFactorListProjector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
namespace Surfnet\StepupMiddleware\ApiBundle\Configuration\Projector;
2020

21-
use Broadway\ReadModel\Projector;
21+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
22+
use Surfnet\Stepup\Projector\Projector;
2223
use Surfnet\Stepup\Configuration\Event\AllowedSecondFactorListUpdatedEvent;
2324
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Entity\AllowedSecondFactor;
2425
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Repository\AllowedSecondFactorRepository;
@@ -40,4 +41,9 @@ public function applyAllowedSecondFactorListUpdatedEvent(AllowedSecondFactorList
4041
$this->allowedSecondFactorRepository->save($allowedSecondFactor);
4142
}
4243
}
44+
45+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
46+
{
47+
// do nothing, no sensitive data in this projection
48+
}
4349
}

src/Surfnet/StepupMiddleware/ApiBundle/Configuration/Projector/ConfiguredInstitutionProjector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
namespace Surfnet\StepupMiddleware\ApiBundle\Configuration\Projector;
2020

21-
use Broadway\ReadModel\Projector;
21+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
22+
use Surfnet\Stepup\Projector\Projector;
2223
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
2324
use Surfnet\Stepup\Configuration\Event\NewInstitutionConfigurationCreatedEvent;
2425
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Entity\ConfiguredInstitution;
@@ -40,4 +41,9 @@ public function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurati
4041
{
4142
$this->configuredInstitutionRepository->removeConfigurationFor($event->institution);
4243
}
44+
45+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
46+
{
47+
// do nothing, no sensitive data in this projection
48+
}
4349
}

src/Surfnet/StepupMiddleware/ApiBundle/Configuration/Projector/InstitutionAuthorizationProjector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
namespace Surfnet\StepupMiddleware\ApiBundle\Configuration\Projector;
2020

21-
use Broadway\ReadModel\Projector;
21+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
22+
use Surfnet\Stepup\Projector\Projector;
2223
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
2324
use Surfnet\Stepup\Configuration\Event\NewInstitutionConfigurationCreatedEvent;
2425
use Surfnet\Stepup\Configuration\Event\SelectRaaOptionChangedEvent;
@@ -72,4 +73,9 @@ public function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurati
7273
$event->institution,
7374
);
7475
}
76+
77+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
78+
{
79+
// do nothing, no sensitive data in this projection
80+
}
7581
}

src/Surfnet/StepupMiddleware/ApiBundle/Configuration/Projector/InstitutionConfigurationOptionsProjector.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
namespace Surfnet\StepupMiddleware\ApiBundle\Configuration\Projector;
2020

21-
use Broadway\ReadModel\Projector;
21+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
22+
use Surfnet\Stepup\Projector\Projector;
2223
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
2324
use Surfnet\Stepup\Configuration\Event\NewInstitutionConfigurationCreatedEvent;
2425
use Surfnet\Stepup\Configuration\Event\NumberOfTokensPerIdentityOptionChangedEvent;
@@ -32,6 +33,9 @@
3233
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Repository\AllowedSecondFactorRepository;
3334
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Repository\InstitutionConfigurationOptionsRepository;
3435

36+
/**
37+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
38+
*/
3539
final class InstitutionConfigurationOptionsProjector extends Projector
3640
{
3741
public function __construct(
@@ -131,4 +135,9 @@ public function applyInstitutionConfigurationRemovedEvent(InstitutionConfigurati
131135
$this->institutionConfigurationOptionsRepository->removeConfigurationOptionsFor($event->institution);
132136
$this->allowedSecondFactorRepository->clearAllowedSecondFactorListFor($event->institution);
133137
}
138+
139+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
140+
{
141+
// do nothing, no sensitive data in this projection
142+
}
134143
}

src/Surfnet/StepupMiddleware/ApiBundle/Configuration/Projector/RaLocationProjector.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818

1919
namespace Surfnet\StepupMiddleware\ApiBundle\Configuration\Projector;
2020

21-
use Broadway\ReadModel\Projector;
21+
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
22+
use Surfnet\Stepup\Projector\Projector;
2223
use Surfnet\Stepup\Configuration\Event\InstitutionConfigurationRemovedEvent;
2324
use Surfnet\Stepup\Configuration\Event\RaLocationAddedEvent;
2425
use Surfnet\Stepup\Configuration\Event\RaLocationContactInformationChangedEvent;
@@ -100,4 +101,9 @@ private function fetchRaLocationById(RaLocationId $raLocationId): RaLocation
100101

101102
return $raLocation;
102103
}
104+
105+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
106+
{
107+
// do nothing, no sensitive data in this projection
108+
}
103109
}

src/Surfnet/StepupMiddleware/ApiBundle/Controller/DeprovisionController.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use Surfnet\Stepup\Exception\DomainException;
2323
use Surfnet\Stepup\Helper\UserDataFormatterInterface;
2424
use Surfnet\StepupMiddleware\ApiBundle\Service\DeprovisionServiceInterface;
25-
use Surfnet\StepupMiddleware\ApiBundle\Controller\AbstractController;
2625
use Symfony\Component\HttpFoundation\JsonResponse;
2726

2827
class DeprovisionController extends AbstractController
@@ -42,11 +41,12 @@ public function deprovision(string $collabPersonId): JsonResponse
4241
if ($userData !== []) {
4342
$this->deprovisionService->deprovision($collabPersonId);
4443
}
45-
} catch (DomainException) {
44+
} catch (DomainException $e) {
4645
// On domain exceptions, like when the identity is forgotten, we return OK, with empty data
4746
// just so the deprovision run does not end prematurely. At this point, no other domain exceptions
4847
// are thrown.
4948
$userData = [];
49+
$errors = [$e->getMessage()];
5050
} catch (Exception $e) {
5151
$userData = [];
5252
$errors = [$e->getMessage()];
@@ -57,8 +57,11 @@ public function deprovision(string $collabPersonId): JsonResponse
5757
public function dryRun(string $collabPersonId): JsonResponse
5858
{
5959
$this->denyAccessUnlessGrantedOneOff(['ROLE_DEPROVISION']);
60+
6061
$errors = [];
6162
try {
63+
$this->deprovisionService->assertIsAllowed($collabPersonId);
64+
6265
$userData = $this->deprovisionService->readUserData($collabPersonId);
6366
} catch (Exception $e) {
6467
$userData = [];

src/Surfnet/StepupMiddleware/ApiBundle/Identity/Entity/AuditLogEntry.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class AuditLogEntry implements JsonSerializable
153153
public ?string $secondFactorType = null;
154154

155155
#[ORM\Column(length: 255, nullable: true)]
156-
public ?string $recoveryTokenIdentifier;
156+
public ?string $recoveryTokenIdentifier = null;
157157

158158
#[ORM\Column(length: 36, nullable: true)]
159159
public ?string $recoveryTokenType = null;

src/Surfnet/StepupMiddleware/ApiBundle/Identity/Projector/AuditLogProjector.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
namespace Surfnet\StepupMiddleware\ApiBundle\Identity\Projector;
2020

2121
use Broadway\Domain\DomainMessage;
22-
use Broadway\EventHandling\EventListener;
2322
use DateTime as CoreDateTime;
2423
use Ramsey\Uuid\Uuid;
2524
use Surfnet\Stepup\DateTime\DateTime;
@@ -33,6 +32,7 @@
3332
use Surfnet\Stepup\Identity\Value\RecoveryTokenIdentifierFactory;
3433
use Surfnet\Stepup\Identity\Value\RecoveryTokenType;
3534
use Surfnet\Stepup\Identity\Value\VettingType;
35+
use Surfnet\Stepup\Projector\Projector;
3636
use Surfnet\StepupMiddleware\ApiBundle\Exception\RuntimeException;
3737
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\AuditLogEntry;
3838
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\Identity;
@@ -42,7 +42,7 @@
4242
/**
4343
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
4444
*/
45-
class AuditLogProjector implements EventListener
45+
class AuditLogProjector extends Projector
4646
{
4747
public function __construct(
4848
private readonly AuditLogRepository $auditLogRepository,
@@ -138,7 +138,7 @@ private function applyAuditableEvent(AuditableEvent $event, DomainMessage $domai
138138
$this->auditLogRepository->save($entry);
139139
}
140140

141-
private function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
141+
protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
142142
{
143143
$entries = $this->auditLogRepository->findByIdentityId($event->identityId);
144144
foreach ($entries as $auditLogEntry) {

0 commit comments

Comments
 (0)