Passed
Push — feature/symfony6-upgrade ( 166417...86e2b9 )
by Paul
06:45
created

SelfAssertedTokensController   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 384
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 199
c 1
b 0
f 0
dl 0
loc 384
rs 9.6
wmc 35

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A invokeSelfAssertedTokenRegistrationCommand() 0 8 1
A registerCreateRecoveryTokenSafeStore() 0 35 4
B selfAssertedTokenRecoveryTokenSmsAuthentication() 0 63 9
A registerRecoveryTokenSms() 0 12 1
A selfAssertedTokenRegistration() 0 43 4
A registerRecoveryTokenSmsProofOfPossession() 0 12 1
A newRecoveryToken() 0 24 3
C selfAssertedTokenRegistrationRecoveryToken() 0 78 11
1
<?php
2
3
/**
4
 * Copyright 2022 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
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
Coding Style introduced by
Missing @link tag in file comment
Loading history...
18
19
namespace Surfnet\StepupSelfService\SelfServiceBundle\Controller;
20
21
use Psr\Log\LoggerInterface;
22
use Surfnet\StepupBundle\Service\LoaResolutionService;
23
use Surfnet\StepupBundle\Value\PhoneNumber\InternationalPhoneNumber;
24
use Surfnet\StepupSelfService\SelfServiceBundle\Command\PromiseSafeStorePossessionCommand;
25
use Surfnet\StepupSelfService\SelfServiceBundle\Command\SafeStoreAuthenticationCommand;
26
use Surfnet\StepupSelfService\SelfServiceBundle\Command\SelfAssertedTokenRegistrationCommand;
27
use Surfnet\StepupSelfService\SelfServiceBundle\Command\SendRecoveryTokenSmsAuthenticationChallengeCommand;
28
use Surfnet\StepupSelfService\SelfServiceBundle\Command\VerifySmsRecoveryTokenChallengeCommand;
29
use Surfnet\StepupSelfService\SelfServiceBundle\Form\Type\AuthenticateSafeStoreType;
30
use Surfnet\StepupSelfService\SelfServiceBundle\Form\Type\PromiseSafeStorePossessionType;
31
use Surfnet\StepupSelfService\SelfServiceBundle\Form\Type\VerifySmsChallengeType;
32
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SecondFactorService;
33
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\AuthenticationRequestFactory;
34
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\RecoveryTokenService;
35
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SelfAssertedTokens\SafeStoreService;
36
use Surfnet\StepupSelfService\SelfServiceBundle\Service\SmsRecoveryTokenService;
37
use Symfony\Component\HttpFoundation\Request;
38
use Symfony\Component\HttpFoundation\Response;
39
use Symfony\Component\Routing\Annotation\Route;
40
41
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
42
 *
43
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
44
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
45
 */
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...
46
class SelfAssertedTokensController extends Controller
47
{
48
    use RecoveryTokenControllerTrait;
0 ignored issues
show
Bug introduced by
The trait Surfnet\StepupSelfServic...eryTokenControllerTrait requires the property $id which is not provided by Surfnet\StepupSelfServic...ssertedTokensController.
Loading history...
49
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
50
     * @var RecoveryTokenService
51
     */
52
    private $recoveryTokenService;
0 ignored issues
show
Coding Style introduced by
Private member variable "recoveryTokenService" must be prefixed with an underscore
Loading history...
53
54
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
55
     * @var SecondFactorService
56
     */
57
    private $secondFactorService;
0 ignored issues
show
Coding Style introduced by
Private member variable "secondFactorService" must be prefixed with an underscore
Loading history...
58
59
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
60
     * @var SmsRecoveryTokenService
61
     */
62
    private $smsService;
0 ignored issues
show
Coding Style introduced by
Private member variable "smsService" must be prefixed with an underscore
Loading history...
63
64
    public function __construct(
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
65
        RecoveryTokenService $recoveryTokenService,
66
        private readonly SafeStoreService $safeStoreService,
67
        SecondFactorService $secondFactorService,
68
        SmsRecoveryTokenService $smsService,
69
        private readonly LoaResolutionService $loaResolutionService,
70
        private readonly AuthenticationRequestFactory $authnRequestFactory,
71
        private readonly LoggerInterface $logger
72
    ) {
73
        $this->recoveryTokenService = $recoveryTokenService;
74
        $this->secondFactorService = $secondFactorService;
75
        $this->smsService = $smsService;
76
    }
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $secondFactorId should have a doc-comment as per coding-style.
Loading history...
79
     * Self-asserted token registration: Registration entrypoint
80
     *
81
     * Select(s) the recovery token to perform the self-asserted second factor
82
     * token registration with.
83
     *
84
     * Possible outcomes:
85
     * 1. Shows a recovery token selection screen when more than one token are available
86
     * 2. Selects the one and only available recovery token and redirects to the recovery token authentication route
87
     * 3. Starts registration of a recovery token if non are in possession
88
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
89
    #[Route(
90
        path: '/second-factor/{secondFactorId}/self-asserted-token-registration',
91
        name: 'ss_second_factor_self_asserted_tokens',
92
        methods: ['GET'],
93
    )]
