Code Duplication    Length = 117-117 lines in 2 locations

src/Surfnet/StepupMiddleware/MiddlewareBundle/Console/Command/BootstrapSmsSecondFactorCommand.php 1 location

@@ 33-149 (lines=117) @@
30
use Symfony\Component\Console\Output\OutputInterface;
31
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
32
33
final class BootstrapSmsSecondFactorCommand extends AbstractBootstrapCommand
34
{
35
    protected function configure()
36
    {
37
        $this
38
            ->setDescription('Creates a SMS second factor for a specified user')
39
            ->addArgument('name-id', InputArgument::REQUIRED, 'The NameID of the identity to create')
40
            ->addArgument('institution', InputArgument::REQUIRED, 'The institution of the identity to create')
41
            ->addArgument(
42
                'phone-number',
43
                InputArgument::REQUIRED,
44
                'The phone number of the user should be formatted like "+31 (0) 612345678"'
45
            )
46
            ->addArgument(
47
                'registration-status',
48
                InputArgument::REQUIRED,
49
                'Valid arguments: unverified, verified, vetted'
50
            )
51
            ->addArgument('actor-id', InputArgument::REQUIRED, 'The id of the vetting actor');
52
    }
53
54
    protected function execute(InputInterface $input, OutputInterface $output)
55
    {
56
        $this->tokenStorage->setToken(
57
            new AnonymousToken('cli.bootstrap-sms-token', 'cli', ['ROLE_SS', 'ROLE_RA'])
58
        );
59
        $nameId = new NameId($input->getArgument('name-id'));
60
        $institutionText = $input->getArgument('institution');
61
        $institution = new Institution($institutionText);
62
        $mailVerificationRequired = $this->requiresMailVerification($institutionText);
63
        $registrationStatus = $input->getArgument('registration-status');
64
        $phoneNumber = $input->getArgument('phone-number');
65
        $actorId = $input->getArgument('actor-id');
66
        $this->enrichEventMetadata($actorId);
67
        if (!$this->tokenBootstrapService->hasIdentityWithNameIdAndInstitution($nameId, $institution)) {
68
            $output->writeln(
69
                sprintf(
70
                    '<error>An identity with name ID "%s" from institution "%s" does not exist, create it first.</error>',
71
                    $nameId->getNameId(),
72
                    $institution->getInstitution()
73
                )
74
            );
75
76
            return;
77
        }
78
        $identity = $this->tokenBootstrapService->findOneByNameIdAndInstitution($nameId, $institution);
79
        $output->writeln(sprintf('<comment>Adding a %s SMS token for %s</comment>', $registrationStatus, $identity->commonName));
80
        $this->beginTransaction();
81
        $secondFactorId = Uuid::uuid4()->toString();
82
83
        try {
84
            switch ($registrationStatus) {
85
                case "unverified":
86
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
87
                    $this->provePossession($secondFactorId, $identity, $phoneNumber);
88
                    break;
89
                case "verified":
90
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
91
                    $this->provePossession($secondFactorId, $identity, $phoneNumber);
92
                    $unverifiedSecondFactor = $this->tokenBootstrapService->findUnverifiedToken($identity->id, 'sms');
93
                    if ($mailVerificationRequired) {
94
                        $output->writeln('<comment>Creating a verified SMS token</comment>');
95
                        $this->verifyEmail($identity, $unverifiedSecondFactor);
96
                    }
97
                    break;
98
                case "vetted":
99
                    $output->writeln('<comment>Creating an unverified SMS token</comment>');
100
                    $this->provePossession($secondFactorId, $identity, $phoneNumber);
101
                    /** @var UnverifiedSecondFactor $unverifiedSecondFactor */
102
                    $unverifiedSecondFactor = $this->tokenBootstrapService->findUnverifiedToken($identity->id, 'sms');
103
                    if ($mailVerificationRequired) {
104
                        $output->writeln('<comment>Creating a verified SMS token</comment>');
105
                        $this->verifyEmail($identity, $unverifiedSecondFactor);
106
                    }
107
                    $verifiedSecondFactor = $this->tokenBootstrapService->findVerifiedToken($identity->id, 'sms');
108
                    $output->writeln('<comment>Vetting the verified SMS token</comment>');
109
                    $this->vetSecondFactor(
110
                        'sms',
111
                        $actorId,
112
                        $identity,
113
                        $secondFactorId,
114
                        $verifiedSecondFactor,
115
                        $phoneNumber
116
                    );
117
                    break;
118
            }
119
            $this->finishTransaction();
120
        } catch (Exception $e) {
121
            $output->writeln(
122
                sprintf(
123
                    '<error>An Error occurred when trying to bootstrap the SMS token: "%s"</error>',
124
                    $e->getMessage()
125
                )
126
            );
127
            $this->rollback();
128
            throw $e;
129
        }
130
        $output->writeln(
131
            sprintf(
132
                '<info>Successfully registered a SMS token with UUID %s</info>',
133
                $identity->id,
134
                $registrationStatus,
135
                $secondFactorId
136
            )
137
        );
138
    }
139
140
    private function provePossession($secondFactorId, $identity, $phoneNumber)
141
    {
142
        $command = new ProvePhonePossessionCommand();
143
        $command->UUID = (string)Uuid::uuid4();
144
        $command->secondFactorId = $secondFactorId;
145
        $command->identityId = $identity->id;
146
        $command->phoneNumber = $phoneNumber;
147
        $this->process($command);
148
    }
149
}
150

src/Surfnet/StepupMiddleware/MiddlewareBundle/Console/Command/BootstrapYubikeySecondFactorCommand.php 1 location

