applyPhonePossessionProvenEvent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
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
 */
0 ignored issues
show
Coding Style introduced by
Missing @link tag in file comment
Loading history...
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\Identity\Projector;
20
21
use Surfnet\Stepup\Projector\Projector;
22
use Surfnet\Stepup\Identity\Event\CompliedWithUnverifiedSecondFactorRevocationEvent;
23
use Surfnet\Stepup\Identity\Event\CompliedWithVerifiedSecondFactorRevocationEvent;
24
use Surfnet\Stepup\Identity\Event\CompliedWithVettedSecondFactorRevocationEvent;
25
use Surfnet\Stepup\Identity\Event\EmailVerifiedEvent;
26
use Surfnet\Stepup\Identity\Event\GssfPossessionProvenAndVerifiedEvent;
27
use Surfnet\Stepup\Identity\Event\GssfPossessionProvenEvent;
28
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
29
use Surfnet\Stepup\Identity\Event\PhonePossessionProvenAndVerifiedEvent;
30
use Surfnet\Stepup\Identity\Event\PhonePossessionProvenEvent;
31
use Surfnet\Stepup\Identity\Event\SecondFactorMigratedEvent;
32
use Surfnet\Stepup\Identity\Event\SecondFactorVettedEvent;
33
use Surfnet\Stepup\Identity\Event\SecondFactorVettedWithoutTokenProofOfPossession;
34
use Surfnet\Stepup\Identity\Event\UnverifiedSecondFactorRevokedEvent;
35
use Surfnet\Stepup\Identity\Event\VerifiedSecondFactorRevokedEvent;
36
use Surfnet\Stepup\Identity\Event\VettedSecondFactorRevokedEvent;
37
use Surfnet\Stepup\Identity\Event\YubikeyPossessionProvenAndVerifiedEvent;
38
use Surfnet\Stepup\Identity\Event\YubikeyPossessionProvenEvent;
39
use Surfnet\Stepup\Identity\Event\YubikeySecondFactorBootstrappedEvent;
40
use Surfnet\Stepup\Identity\Value\UnknownVettingType;
41
use Surfnet\Stepup\Identity\Value\VettingType;
42
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\UnverifiedSecondFactor;
43
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\VerifiedSecondFactor;
44
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\VettedSecondFactor;
45
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\UnverifiedSecondFactorRepository;
46
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\VerifiedSecondFactorRepository;
47
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\VettedSecondFactorRepository;
48
49
/**
50
 * @SuppressWarnings(PHPMD.TooManyMethods)
51
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
52
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
53
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
54
class SecondFactorProjector extends Projector
55
{
56
    public function __construct(
57
        private readonly UnverifiedSecondFactorRepository $unverifiedRepository,
58
        private readonly VerifiedSecondFactorRepository $verifiedRepository,
59
        private readonly VettedSecondFactorRepository $vettedRepository,
60
    ) {
61
    }
62
63
    public function applyYubikeySecondFactorBootstrappedEvent(YubikeySecondFactorBootstrappedEvent $event): void
64
    {
65
        $secondFactor = new VettedSecondFactor();
66
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
67
        $secondFactor->identityId = $event->identityId->getIdentityId();
68
        $secondFactor->type = 'yubikey';
69
        $secondFactor->secondFactorIdentifier = $event->yubikeyPublicId->getValue();
70
        $secondFactor->vettingType = VettingType::TYPE_ON_PREMISE;
71
        $this->vettedRepository->save($secondFactor);
72
    }
73
74
    public function applyYubikeyPossessionProvenEvent(YubikeyPossessionProvenEvent $event): void
75
    {
76
        $secondFactor = new UnverifiedSecondFactor();
77
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
78
        $secondFactor->identityId = $event->identityId->getIdentityId();
79
        $secondFactor->type = 'yubikey';
80
        $secondFactor->secondFactorIdentifier = $event->yubikeyPublicId->getValue();
81
        $secondFactor->verificationNonce = $event->emailVerificationNonce;
82
83
        $this->unverifiedRepository->save($secondFactor);
84
    }
85
86
    public function applyYubikeyPossessionProvenAndVerifiedEvent(YubikeyPossessionProvenAndVerifiedEvent $event): void
87
    {
88
        $secondFactor = new VerifiedSecondFactor();
89
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
90
        $secondFactor->identityId = $event->identityId->getIdentityId();
91
        $secondFactor->institution = $event->identityInstitution->getInstitution();
92
        $secondFactor->type = 'yubikey';
93
        $secondFactor->secondFactorIdentifier = $event->yubikeyPublicId->getValue();
94
        $secondFactor->commonName = $event->commonName;
95
        $secondFactor->registrationRequestedAt = $event->registrationRequestedAt;
96
        $secondFactor->registrationCode = $event->registrationCode;
97
98
        $this->verifiedRepository->save($secondFactor);
99
    }
100
101
    public function applyPhonePossessionProvenEvent(PhonePossessionProvenEvent $event): void
102
    {
103
        $secondFactor = new UnverifiedSecondFactor();
104
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
105
        $secondFactor->identityId = $event->identityId->getIdentityId();
106
        $secondFactor->type = 'sms';
107
        $secondFactor->secondFactorIdentifier = $event->phoneNumber->getValue();
108
        $secondFactor->verificationNonce = $event->emailVerificationNonce;
109
110
        $this->unverifiedRepository->save($secondFactor);
111
    }
112
113
    public function applyPhonePossessionProvenAndVerifiedEvent(PhonePossessionProvenAndVerifiedEvent $event): void
114
    {
115
        $secondFactor = new VerifiedSecondFactor();
116
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
117
        $secondFactor->identityId = $event->identityId->getIdentityId();
118
        $secondFactor->institution = $event->identityInstitution->getInstitution();
119
        $secondFactor->type = 'sms';
120
        $secondFactor->secondFactorIdentifier = $event->phoneNumber->getValue();
121
        $secondFactor->commonName = $event->commonName;
122
        $secondFactor->registrationRequestedAt = $event->registrationRequestedAt;
123
        $secondFactor->registrationCode = $event->registrationCode;
124
125
        $this->verifiedRepository->save($secondFactor);
126
    }
127
128
    public function applyGssfPossessionProvenEvent(GssfPossessionProvenEvent $event): void
129
    {
130
        $secondFactor = new UnverifiedSecondFactor();
131
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
132
        $secondFactor->identityId = $event->identityId->getIdentityId();
133
        $secondFactor->type = $event->stepupProvider->getStepupProvider();
134
        $secondFactor->secondFactorIdentifier = $event->gssfId->getValue();
135
        $secondFactor->verificationNonce = $event->emailVerificationNonce;
136
137
        $this->unverifiedRepository->save($secondFactor);
138
    }
139
140
    public function applyGssfPossessionProvenAndVerifiedEvent(GssfPossessionProvenAndVerifiedEvent $event): void
141
    {
142
        $secondFactor = new VerifiedSecondFactor();
143
        $secondFactor->id = $event->secondFactorId->getSecondFactorId();
144
        $secondFactor->identityId = $event->identityId->getIdentityId();
145
        $secondFactor->institution = $event->identityInstitution->getInstitution();
146
        $secondFactor->type = $event->stepupProvider->getStepupProvider();
147
        $secondFactor->secondFactorIdentifier = $event->gssfId->getValue();
148
        $secondFactor->commonName = $event->commonName;
149
        $secondFactor->registrationRequestedAt = $event->registrationRequestedAt;
150
        $secondFactor->registrationCode = $event->registrationCode;
151
152
        $this->verifiedRepository->save($secondFactor);
153
    }
154
155
    public function applyEmailVerifiedEvent(EmailVerifiedEvent $event): void
156
    {
157
        if ($event->secondFactorType->isU2f()) {
0 ignored issues
show
Deprecated Code introduced by
The function Surfnet\StepupBundle\Val...condFactorType::isU2f() has been deprecated: u2f support is removed from StepUp in favour of the WebAuthn GSSP ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

157
        if (/** @scrutinizer ignore-deprecated */ $event->secondFactorType->isU2f()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
