RaSecondFactorProjector::saveRaSecondFactor()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 8
dl 0
loc 28
rs 9.8333
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\IdentityEmailChangedEvent;
29
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
30
use Surfnet\Stepup\Identity\Event\IdentityRenamedEvent;
31
use Surfnet\Stepup\Identity\Event\PhonePossessionProvenAndVerifiedEvent;
32
use Surfnet\Stepup\Identity\Event\PhonePossessionProvenEvent;
33
use Surfnet\Stepup\Identity\Event\SecondFactorMigratedEvent;
34
use Surfnet\Stepup\Identity\Event\SecondFactorVettedEvent;
35
use Surfnet\Stepup\Identity\Event\SecondFactorVettedWithoutTokenProofOfPossession;
36
use Surfnet\Stepup\Identity\Event\U2fDevicePossessionProvenAndVerifiedEvent;
37
use Surfnet\Stepup\Identity\Event\U2fDevicePossessionProvenEvent;
38
use Surfnet\Stepup\Identity\Event\UnverifiedSecondFactorRevokedEvent;
39
use Surfnet\Stepup\Identity\Event\VerifiedSecondFactorRevokedEvent;
40
use Surfnet\Stepup\Identity\Event\VettedSecondFactorRevokedEvent;
41
use Surfnet\Stepup\Identity\Event\YubikeyPossessionProvenAndVerifiedEvent;
42
use Surfnet\Stepup\Identity\Event\YubikeyPossessionProvenEvent;
43
use Surfnet\Stepup\Identity\Event\YubikeySecondFactorBootstrappedEvent;
44
use Surfnet\Stepup\Identity\Value\CommonName;
45
use Surfnet\Stepup\Identity\Value\DocumentNumber;
46
use Surfnet\Stepup\Identity\Value\Email;
47
use Surfnet\Stepup\Identity\Value\OnPremiseVettingType;
48
use Surfnet\Stepup\Identity\Value\SecondFactorId;
49
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaSecondFactor;
50
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\IdentityRepository;
51
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\RaSecondFactorRepository;
52
use Surfnet\StepupMiddleware\ApiBundle\Identity\Value\SecondFactorStatus;
0 ignored issues
show
Bug introduced by
The type Surfnet\StepupMiddleware...alue\SecondFactorStatus was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
53
54
/**
55
 * @SuppressWarnings(PHPMD.TooManyMethods)
56
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
57
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
58
 */
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...
59
class RaSecondFactorProjector extends Projector
60
{
61
    public function __construct(
62
        private readonly RaSecondFactorRepository $raSecondFactorRepository,
63
        private readonly IdentityRepository $identityRepository,
64
    ) {
65
    }
66
67
    public function applyIdentityRenamedEvent(IdentityRenamedEvent $event): void
68
    {
69
        $secondFactors = $this->raSecondFactorRepository->findByIdentityId((string)$event->identityId);
70
71
        if ($secondFactors === []) {
72
            return;
73
        }
74
75
        $commonName = $event->commonName;
76
77
        foreach ($secondFactors as $secondFactor) {
78
            $secondFactor->name = $commonName;
79
        }
80
81
        $this->raSecondFactorRepository->saveAll($secondFactors);
82
    }
83
84
    public function applyIdentityEmailChangedEvent(IdentityEmailChangedEvent $event): void
85
    {
86
        $secondFactors = $this->raSecondFactorRepository->findByIdentityId((string)$event->identityId);
87
88
        if ($secondFactors === []) {
89
            return;
90
        }
91
92
        $email = $event->email;
93
94
        foreach ($secondFactors as $secondFactor) {
95
            $secondFactor->email = $email;
96
        }
97
98
        $this->raSecondFactorRepository->saveAll($secondFactors);
99
    }
100
101
    public function applyYubikeySecondFactorBootstrappedEvent(YubikeySecondFactorBootstrappedEvent $event): void
102
    {
103
        $identity = $this->identityRepository->find((string)$event->identityId);
104
105
        $secondFactor = new RaSecondFactor(
106
            (string)$event->secondFactorId,
107
            'yubikey',
108
            (string)$event->yubikeyPublicId,
109
            $identity->id,
110
            $identity->institution,
111
            $event->commonName,
112
            $event->email,
113
        );
114
        $secondFactor->status = SecondFactorStatus::vetted();
115
116
        $this->raSecondFactorRepository->save($secondFactor);
117
    }
118
119
    public function applyYubikeyPossessionProvenEvent(YubikeyPossessionProvenEvent $event): void
120
    {
121
        $this->saveRaSecondFactor(
122
            (string)$event->identityId,
123
            (string)$event->secondFactorId,
124
            'yubikey',
125
            (string)$event->yubikeyPublicId,
126
            $event->commonName,
127
            $event->email,
128
        );
129
    }
130
131
    public function applyYubikeyPossessionProvenAndVerifiedEvent(YubikeyPossessionProvenAndVerifiedEvent $event): void
132
    {
133
        $this->saveRaSecondFactor(
134
            (string)$event->identityId,
135
            (string)$event->secondFactorId,
136
            'yubikey',
137
            (string)$event->yubikeyPublicId,
138
            $event->commonName,
139
            $event->email,
140
        );
141
    }
142
143
    public function applyPhonePossessionProvenEvent(PhonePossessionProvenEvent $event): void
144
    {
145
        $this->saveRaSecondFactor(
146
            (string)$event->identityId,
147
            (string)$event->secondFactorId,
148
            'sms',
149
            (string)$event->phoneNumber,
150
            $event->commonName,
151
            $event->email,
152
        );
153
    }
154
155
    public function applyPhonePossessionProvenAndVerifiedEvent(PhonePossessionProvenAndVerifiedEvent $event): void
156
    {
157
        $this->saveRaSecondFactor(
158
            (string)$event->identityId,
159
            (string)$event->secondFactorId,
160
            'sms',
161
            (string)$event->phoneNumber,
162
            $event->commonName,
163
            $event->email,
164
        );
165
    }
166
167
    public function applyGssfPossessionProvenEvent(GssfPossessionProvenEvent $event): void
168
    {
169
        $this->saveRaSecondFactor(
170
            (string)$event->identityId,
171
            (string)$event->secondFactorId,
172
            (string)$event->stepupProvider,
173
            (string)$event->gssfId,
174
            $event->commonName,
175
            $event->email,
176
        );
177
    }
178
179
    public function applyGssfPossessionProvenAndVerifiedEvent(GssfPossessionProvenAndVerifiedEvent $event): void
180
    {
181
        $this->saveRaSecondFactor(
182
            (string)$event->identityId,
183
            (string)$event->secondFactorId,
184
            (string)$event->stepupProvider,
185
            (string)$event->gssfId,
186
            $event->commonName,
187
            $event->email,
188
        );
189
    }
190
191
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $event should have a doc-comment as per coding-style.
Loading history...
192
     * @deprecated Built in U2F support is dropped from StepUp, this was not removed to support event replay
193
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
194
    public function applyU2fDevicePossessionProvenEvent(U2fDevicePossessionProvenEvent $event): void
195
    {
196
        $this->saveRaSecondFactor(
197
            (string)$event->identityId,
198
            (string)$event->secondFactorId,
199
            'u2f',
200
            $event->keyHandle->getValue(),
201
            $event->commonName,
202
            $event->email,
203
        );
204
    }
205
206
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $event should have a doc-comment as per coding-style.
Loading history...
207
     * @deprecated Built in U2F support is dropped from StepUp, this was not removed to support event replay
208
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
209
    public function applyU2fDevicePossessionProvenAndVerifiedEvent(U2fDevicePossessionProvenAndVerifiedEvent $event,): void
210
    {
211
        $this->saveRaSecondFactor(
212
            (string)$event->identityId,
213
            (string)$event->secondFactorId,
214
            'u2f',
215
            $event->keyHandle->getValue(),
216
            $event->commonName,
217
            $event->email,
218
        );
219
    }
220
221
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $identityId should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $secondFactorId should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $secondFactorType should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $secondFactorIdentifier should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $commonName should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $email should have a doc-comment as per coding-style.
Loading history...
222
     * @param SecondFactorStatus|null $status
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $status does not match actual variable name $identityId
Loading history...
223
     * @param DocumentNumber|null $documentNumber
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Doc comment for parameter $documentNumber does not match actual variable name $secondFactorId
Loading history...
224
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
225
    private function saveRaSecondFactor(
0 ignored issues
show
Coding Style introduced by
Private method name "RaSecondFactorProjector::saveRaSecondFactor" must be prefixed with an underscore
Loading history...
226
        string             $identityId,
227
        string             $secondFactorId,
228
        string             $secondFactorType,
229
        string             $secondFactorIdentifier,
230
        CommonName         $commonName,
231
        Email              $email,
232
        SecondFactorStatus $status = null,
233
        DocumentNumber     $documentNumber = null,
234
    ): void {
235
        $identity = $this->identityRepository->find($identityId);
236
237
        $secondFactor = new RaSecondFactor(
238
            $secondFactorId,
239
            $secondFactorType,
240
            $secondFactorIdentifier,
241
            $identity->id,
242
            $identity->institution,
243
            $commonName,
244
            $email,
245
            $documentNumber,
246
        );
247
248
        if ($status instanceof SecondFactorStatus) {
249
            $secondFactor->status = $status;
250
        }
251
252
        $this->raSecondFactorRepository->save($secondFactor);
253
    }
254
255
    public function applyEmailVerifiedEvent(EmailVerifiedEvent $event): void
256
    {
257
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::verified());
258
    }