94
    public function selfAssertedTokenRegistration(string $secondFactorId): Response
95
    {
96
        $this->logger->info('Checking if Identity has a recovery token');
97
        $identity = $this->getIdentity();
98
        $this->assertSecondFactorInPossession($secondFactorId, $identity);
99
        $secondFactor = $this->secondFactorService->findOneVerified($secondFactorId);
100
        if ($this->recoveryTokenService->hasRecoveryToken($identity)) {
101
            $tokens = $this->recoveryTokenService->getAvailableTokens($identity, $secondFactor);
0 ignored issues
show
Bug introduced by
It seems like $secondFactor can also be of type null; however, parameter $secondFactor of Surfnet\StepupSelfServic...e::getAvailableTokens() does only seem to accept Surfnet\StepupMiddleware...to\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

101
            $tokens = $this->recoveryTokenService->getAvailableTokens($identity, /** @scrutinizer ignore-type */ $secondFactor);
Loading history...
102
            if ($tokens === []) {
103
                // User is in possession of a recovery token, but it is not safe to use here (for example sms recovery
104
                // token is not available while activating a SMS second factor)
105
                $this->addFlash('error', 'ss.self_asserted_tokens.second_factor.no_available_recovery_token.alert.failed');
106
                return $this->redirectToRoute('ss_second_factor_list');
107
            }
108
            if (count($tokens) > 1) {
109
                $this->logger->info('Show recovery token selection screen');
110
                return $this->render(
111
                    '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/select_available_recovery_token.html.twig',
112
                    [
113
                        'secondFactorId' => $secondFactorId,
114
                        'showAvailable' => true,
115
                        'availableRecoveryTokens' => $tokens,
116
                    ]
117
                );
118
            }
119
            $this->logger->info('Continue to recovery token authentication screen for the one available recovery token');
120
            $token = reset($tokens);
121
            return $this->redirect($this->generateUrl(
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
122
                'ss_second_factor_self_asserted_tokens_recovery_token',
123
                [
124
                    'secondFactorId' => $secondFactorId,
125
                    'recoveryTokenId' => $token->recoveryTokenId
126
                ]
127
            ));
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
128
        }
129
        $this->logger->info('Start registration of a recovery token (none are available yet)');
130
        return $this->redirect(
131
            $this->generateUrl('ss_second_factor_new_recovery_token', ['secondFactorId' => $secondFactorId])
132
        );
133
    }
134
135
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request 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 $recoveryTokenId should have a doc-comment as per coding-style.
Loading history...
136
     * Self-asserted token registration: Authenticate recovery token
137
     *
138
     * Identity must authenticate the recovery token in order to perform a
139
     * self-asserted token registration. But only when this action is
140
     * performed while recovering a Second Factor token. During initial
141
     * registration of a recovery token in the self-asserted token registration
142
     * flow, authentication is not required.
143
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
144
    #[Route(
145
        path: '/second-factor/{secondFactorId}/self-asserted-token-registration/{recoveryTokenId}',
146
        name: 'ss_second_factor_self_asserted_tokens_recovery_token',
147
        methods: ['GET','POST']
148
    )]