158
            // u2f is deprecated so those events shouldn't be handled anymore
159
            return;
160
        }
161
        $unverified = $this->unverifiedRepository->find($event->secondFactorId->getSecondFactorId());
162
163
        $verified = new VerifiedSecondFactor();
164
        $verified->id = $event->secondFactorId->getSecondFactorId();
165
        $verified->identityId = $event->identityId->getIdentityId();
166
        $verified->institution = $event->identityInstitution->getInstitution();
167
        $verified->commonName = $event->commonName->getCommonName();
168
        $verified->type = $event->secondFactorType->getSecondFactorType();
169
        $verified->secondFactorIdentifier = $unverified->secondFactorIdentifier;
170
        $verified->registrationCode = $event->registrationCode;
171
        $verified->registrationRequestedAt = $event->registrationRequestedAt;
172
173
        $this->verifiedRepository->save($verified);
174
        $this->unverifiedRepository->remove($unverified);
0 ignored issues
show
Bug introduced by
It seems like $unverified can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...\UnverifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
        $this->unverifiedRepository->remove(/** @scrutinizer ignore-type */ $unverified);
Loading history...
175
    }
176
177
    public function applySecondFactorVettedEvent(SecondFactorVettedEvent $event): void
178
    {
179
        $verified = $this->verifiedRepository->find($event->secondFactorId->getSecondFactorId());
180
181
        $vetted = new VettedSecondFactor();
182
        $vetted->id = $event->secondFactorId->getSecondFactorId();
183
        $vetted->identityId = $event->identityId->getIdentityId();
184
        $vetted->type = $event->secondFactorType->getSecondFactorType();
185
        $vetted->secondFactorIdentifier = $event->secondFactorIdentifier->getValue();
186
        // In case the vetting type is unknown (for example when no event replay was performed)
187
        // fall back to the unknown vetting type.
188
        $vettingType = $event->vettingType;
189
        if (!$vettingType instanceof \Surfnet\Stepup\Identity\Value\VettingType) {
190
            $vettingType = new UnknownVettingType();
191
        }
192
        $vetted->vettingType = $vettingType->type();
193
194
        $this->vettedRepository->save($vetted);
195
        $this->verifiedRepository->remove($verified);
0 ignored issues
show
Bug introduced by
It seems like $verified can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...ty\VerifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

195
        $this->verifiedRepository->remove(/** @scrutinizer ignore-type */ $verified);
Loading history...
196
    }
