ChangePassphraseCommand   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 50
c 1
b 0
f 0
dl 0
loc 108
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A execute() 0 31 3
A interact() 0 37 6
A configure() 0 7 1
A __construct() 0 6 1
1
<?php
2
3
namespace BenTools\Shh\Command;
4
5
use BenTools\Shh\Shh;
6
use Symfony\Component\Console\Attribute\AsCommand;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Style\SymfonyStyle;
12
use Symfony\Component\Filesystem\Filesystem;
13
14
#[AsCommand(
15
    name: 'shh:change:passphrase',
16
)]
17
final class ChangePassphraseCommand extends Command
18
{
19
    /**
20
     * @var Filesystem
21
     */
22
    private $fs;
23
24
    /**
25
     * @var string
26
     */
27
    private $keysDir;
28
29
    /**
30
     * @var string|null
31
     */
32
    private $privateKey;
33
34
    public function __construct(Filesystem $fs, string $keysDir, ?string $privateKey)
35
    {
36
        parent::__construct();
37
        $this->fs = $fs;
38
        $this->keysDir = $keysDir;
39
        $this->privateKey = $privateKey;
40
    }
41
42
    protected function configure(): void
43
    {
44
        $this
45
            ->setDescription('Change passphrase, generate a new private key.')
46
            ->addOption('old-passphrase', '', InputOption::VALUE_OPTIONAL, 'Your current passhrase.')
47
            ->addOption('new-passphrase', '', InputOption::VALUE_OPTIONAL, '(Optional) your new passhrase.')
48
            ->addOption('overwrite', '', InputOption::VALUE_NONE, 'Overwrite the existing key.')
49
        ;
50
    }
51
52
    protected function interact(InputInterface $input, OutputInterface $output): void
53
    {
54
        $io = new SymfonyStyle($input, $output);
55
56
        if (null === $input->getOption('old-passphrase')) {
57
            $input->setOption('old-passphrase', $io->askHidden(
58
                'Enter your old passphrase:',
59
                function ($passphrase) {
60
61
                    if (0 === \strlen($passphrase)) {
62
                        return null;
63
                    }
64
65
                    return $passphrase;
66
                }
67
            ));
68
        }
69
70
        if (null === $input->getOption('new-passphrase')) {
71
            $input->setOption('new-passphrase', $io->askHidden(
72
                'Enter your new passphrase:',
73
                function ($passphrase) use ($io) {
74
75
                    if (0 === \strlen($passphrase)) {
76
                        return null;
77
                    }
78
79
                    if ($passphrase !== $io->askHidden('Confirm:')) {
80
                        throw new \InvalidArgumentException("Both passphrases don't match.");
81
                    }
82
83
                    return $passphrase;
84
                }
85
            ));
86
        }
87
88
        $input->setOption('overwrite', $io->confirm('Overwrite current private key?'));
89
    }
90
91
    protected function execute(InputInterface $input, OutputInterface $output): int
92
    {
93
        $io = new SymfonyStyle($input, $output);
94
95
        if (null === $this->privateKey) {
96
            $io->error('Private key was not found.');
97
98
            return 1;
99
        }
100
101
        $passphrase = $input->getOption('new-passphrase');
102
        $dir = $this->keysDir;
103
104
        $oldPrivateKey = $this->privateKey;
105
        $newPrivateKey = Shh::changePassphrase($oldPrivateKey, $input->getOption('old-passphrase'), $passphrase);
106
107
        $io->comment('Here is your new private key:');
108
109
        $io->writeln($newPrivateKey);
110
111
        if (true === $input->getOption('overwrite')) {
112
            $this->fs->dumpFile($dir . '/private.pem', $newPrivateKey);
113
            $io->success(\sprintf('%s was successfully updated.', $dir . '/private.pem'));
114
        }
115
116
        $io->caution(
117
            'Don\'t forget to report your new passphrase into the SHH_PASSPHRASE environment variable, 
118
        and to deploy the new private key to everywhere it\'s needed!'
119
        );
120
121
        return 0;
122
    }
123
}
124