BootstrapSmsSecondFactorCommand   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 107
rs 10
c 0
b 0
f 0
wmc 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 17 1
B execute() 0 79 8
A __construct() 0 5 1
1
<?php
2
3
/**
4
 * Copyright 2020 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\MiddlewareBundle\Console\Command;
20
21
use Exception;
22
use Ramsey\Uuid\Uuid;
23
use Surfnet\Stepup\Identity\Value\Institution;
24
use Surfnet\Stepup\Identity\Value\NameId;
25
use Surfnet\StepupMiddleware\MiddlewareBundle\Service\BootstrapCommandService;
26
use Surfnet\StepupMiddleware\MiddlewareBundle\Service\TransactionHelper;
0 ignored issues
show
Bug introduced by
The type Surfnet\StepupMiddleware...rvice\TransactionHelper 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...
27
use Symfony\Component\Console\Command\Command;
28
use Symfony\Component\Console\Input\InputArgument;
29
use Symfony\Component\Console\Input\InputInterface;
30
use Symfony\Component\Console\Output\OutputInterface;
31
32
final class BootstrapSmsSecondFactorCommand extends Command
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class BootstrapSmsSecondFactorCommand
Loading history...
33
{
34
    public function __construct(
35
        private readonly BootstrapCommandService $bootstrapService,
36
        private readonly TransactionHelper $transactionHelper,
37
    ) {
38
        parent::__construct();
39
    }
40
41
    protected function configure(): void
42
    {
43
        $this
44
            ->setDescription('Creates a SMS second factor for a specified user')
45
            ->addArgument('name-id', InputArgument::REQUIRED, 'The NameID of the identity to create')
46
            ->addArgument('institution', InputArgument::REQUIRED, 'The institution of the identity to create')
47
            ->addArgument(
48
                'phone-number',
49
                InputArgument::REQUIRED,
50
                'The phone number of the user should be formatted like "+31 (0) 612345678"',
51
            )
52
            ->addArgument(
53
                'registration-status',
54
                InputArgument::REQUIRED,
55
                'Valid arguments: unverified, verified, vetted',
56
            )
57
            ->addArgument('actor-id', InputArgument::REQUIRED, 'The id of the vetting actor');
58
    }
59
60
    protected function execute(InputInterface $input, OutputInterface $output): int
61
    {
62
        $registrationStatus = $input->getArgument('registration-status');
63
        $this->bootstrapService->validRegistrationStatus($registrationStatus);
64
65
        $nameId = new NameId($input->getArgument('name-id'));
66
        $institutionText = $input->getArgument('institution');
67
        $institution = new Institution($institutionText);
68
        $mailVerificationRequired = $this->bootstrapService->requiresMailVerification($institutionText);
69
        $phoneNumber = $input->getArgument('phone-number');
70
        $actorId = $input->getArgument('actor-id');
71
        $this->bootstrapService->enrichEventMetadata($actorId);
72
        if (!$this->bootstrapService->identityExists($nameId, $institution)) {
73
            $output->writeln(
74
                sprintf(
75
                    '<error>An identity with name ID "%s" from institution "%s" does not exist, create it first.</error>',
76
                    $nameId->getNameId(),
77
                    $institution->getInstitution(),
78
                ),
79
            );
80
81
            return 1;
82
        }
83
        $identity = $this->bootstrapService->getIdentity($nameId, $institution);
84
        $output->writeln(
85
            sprintf('<comment>Adding a %s SMS token for %s</comment>', $registrationStatus, $identity->commonName),
86
        );
87
        $this->transactionHelper->beginTransaction();
88
        $secondFactorId = Uuid::uuid4()->toString();
89
90
        try {
91
            switch ($registrationStatus) {
92
                case "unverified":
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
93
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
94
                    $this->bootstrapService->provePhonePossession($secondFactorId, $identity, $phoneNumber);
95
                    break;
96
                case "verified":
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
97
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
98
                    $this->bootstrapService->provePhonePossession($secondFactorId, $identity, $phoneNumber);
99
                    if ($mailVerificationRequired) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
100
                        $output->writeln('<comment>Creating a verified SMS token</comment>');
101
                        $this->bootstrapService->verifyEmail($identity, 'sms');
102
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
103
                    break;
104
                case "vetted":
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
105
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
106
                    $this->bootstrapService->provePhonePossession($secondFactorId, $identity, $phoneNumber);
107
                    if ($mailVerificationRequired) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
108
                        $output->writeln('<comment>Creating a verified SMS token</comment>');
109
                        $this->bootstrapService->verifyEmail($identity, 'sms');
110
                    }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
111
                    $output->writeln('<comment>Vetting the verified SMS token</comment>');
112
                    $this->bootstrapService->vetSecondFactor(
113
                        'sms',
114
                        $actorId,
115
                        $identity,
116
                        $secondFactorId,
117
                        $phoneNumber,
118
                    );
119
                    break;
120
            }
121
            $this->transactionHelper->finishTransaction();
122
        } catch (Exception $e) {
123
            $output->writeln(
124
                sprintf(
125
                    '<error>An Error occurred when trying to bootstrap the SMS token: "%s"</error>',
126
                    $e->getMessage(),
127
                ),
128
            );
129
            $this->transactionHelper->rollback();
130
            return 1;
131
        }
132
        $output->writeln(
133
            sprintf(
134
                '<info>Successfully registered a SMS token with UUID %s</info>',
135
                $secondFactorId,
136
            ),
137
        );
138
        return 0;
139
    }
140
}
141