197
198
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $event should have a doc-comment as per coding-style.
Loading history...
199
     * A new vetted second factor is projected. A copy of the 'source' second factor.
200
     * The original 'source' second factor is not yet removed. This is handled when the
201
     * old identity is cleaned up.
202
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
203
    public function applySecondFactorMigratedEvent(SecondFactorMigratedEvent $event): void
204
    {
205
        $vetted = new VettedSecondFactor();
206
        $vetted->id = $event->newSecondFactorId->getSecondFactorId();
207
        $vetted->identityId = $event->identityId->getIdentityId();
208
        $vetted->type = $event->secondFactorType->getSecondFactorType();
209
        $vettingType = $event->vettingType ?? new UnknownVettingType();
210
        $vetted->vettingType = $vettingType;
211
        $vetted->secondFactorIdentifier = $event->secondFactorIdentifier->getValue();
212
        $this->vettedRepository->save($vetted);
213
    }
214
215
    public function applySecondFactorVettedWithoutTokenProofOfPossession(
216
        SecondFactorVettedWithoutTokenProofOfPossession $event,
217
    ): void {
218
        $verified = $this->verifiedRepository->find($event->secondFactorId->getSecondFactorId());
219
220
        $vetted = new VettedSecondFactor();
221
        $vetted->id = $event->secondFactorId->getSecondFactorId();
222
        $vetted->identityId = $event->identityId->getIdentityId();
223
        $vetted->type = $event->secondFactorType->getSecondFactorType();
224
        $vetted->secondFactorIdentifier = $event->secondFactorIdentifier->getValue();
225
        $vettingType = $event->vettingType;
226
        // In case the vetting type is unknown (for example when no event replay was performed)
227
        // fall back to the unknown vetting type.
228
        if (!$vettingType instanceof \Surfnet\Stepup\Identity\Value\VettingType) {
229
            $vettingType = new UnknownVettingType();
230
        }
231
        $vetted->vettingType = $vettingType->type();
232
233
        $this->vettedRepository->save($vetted);
234
        $this->verifiedRepository->remove($verified);
0 ignored issues
show
Bug introduced by
It seems like $verified can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...ty\VerifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

234
        $this->verifiedRepository->remove(/** @scrutinizer ignore-type */ $verified);
Loading history...
235
    }
236
237
    protected function applyUnverifiedSecondFactorRevokedEvent(UnverifiedSecondFactorRevokedEvent $event): void