149
    public function selfAssertedTokenRegistrationRecoveryToken(
150
        Request $request,
151
        string $secondFactorId,
152
        string $recoveryTokenId
153
    ): Response {
154
        $this->logger->info('Start authentication of recovery token to perform self-asserted token registration');
155
        $identity = $this->getIdentity();
156
        $this->assertSecondFactorInPossession($secondFactorId, $identity);
157
        $this->assertRecoveryTokenInPossession($recoveryTokenId, $identity);
158
        $token = $this->recoveryTokenService->getRecoveryToken($recoveryTokenId);
159
160
        switch ($token->type) {
161
            case "sms":
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
162
                if ($this->smsService->wasTokenCreatedDuringSecondFactorRegistration()) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
163
                    // Forget we created the recovery token during token registration. Next time Identity
164
                    // must fill its password.
165
                    $this->smsService->forgetTokenCreatedDuringSecondFactorRegistration();
166
                    $secondFactor = $this->secondFactorService->findOneVerified($secondFactorId);
167
168
                    $command = new SelfAssertedTokenRegistrationCommand();
169
                    $command->identity = $this->getIdentity();
170
                    $command->secondFactor = $secondFactor;
171
                    $command->recoveryTokenId = $recoveryTokenId;
172
173
                    if ($this->secondFactorService->registerSelfAssertedToken($command)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
174
                        $this->addFlash('success', 'ss.self_asserted_tokens.second_factor.alert.successful');
175
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
176
                        $this->addFlash('error', 'ss.self_asserted_tokens.second_factor.alert.failed');
177
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
178
                    return $this->redirectToRoute('ss_second_factor_list');
179
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
180
                $number = InternationalPhoneNumber::fromStringFormat($token->identifier);
181
                $command = new SendRecoveryTokenSmsAuthenticationChallengeCommand();
182
                $command->identifier = $number;
183
                $command->institution = $identity->institution;
184
                $command->recoveryTokenId = $recoveryTokenId;
185
                $command->identity = $identity->id;
186
                $this->smsService->authenticate($command);
187
                return $this->redirectToRoute(
188
                    'ss_second_factor_self_asserted_tokens_recovery_token_sms',
189
                    ['secondFactorId' => $secondFactorId, 'recoveryTokenId' => $recoveryTokenId]
190
                );
191
            case "safe-store":
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
192
                // No authentication of the safe store token is required if created during SF token registration
193
                if ($this->safeStoreService->wasSafeStoreTokenCreatedDuringSecondFactorRegistration()) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
194
                    // Forget we created the safe-store recovery token during token registration. Next time Identity
195
                    // must fill its password.
196
                    $this->safeStoreService->forgetSafeStoreTokenCreatedDuringSecondFactorRegistration();
197
                    if ($this->invokeSelfAssertedTokenRegistrationCommand($secondFactorId, $recoveryTokenId)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
198
                        $this->addFlash('success', 'ss.self_asserted_tokens.second_factor.vetting.alert.successful');
199
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
200
                        $this->addFlash('error', 'ss.self_asserted_tokens.second_factor.vetting.alert.failed');
201
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
202
                    return $this->redirectToRoute('ss_second_factor_list');
203
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
204
                $command = new SafeStoreAuthenticationCommand();
205
                $command->recoveryToken = $token;
206
                $command->identity = $identity;
207
                $form = $this->createForm(AuthenticateSafeStoreType::class, $command)->handleRequest($request);
208
                if ($form->isSubmitted() && $form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
209
                    if ($this->recoveryTokenService->authenticateSafeStore($command)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
210
                        if ($this->invokeSelfAssertedTokenRegistrationCommand($secondFactorId, $recoveryTokenId)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
211
                            $this->addFlash('success', 'ss.self_asserted_tokens.second_factor.vetting.alert.successful');
212
                            return $this->redirectToRoute('ss_second_factor_list');
213
                        }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
214
                        $this->addFlash('error', 'ss.self_asserted_tokens.second_factor.vetting.alert.failed');
215
                    } else {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
216
                        $this->addFlash('error', 'ss.self_asserted_tokens.safe_store.authentication.alert.failed');
217
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
218
                }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
219
                return $this->render(
220
                    '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/authenticate_safe_store.html.twig',
221
                    ['form' => $form->createView()]
222
                );
223
        }
224
    }
225
226
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $secondFactorId should have a doc-comment as per coding-style.
Loading history...
227
     * Self-asserted token registration: choose recovery token type
228
     *
229
     * The user can select which recovery token to add. Some limitations may
230
     * apply. For example, using a SMS Recovery Token for registration of an
231
     * SMS Second Factor is only allowed when different phone numbers are used.
232
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
233
    #[Route(
234
        path: '/second-factor/{secondFactorId}/new-recovery-token',
235
        name: 'ss_second_factor_new_recovery_token',
236
        methods: ['GET']
237
    )]
238
    public function newRecoveryToken(string $secondFactorId): \Symfony\Component\HttpFoundation\Response
239
    {
240
        $this->logger->info('Determining which recovery token are available');
241
        $identity = $this->getIdentity();
242
        $this->assertSecondFactorInPossession($secondFactorId, $identity);
243
        $this->assertNoRecoveryTokens($identity);
244
245
        $secondFactor = $this->secondFactorService->findOneVerified($secondFactorId);
246
        $availableRecoveryTokens = $this->recoveryTokenService->getRemainingTokenTypes($identity);
247
        if ($secondFactor && $secondFactor->type === 'sms') {
248
            $this->logger->notice('SMS recovery token type is not allowed as we are vetting a SMS second factor');
249
            unset($availableRecoveryTokens['sms']);
250
        }
251
252
        return $this->render(
253
            '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/new_recovery_token.html.twig',
254
            [
255
                'secondFactorId' => $secondFactorId,
256
                'availableRecoveryTokens' => $availableRecoveryTokens
257
            ]
258
        );
259
    }
260
261
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request 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 $recoveryTokenId should have a doc-comment as per coding-style.
Loading history...
262
     * Self-asserted token registration: Authenticate a SMS recovery token
263
     *
264
     * The previous action (selfAssertedTokenRegistrationRecoveryTokenAction)
265
     * sent the Identity a OTP via SMS. The Identity must reproduce that OTP
266
     * in this action. Proving possession of the recovery token.
267
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
268
    #[Route(
269
        path: '/second-factor/{secondFactorId}/self-asserted-token-registration/{recoveryTokenId}/authenticate',
270
        name: 'ss_second_factor_self_asserted_tokens_recovery_token_sms',
271
        methods: ['GET','POST']
272
    )]
