InitSetupCommand::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * This file is part of the mailserver-admin package.
6
 * (c) Jeffrey Boehm <https://github.com/jeboehm/mailserver-admin>
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace App\Command;
12
13
use App\Entity\Domain;
14
use App\Entity\User;
15
use Doctrine\Persistence\ManagerRegistry;
16
use RuntimeException;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Helper\QuestionHelper;
19
use Symfony\Component\Console\Input\InputInterface;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Console\Question\Question;
22
use Symfony\Component\Validator\ConstraintViolation;
23
use Symfony\Component\Validator\Validator\ValidatorInterface;
24
25
class InitSetupCommand extends Command
26
{
27
    private ValidatorInterface $validator;
28
    private ManagerRegistry $manager;
29
30
    public function __construct(ValidatorInterface $validator, ManagerRegistry $manager)
31
    {
32
        parent::__construct();
33
34
        $this->validator = $validator;
35
        $this->manager = $manager;
36
    }
37
38
    protected function configure(): void
39
    {
40
        $this
41
            ->setName('init:setup')
42
            ->setDescription('Does an initially setup for docker-mailserver.');
43
    }
44
45
    protected function execute(InputInterface $input, OutputInterface $output): int
46
    {
47
        /** @var QuestionHelper $questionHelper */
48
        $questionHelper = $this->getHelper('question');
49
        $output
50
            ->writeln(
51
                [
52
                    '<info>Welcome to docker-mailserver!</info>',
53
                    '<info>This tool will help you to set up the first mail account.</info>',
54
                    '<info>You just have to answer a few questions.</info>',
55
                ]
56
            );
57
58
        [$localPart, $domainPart] = $this->getEmailAddress($questionHelper, $input, $output);
59
        $password = $this->getPassword($questionHelper, $input, $output);
60
61
        $domain = new Domain();
62
        $domain->setName($domainPart);
63
64
        $user = new User();
65
        $user->setName($localPart);
66
        $user->setPlainPassword($password);
67
        $user->setAdmin(true);
68
        $user->setDomain($domain);
69
70
        $domainValidationList = $this->validator->validate($domain);
71
        $userValidationList = $this->validator->validate($user);
72
73
        if ($domainValidationList->count() > 0) {
74
            foreach ($domainValidationList as $item) {
75
                /* @var $item ConstraintViolation */
76
                $output->writeln(
77
                    sprintf('<error>Domain %s: %s</error>', $item->getPropertyPath(), $item->getMessage())
78
                );
79
            }
80
81
            $output->writeln('<error>There were some errors. Please start over again.</error>');
82
83
            return 1;
84
        }
85
86
        if ($userValidationList->count() > 0) {
87
            foreach ($userValidationList as $item) {
88
                /* @var $item ConstraintViolation */
89
                $output->writeln(
90
                    sprintf('<error>User %s: %s</error>', $item->getPropertyPath(), $item->getMessage())
91
                );
92
            }
93
94
            $output->writeln('<error>There were some errors. Please start over again.</error>');
95
96
            return 1;
97
        }
98
99
        $this->manager->getManager()->persist($domain);
100
        $this->manager->getManager()->persist($user);
101
102
        $this->manager->getManager()->flush();
103
104
        $output->writeln(sprintf('<info>Your new email address %s was successfully created.</info>', $user));
105
        $output->writeln('<info>You can now login using the previously set password.</info>');
106
107
        return 0;
108
    }
109
110
    private function getEmailAddress(
111
        QuestionHelper $questionHelper,
112
        InputInterface $input,
113
        OutputInterface $output
114
    ): array {
115
        $emailQuestion = new Question('Please enter the first email address you want to receive mails to: ');
116
        $emailQuestion->setValidator(
117
            function (string $value): string {
118
                if (!$value = \filter_var($value, \FILTER_VALIDATE_EMAIL)) {
119
                    throw new RuntimeException('Please enter a valid email address.');
120
                }
121
122
                return $value;
123
            }
124
        );
125
126
        $email = (string) $questionHelper->ask(
127
            $input,
128
            $output,
129
            $emailQuestion
130
        );
131
132
        return \explode('@', $email);
133
    }
134
135
    private function getPassword(
136
        QuestionHelper $questionHelper,
137
        InputInterface $input,
138
        OutputInterface $output
139
    ): string {
140
        $passwordQuestion = new Question('Enter a password for the new account: ');
141
        $passwordQuestion->setValidator(
142
            function (string $value): string {
143
                if (\mb_strlen($value) < 8) {
144
                    throw new RuntimeException('The password should be longer.');
145
                }
146
147
                return $value;
148
            }
149
        );
150
        $passwordQuestion->setHidden(true);
151
152
        $repeatPasswordQuestion = new Question('Repeat the password: ');
153
        $repeatPasswordQuestion->setHidden(true);
154
155
        $password1 = $questionHelper->ask($input, $output, $passwordQuestion);
156
        $password2 = $questionHelper->ask($input, $output, $repeatPasswordQuestion);
157
158
        if ($password1 !== $password2) {
159
            $output->writeln('<error>The passwords do not match.</error>');
160
161
            return $this->getPassword($questionHelper, $input, $output);
162
        }
163
164
        return (string) $password1;
165
    }
166
}
167