238
    {
239
        $this->unverifiedRepository->remove(
240
            $this->unverifiedRepository->find($event->secondFactorId->getSecondFactorId()),
0 ignored issues
show
Bug introduced by
It seems like $this->unverifiedReposit...d->getSecondFactorId()) can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...\UnverifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

240
            /** @scrutinizer ignore-type */ $this->unverifiedRepository->find($event->secondFactorId->getSecondFactorId()),
Loading history...
241
        );
242
    }
243
244
    protected function applyCompliedWithUnverifiedSecondFactorRevocationEvent(
245
        CompliedWithUnverifiedSecondFactorRevocationEvent $event,
246
    ): void {
247
        $this->unverifiedRepository->remove(
248
            $this->unverifiedRepository->find($event->secondFactorId->getSecondFactorId()),
0 ignored issues
show
Bug introduced by
It seems like $this->unverifiedReposit...d->getSecondFactorId()) can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...\UnverifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

248
            /** @scrutinizer ignore-type */ $this->unverifiedRepository->find($event->secondFactorId->getSecondFactorId()),
Loading history...
249
        );
250
    }
251
252
    protected function applyVerifiedSecondFactorRevokedEvent(VerifiedSecondFactorRevokedEvent $event): void
253
    {
254
        if ($event->secondFactorType->isU2f()) {
0 ignored issues
show
Deprecated Code introduced by
The function Surfnet\StepupBundle\Val...condFactorType::isU2f() has been deprecated: u2f support is removed from StepUp in favour of the WebAuthn GSSP ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

254
        if (/** @scrutinizer ignore-deprecated */ $event->secondFactorType->isU2f()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
255
            // u2f is deprecated so those events shouldn't be handled anymore
256
            return;
257
        }
258
        $verifiedSecondFactor = $this->verifiedRepository->find($event->secondFactorId->getSecondFactorId());
259
260
        $this->verifiedRepository->remove($verifiedSecondFactor);
0 ignored issues
show
Bug introduced by
It seems like $verifiedSecondFactor can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...ty\VerifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

260
        $this->verifiedRepository->remove(/** @scrutinizer ignore-type */ $verifiedSecondFactor);
Loading history...
261
    }
262
263
    protected function applyCompliedWithVerifiedSecondFactorRevocationEvent(
264
        CompliedWithVerifiedSecondFactorRevocationEvent $event,
265
    ): void {
266
        $this->verifiedRepository->remove($this->verifiedRepository->find($event->secondFactorId->getSecondFactorId()));
0 ignored issues
show
Bug introduced by
It seems like $this->verifiedRepositor...d->getSecondFactorId()) can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...ty\VerifiedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

266
        $this->verifiedRepository->remove(/** @scrutinizer ignore-type */ $this->verifiedRepository->find($event->secondFactorId->getSecondFactorId()));
Loading history...
267
    }
268
269
    protected function applyVettedSecondFactorRevokedEvent(VettedSecondFactorRevokedEvent $event): void
270
    {
271
        $this->vettedRepository->remove($this->vettedRepository->find($event->secondFactorId->getSecondFactorId()));
0 ignored issues
show
Bug introduced by
It seems like $this->vettedRepository-...d->getSecondFactorId()) can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...tity\VettedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

271
        $this->vettedRepository->remove(/** @scrutinizer ignore-type */ $this->vettedRepository->find($event->secondFactorId->getSecondFactorId()));
Loading history...
272
    }
273
274
    protected function applyCompliedWithVettedSecondFactorRevocationEvent(
275
        CompliedWithVettedSecondFactorRevocationEvent $event,
276
    ): void {
277
        $this->vettedRepository->remove($this->vettedRepository->find($event->secondFactorId->getSecondFactorId()));
0 ignored issues
show
Bug introduced by
It seems like $this->vettedRepository-...d->getSecondFactorId()) can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...torRepository::remove() does only seem to accept Surfnet\StepupMiddleware...tity\VettedSecondFactor, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

277
        $this->vettedRepository->remove(/** @scrutinizer ignore-type */ $this->vettedRepository->find($event->secondFactorId->getSecondFactorId()));
Loading history...
278
    }
279
280
    protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
281
    {
282
        $this->unverifiedRepository->removeByIdentityId($event->identityId);
283
        $this->verifiedRepository->removeByIdentityId($event->identityId);
284
        $this->vettedRepository->removeByIdentityId($event->identityId);
285
    }
286
}
287