Passed
Push — master ( c708b1...04f164 )
by Peter
02:28
created

SecretGenerator::getEnvFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Opulence
5
 *
6
 * @link      https://www.opulencephp.com
7
 * @copyright Copyright (C) 2017 David Young
8
 * @license   https://github.com/opulencephp/Opulence/blob/master/LICENSE.md
9
 */
10
11
namespace AbterPhp\Framework\Console\Commands\Security;
12
13
use AbterPhp\Framework\Constant\Env;
14
use Defuse\Crypto\Key;
15
use Opulence\Console\Commands\Command;
16
use Opulence\Console\Requests\Option;
17
use Opulence\Console\Requests\OptionTypes;
18
use Opulence\Console\Responses\IResponse;
19
use Opulence\Framework\Configuration\Config;
20
21
/**
22
 * Defines the encryption key generator command
23
 */
24
class SecretGenerator extends Command
25
{
26
    /** @var array */
27
    protected $keys = [
28
        Env::DB_PASSWORD                 => 12,
29
        Env::ENCRYPTION_KEY              => 32,
30
        Env::CRYPTO_FRONTEND_SALT        => 8,
31
        Env::CRYPTO_ENCRYPTION_PEPPER    => 16,
32
        Env::OAUTH2_PRIVATE_KEY_PASSWORD => 16,
33
    ];
34
35
    /** @var null|string */
36
    protected $envFile;
37
38
    /**
39
     * @inheritdoc
40
     */
41
    protected function define()
42
    {
43
        $this->setName('abterphp:generatesecrets')
44
            ->setDescription('Creates secrets for AbterAdmin')
45
            ->addOption(
46
                new Option(
47
                    'show',
48
                    's',
49
                    OptionTypes::NO_VALUE,
50
                    'Whether to just show the new secrets or replace them in the environment config'
51
                )
52
            );
53
    }
54
55
    /**
56
     * @param string $name
57
     * @param int    $length
58
     */
59
    public function addKey(string $name, int $length)
60
    {
61
        $this->keys[$name] = $length;
62
    }
63
64
    /**
65
     * @inheritdoc
66
     */
67
    protected function doExecute(IResponse $response)
68
    {
69
        $maxNameLength = strlen(Env::OAUTH2_ENCRYPTION_KEY);
70
        foreach ($this->keys as $name => $length) {
71
            $maxNameLength = (int)max($maxNameLength, strlen($name));
72
        }
73
74
        foreach ($this->keys as $name => $length) {
75
            $key = \bin2hex(\random_bytes($length));
76
            $this->handleKey($response, $name, $key, $maxNameLength);
77
        }
78
79
        $key = Key::createNewRandomKey()->saveToAsciiSafeString();
80
        $this->handleKey($response, Env::OAUTH2_ENCRYPTION_KEY, $key, $maxNameLength);
81
    }
82
83
    /**
84
     * @return string|null
85
     */
86
    protected function getEnvFile()
87
    {
88
        if (null !== $this->envFile) {
89
            return $this->envFile;
90
        }
91
92
        $fileName = Config::get('paths', 'config') . '/environment/.env.app.php';
93
94
        $this->envFile = '';
95
        if (file_exists($fileName)) {
96
            $this->envFile = $fileName;
97
        }
98
99
        return $this->envFile;
100
    }
101
102
    /**
103
     * @param IResponse $response
104
     * @param string    $name
105
     * @param string    $key
106
     * @param int       $maxNameLength
107
     *
108
     * @throws \Exception
109
     */
110
    protected function handleKey(IResponse $response, string $name, string $key, int $maxNameLength)
111
    {
112
        if (!$this->optionIsSet('show') && $this->getEnvFile()) {
113
            $contents    = file_get_contents($this->getEnvFile());
114
            $newContents = preg_replace(
115
                sprintf("/\"%s\",\s*\"[^\"]*\"/U", $name),
116
                sprintf('"%s", "' . $key . '"', $name),
117
                $contents
118
            );
119
            file_put_contents($this->getEnvFile(), $newContents);
120
        }
121
122
        $pad = str_repeat(' ', $maxNameLength - strlen($name));
123
        $response->writeln("Generated $name:$pad <info>$key</info>");
124
    }
125
}
126