validateInput()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 4
nop 1
dl 0
loc 14
rs 9.9666
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\MiddlewareBundle\Console\Command;
20
21
use Assert\Assertion;
22
use DateInterval;
23
use DateTime;
24
use Exception;
25
use InvalidArgumentException;
26
use Psr\Log\LoggerInterface;
27
use Ramsey\Uuid\Uuid;
28
use Surfnet\StepupMiddleware\CommandHandlingBundle\EventHandling\BufferedEventBus;
29
use Surfnet\StepupMiddleware\CommandHandlingBundle\Identity\Command\SendVerifiedSecondFactorRemindersCommand;
30
use Surfnet\StepupMiddleware\CommandHandlingBundle\Pipeline\TransactionAwarePipeline;
31
use Surfnet\StepupMiddleware\MiddlewareBundle\Service\DBALConnectionHelper;
32
use Symfony\Component\Console\Command\Command;
33
use Symfony\Component\Console\Input\InputInterface;
34
use Symfony\Component\Console\Input\InputOption;
35
use Symfony\Component\Console\Output\OutputInterface;
36
37
/**
38
 * The EmailVerifiedSecondFactorRemindersCommand can be run to send reminders to token registrants.
39
 *
40
 * The command utilizes a specific service for this task (VerifiedSecondFactorReminderService). Input validation is
41
 * performed on the incoming request parameters.
42
 *
43
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
44
 */
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...
45
final class EmailVerifiedSecondFactorRemindersCommand extends Command
46
{
47
    protected static $defaultName = 'middleware:cron:email-reminder';
48
49
    protected function configure(): void
50
    {
51
        $this
52
            ->setDescription('Sends email reminders to identities with verified tokens more than 7 days old.')
53
            ->addOption(
54
                'dry-run',
55
                null,
56
                InputOption::VALUE_NONE,
57
                'Run in dry mode, not sending any email',
58
            )
59
            ->addOption(
60
                'date',
61
                null,
62
                InputOption::VALUE_OPTIONAL,
63
                'The date (Y-m-d) that should be used for sending reminder email messages, defaults to TODAY - 7',
64
            );
65
    }
66
67
    public function __construct(
68
        private readonly TransactionAwarePipeline $pipeline,
69
        private readonly BufferedEventBus $eventBus,
70
        private readonly DBALConnectionHelper $connection,
71
        private readonly LoggerInterface $logger,
72
    ) {
73
        parent::__construct();
74
    }
75
76
    protected function execute(InputInterface $input, OutputInterface $output): int
77
    {
78
        try {
79
            $this->validateInput($input);
80
        } catch (InvalidArgumentException $e) {
81
            $output->writeln('<error>' . $e->getMessage() . '</error>');
82
            $this->logger->error(sprintf('Invalid arguments passed to the %s', $this->getName()), [$e->getMessage()]);
83
            return 1;
84
        }
85
86
        $date = new DateTime();
87
        $date->sub(new DateInterval('P7D'));
88
        if ($input->hasOption('date') && !is_null($input->getOption('date'))) {
89
            $receivedDate = $input->getOption('date');
90
            $date = DateTime::createFromFormat('Y-m-d', $receivedDate);
91
            if ($date === false) {
92
                $output->writeln(
93
                    sprintf(
94
                        '<error>Error processing the "date" option. Please review the received input: "%s" </error>',
95
                        $receivedDate
96
                    )
97
                );
98
                return 1;
99
            }
100
        }
101
102
        $dryRun = false;
103
        if ($input->hasOption('dry-run') && !is_null($input->getOption('dry-run'))) {
104
            $dryRun = $input->getOption('dry-run');
105
        }
106
107
        $command = new SendVerifiedSecondFactorRemindersCommand();
108
        $command->requestedAt = $date;
109
        $command->dryRun = $dryRun;
110
        $command->UUID = Uuid::uuid4()->toString();
111
112
        $this->connection->beginTransaction();
113
        try {
114
            $this->pipeline->process($command);
115
            $this->eventBus->flush();
116
117
            $this->connection->commit();
118
        } catch (Exception $e) {
119
            $output->writeln('<error>An Error occurred while sending reminder email messages.</error>');
120
            $this->connection->rollBack();
121
            throw $e;
122
        }
123
        return 0;
124
    }
125
126
    private function validateInput(InputInterface $input): void
0 ignored issues
show
Coding Style introduced by
Private method name "EmailVerifiedSecondFactorRemindersCommand::validateInput" must be prefixed with an underscore
Loading history...
127
    {
128
        if ($input->hasOption('date')) {
129
            $date = $input->getOption('date');
130
            Assertion::nullOrDate(
131
                $date,
132
                'Y-m-d',
133
                'Expected date to be a string and formatted in the Y-m-d date format',
134
            );
135
        }
136
137
        if ($input->hasOption('dry-run')) {
138
            $dryRun = $input->getOption('dry-run');
139
            Assertion::nullOrBoolean($dryRun, 'Expected dry-run parameter to be a boolean value.');
140
        }
141
    }
142
}
143