@@ 32-148 (lines=117) @@
29
use Symfony\Component\Console\Output\OutputInterface;
30
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
31
32
final class BootstrapYubikeySecondFactorCommand extends AbstractBootstrapCommand
33
{
34
    protected function configure()
35
    {
36
        $this
37
            ->setDescription('Creates a Yubikey second factor for a specified user')
38
            ->addArgument('name-id', InputArgument::REQUIRED, 'The NameID of the identity to create')
39
            ->addArgument('institution', InputArgument::REQUIRED, 'The institution of the identity to create')
40
            ->addArgument(
41
                'yubikey',
42
                InputArgument::REQUIRED,
43
                'The public ID of the Yubikey. Remove the last 32 characters of a Yubikey OTP to acquire this.'
44
            )
45
            ->addArgument(
46
                'registration-status',
47
                InputArgument::REQUIRED,
48
                'Valid arguments: unverified, verified, vetted'
49
            )
50
            ->addArgument('actor-id', InputArgument::REQUIRED, 'The id of the vetting actor');
51
    }
52
53
    protected function execute(InputInterface $input, OutputInterface $output)
54
    {
55
        $this->tokenStorage->setToken(
56
            new AnonymousToken('cli.bootstrap-yubikey-token', 'cli', ['ROLE_SS', 'ROLE_RA'])
57
        );
58
        $nameId = new NameId($input->getArgument('name-id'));
59
        $institutionText = $input->getArgument('institution');
60
        $institution = new Institution($institutionText);
61
        $mailVerificationRequired = $this->requiresMailVerification($institutionText);
62
        $registrationStatus = $input->getArgument('registration-status');
63
        $yubikey = $input->getArgument('yubikey');
64
        $actorId = $input->getArgument('actor-id');
65
        $this->enrichEventMetadata($actorId);
66
        if (!$this->tokenBootstrapService->hasIdentityWithNameIdAndInstitution($nameId, $institution)) {
67
            $output->writeln(
68
                sprintf(
69
                    '<error>An identity with name ID "%s" from institution "%s" does not exist, create it first.</error>',
70
                    $nameId->getNameId(),
71
                    $institution->getInstitution()
72
                )
73
            );
74
75
            return;
76
        }
77
        $identity = $this->tokenBootstrapService->findOneByNameIdAndInstitution($nameId, $institution);
78
        $output->writeln(sprintf('<comment>Adding a %s Yubikey token for %s</comment>', $registrationStatus, $identity->commonName));
79
        $this->beginTransaction();
80
        $secondFactorId = Uuid::uuid4()->toString();
81
82
        try {
83
            switch ($registrationStatus) {
84
                case "unverified":
85
                    $output->writeln('<comment>Creating an unverified Yubikey token</comment>');
86
                    $this->provePossession($secondFactorId, $identity, $yubikey);
87
                    break;
88
                case "verified":
89
                    $output->writeln('<comment>Creating an unverified Yubikey token</comment>');
90
                    $this->provePossession($secondFactorId, $identity, $yubikey);
91
                    $unverifiedSecondFactor = $this->tokenBootstrapService->findUnverifiedToken($identity->id, 'yubikey');
92
                    if ($mailVerificationRequired) {
93
                        $output->writeln('<comment>Creating a verified Yubikey token</comment>');
94
                        $this->verifyEmail($identity, $unverifiedSecondFactor);
95
                    }
96
                    break;
97
                case "vetted":
98
                    $output->writeln('<comment>Creating an unverified Yubikey token</comment>');
99
                    $this->provePossession($secondFactorId, $identity, $yubikey);
100
                    /** @var UnverifiedSecondFactor $unverifiedSecondFactor */
101
                    $unverifiedSecondFactor = $this->tokenBootstrapService->findUnverifiedToken($identity->id, 'yubikey');
102
                    if ($mailVerificationRequired) {
103
                        $output->writeln('<comment>Creating a verified Yubikey token</comment>');
104
                        $this->verifyEmail($identity, $unverifiedSecondFactor);
105
                    }
106
                    $verifiedSecondFactor = $this->tokenBootstrapService->findVerifiedToken($identity->id, 'yubikey');
107
                    $output->writeln('<comment>Vetting the verified Yubikey token</comment>');
108
                    $this->vetSecondFactor(
109
                        'yubikey',
110
                        $actorId,
111
                        $identity,
112
                        $secondFactorId,
113
                        $verifiedSecondFactor,
114
                        $yubikey
115
                    );
116
                    break;
117
            }
118
            $this->finishTransaction();
119
        } catch (Exception $e) {
120
            $output->writeln(
121
                sprintf(
122
                    '<error>An Error occurred when trying to bootstrap the Yubikey token: "%s"</error>',
123
                    $e->getMessage()
124
                )
125
            );
126
            $this->rollback();
127
            throw $e;
128
        }
129
        $output->writeln(
130
            sprintf(
131
                '<info>Successfully created identity with UUID %s and %s second factor with UUID %s</info>',
132
                $identity->id,
133
                $registrationStatus,
134
                $secondFactorId
135
            )
136
        );
137
    }
138
139
    private function provePossession($secondFactorId, $identity, $phoneNumber)
140
    {
141
        $command = new ProveYubikeyPossessionCommand();
142
        $command->UUID = (string)Uuid::uuid4();
143
        $command->secondFactorId = $secondFactorId;
144
        $command->identityId = $identity->id;
145
        $command->yubikeyPublicId = $phoneNumber;
146
        $this->process($command);
147
    }
148
}
149