273
    public function selfAssertedTokenRecoveryTokenSmsAuthentication(
274
        Request $request,
275
        string $secondFactorId,
276
        string $recoveryTokenId
277
    ): Response {
278
        $identity = $this->getIdentity();
279
        $this->assertSecondFactorInPossession($secondFactorId, $identity);
280
        $this->assertRecoveryTokenInPossession($recoveryTokenId, $identity);
281
282
        // Then render the authentication (proof of possession screen
283
        if (!$this->smsService->hasSmsVerificationState($recoveryTokenId)) {
284
            $this->get('session')->getFlashBag()->add('notice', 'ss.registration.sms.alert.no_verification_state');
0 ignored issues
show
Bug introduced by
The method get() does not exist on Surfnet\StepupSelfServic...ssertedTokensController. ( Ignorable by Annotation )

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

284
            $this->/** @scrutinizer ignore-call */ 
285
                   get('session')->getFlashBag()->add('notice', 'ss.registration.sms.alert.no_verification_state');

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...
285
            return $this->redirectToRoute(
286
                'ss_second_factor_self_asserted_tokens',
287
                ['secondFactorId' => $secondFactorId]
288
            );
289
        }
290
291
        $secondFactor = $this->secondFactorService->findOneVerified($secondFactorId);
292
293
        $command = new VerifySmsRecoveryTokenChallengeCommand();
294
        $command->identity = $identity->id;
295
        $command->resendRouteParameters = ['secondFactorId' => $secondFactorId, 'recoveryTokenId' => $recoveryTokenId];
296
297
        $form = $this->createForm(VerifySmsChallengeType::class, $command)->handleRequest($request);
298
299
        if ($form->isSubmitted() && $form->isValid()) {
300
            $command->recoveryTokenId = $recoveryTokenId;
301
            $result = $this->smsService->verifyAuthentication($command);
302
            if ($result->authenticated()) {
303
                $this->smsService->clearSmsVerificationState($recoveryTokenId);
304
305
                $command = new SelfAssertedTokenRegistrationCommand();
306
                $command->identity = $this->getIdentity();
307
                $command->secondFactor = $secondFactor;
308
                $command->recoveryTokenId = $recoveryTokenId;
309
310
                if ($this->secondFactorService->registerSelfAssertedToken($command)) {
311
                    $this->addFlash('success', 'ss.self_asserted_tokens.second_factor.alert.successful');
312
                } else {
313
                    $this->addFlash('error', 'ss.self_asserted_tokens.second_factor.alert.failed');
314
                }
315
316
                return $this->redirectToRoute('ss_second_factor_list');
317
            } elseif ($result->wasIncorrectChallengeResponseGiven()) {
318
                $this->addFlash('error', 'ss.prove_phone_possession.incorrect_challenge_response');
319
            } elseif ($result->hasChallengeExpired()) {
320
                $this->addFlash('error', 'ss.prove_phone_possession.challenge_expired');
321
            } elseif ($result->wereTooManyAttemptsMade()) {
322
                $this->addFlash('error', 'ss.prove_phone_possession.too_many_attempts');
323
            } else {
324
                $this->addFlash('error', 'ss.prove_phone_possession.proof_of_possession_failed');
325
            }
326
        }
327
        return $this->render(
328
            '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/registration_sms_prove_possession.html.twig',
329
            [
330
                'form' => $form->createView(),
331
            ]
332
        );
333
    }