259
260
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $event should have a doc-comment as per coding-style.
Loading history...
261
     * The RA second factor projection is updated with a new Second factor based on the 'source' second factor
262
     * from the original identity.
263
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
264
    public function applySecondFactorMigratedEvent(SecondFactorMigratedEvent $event): void
265
    {
266
        $oldSecondFactor = $this->raSecondFactorRepository->find((string)$event->secondFactorId);
267
268
        $this->saveRaSecondFactor(
269
            (string)$event->identityId,
270
            (string)$event->newSecondFactorId,
271
            (string)$event->secondFactorType,
272
            (string)$event->secondFactorIdentifier,
273
            $event->commonName,
274
            $event->email,
275
            $oldSecondFactor->status,
276
            $oldSecondFactor->documentNumber,
277
        );
278
    }
279
280
    public function applySecondFactorVettedEvent(SecondFactorVettedEvent $event): void
281
    {
282
        $secondFactor = $this->raSecondFactorRepository->find((string)$event->secondFactorId);
283
        $secondFactor->documentNumber = $event->vettingType->getDocumentNumber();
0 ignored issues
show
Bug introduced by
The method getDocumentNumber() does not exist on null. ( Ignorable by Annotation )

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

283
        /** @scrutinizer ignore-call */ 
284
        $secondFactor->documentNumber = $event->vettingType->getDocumentNumber();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
284
        $secondFactor->status = SecondFactorStatus::vetted();
285
286
        $this->raSecondFactorRepository->save($secondFactor);
0 ignored issues
show
Bug introduced by
It seems like $secondFactor can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...actorRepository::save() does only seem to accept Surfnet\StepupMiddleware...y\Entity\RaSecondFactor, 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

286
        $this->raSecondFactorRepository->save(/** @scrutinizer ignore-type */ $secondFactor);
Loading history...
287
    }