334
335
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request 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...
336
     * Self-asserted token registration: Create Recovery Token (safe-store)
337
     *
338
     * Shows the one-time secret and asks the Identity to store the
339
     * password in a safe location.
340
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
341
    #[Route(
342
        path: '/second-factor/{secondFactorId}/safe-store',
343
        name: 'ss_registration_recovery_token_safe_store',
344
        methods: ['GET','POST']
345
    )]
346
    public function registerCreateRecoveryTokenSafeStore(Request $request, string $secondFactorId): \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
347
    {
348
        $identity = $this->getIdentity();
349
        $this->assertSecondFactorInPossession($secondFactorId, $identity);
350
        $this->assertNoRecoveryTokenOfType('safe-store', $identity);
351
352
        $secret = $this->safeStoreService->produceSecret();
353
        $command = new PromiseSafeStorePossessionCommand();
354
355
        $form = $this->createForm(PromiseSafeStorePossessionType::class, $command)->handleRequest($request);
356
357
        if ($form->isSubmitted() && $form->isValid()) {
358
            $command->secret = $secret;
359
            $command->identity = $this->getIdentity();
360
361
            $executionResult = $this->safeStoreService->promisePossession($command);
362
            if (!$executionResult->getErrors()) {
363
                return $this->redirect(
364
                    $this->generateUrl('ss_second_factor_self_asserted_tokens', ['secondFactorId' => $secondFactorId])
365
                );
366
            }
367
            $this->addFlash('error', 'ss.form.recovery_token.error.error_message');
368
        }
369
370
        return $this->render(
371
            '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/recovery_token_safe_store.html.twig',
372
            [
373
                'form' => $form->createView(),
374
                'secondFactorId' => $secondFactorId,
375
                'secret' => $secret,
376
            ]
377
        );
378
    }
379
380
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request 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...
381
     * Self-asserted token registration: Create the SMS recovery token
382
     * Step 1: Send an OTP to phone of Identity
383
     *
384
     * Note: Shares logic with the recovery token SMS send challenge action
385
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
386
    #[Route(
387
        path: '/second-factor/{secondFactorId}/sms',
388
        name: 'ss_registration_recovery_token_sms',
389
        methods: ['GET','POST'],
390
    )]
391
    public function registerRecoveryTokenSms(Request $request, string $secondFactorId): \Symfony\Component\HttpFoundation\Response
392
    {
393
        return $this->handleSmsChallenge(
394
            $request,
395
            '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/recovery_token_sms.html.twig',
396
            'ss_registration_recovery_token_sms_proof_of_possession',
397
            $secondFactorId
398
        );
399
    }
400
401
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request 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...
402
     * Self-asserted token registration: Create the SMS recovery token
403
     * Step 2: Process proof of phone possession of Identity
404
     *
405
     * Note: Shares logic with the recovery token SMS send challenge action
406
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
407
    #[Route(
408
        path: '/recovery-token/{secondFactorId}/prove-sms-possession',
409
        name: 'ss_registration_recovery_token_sms_proof_of_possession',
410
        methods: ['GET', 'POST']
411
    )]
412
    public function registerRecoveryTokenSmsProofOfPossession(Request $request, string $secondFactorId)
413
    {
414
        return $this->handleSmsProofOfPossession(
415
            $request,
416
            '@SurfnetStepupSelfServiceSelfService/registration/self_asserted_tokens/registration_sms_prove_possession.html.twig',
417
            'ss_second_factor_self_asserted_tokens',
418
            $secondFactorId
419
        );
420
    }
421
422
    private function invokeSelfAssertedTokenRegistrationCommand(string $secondFactorId, string $recoveryTokenId): bool
0 ignored issues
show
Coding Style introduced by
Private method name "SelfAssertedTokensController::invokeSelfAssertedTokenRegistrationCommand" must be prefixed with an underscore
Loading history...
Coding Style introduced by
Missing doc comment for function invokeSelfAssertedTokenRegistrationCommand()
Loading history...
423
    {
424
        $secondFactor = $this->secondFactorService->findOneVerified($secondFactorId);
425
        $command = new SelfAssertedTokenRegistrationCommand();
426
        $command->identity = $this->getIdentity();
427
        $command->secondFactor = $secondFactor;
428
        $command->recoveryTokenId = $recoveryTokenId;
429
        return $this->secondFactorService->registerSelfAssertedToken($command);
430
    }
431
}
432