288
289
    public function applySecondFactorVettedWithoutTokenProofOfPossession(
290
        SecondFactorVettedWithoutTokenProofOfPossession $event,
291
    ): void {
292
        $secondFactor = $this->raSecondFactorRepository->find((string)$event->secondFactorId);
293
294
        $documentNumber = null;
295
        if ($event->vettingType instanceof OnPremiseVettingType) {
296
            $documentNumber = $event->vettingType->getDocumentNumber();
297
        }
298
        $secondFactor->documentNumber = $documentNumber;
299
        $secondFactor->status = SecondFactorStatus::vetted();
300
301
        $this->raSecondFactorRepository->save($secondFactor);
0 ignored issues
show
Bug introduced by
It seems like $secondFactor can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...actorRepository::save() does only seem to accept Surfnet\StepupMiddleware...y\Entity\RaSecondFactor, 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

301
        $this->raSecondFactorRepository->save(/** @scrutinizer ignore-type */ $secondFactor);
Loading history...
302
    }
303
304
    protected function applyUnverifiedSecondFactorRevokedEvent(UnverifiedSecondFactorRevokedEvent $event): void
305
    {
306
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
307
    }
308
309
    protected function applyCompliedWithUnverifiedSecondFactorRevocationEvent(
310
        CompliedWithUnverifiedSecondFactorRevocationEvent $event,
311
    ): void {
312
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
313
    }
314
315
    protected function applyVerifiedSecondFactorRevokedEvent(VerifiedSecondFactorRevokedEvent $event): void
316
    {
317
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
318
    }
319
320
    protected function applyCompliedWithVerifiedSecondFactorRevocationEvent(
321
        CompliedWithVerifiedSecondFactorRevocationEvent $event,
322
    ): void {
323
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
324
    }
325
326
    protected function applyVettedSecondFactorRevokedEvent(VettedSecondFactorRevokedEvent $event): void
327
    {
328
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
329
    }
330
331
    protected function applyCompliedWithVettedSecondFactorRevocationEvent(
332
        CompliedWithVettedSecondFactorRevocationEvent $event,
333
    ): void {
334
        $this->updateStatus($event->secondFactorId, SecondFactorStatus::revoked());
335
    }
336
337
    protected function applyIdentityForgottenEvent(IdentityForgottenEvent $event): void
338
    {
339
        $this->raSecondFactorRepository->updateStatusByIdentityIdToForgotten($event->identityId);
340
    }
341
342
    private function updateStatus(SecondFactorId $secondFactorId, SecondFactorStatus $status): void
0 ignored issues
show
Coding Style introduced by
Private method name "RaSecondFactorProjector::updateStatus" must be prefixed with an underscore
Loading history...
343
    {
344
        $secondFactor = $this->raSecondFactorRepository->find((string)$secondFactorId);
345
        $secondFactor->status = $status;
346
347
        $this->raSecondFactorRepository->save($secondFactor);
0 ignored issues
show
Bug introduced by
It seems like $secondFactor can also be of type null; however, parameter $secondFactor of Surfnet\StepupMiddleware...actorRepository::save() does only seem to accept Surfnet\StepupMiddleware...y\Entity\RaSecondFactor, 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

347
        $this->raSecondFactorRepository->save(/** @scrutinizer ignore-type */ $secondFactor);
Loading history...
348
    }
349
}
350