Passed
Push — 3.0 ( 5e1ed3...5a5495 )
by Rubén
04:22
created

Config::checkCacheDate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
8
 *
9
 * This file is part of sysPass.
10
 *
11
 * sysPass is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * sysPass is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace SP\Config;
26
27
use Psr\Container\ContainerInterface;
28
use ReflectionObject;
29
use SP\Core\Context\ContextInterface;
30
use SP\Core\Exceptions\ConfigException;
31
use SP\Services\Config\ConfigBackupService;
32
use SP\Storage\File\FileCacheInterface;
33
use SP\Storage\File\FileException;
34
use SP\Storage\File\XmlFileStorageInterface;
35
use SP\Util\PasswordUtil;
36
37
defined('APP_ROOT') || die();
38
39
/**
40
 * Esta clase es responsable de leer y escribir la configuración del archivo config.php
41
 */
42
final class Config
43
{
44
    /**
45
     * Cache file name
46
     */
47
    const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache';
48
    /**
49
     * @var int
50
     */
51
    private static $timeUpdated;
52
    /**
53
     * @var ContextInterface
54
     */
55
    private $context;
56
    /**
57
     * @var bool
58
     */
59
    private $configLoaded = false;
60
    /**
61
     * @var ConfigData
62
     */
63
    private $configData;
64
    /**
65
     * @var XmlFileStorageInterface
66
     */
67
    private $fileStorage;
68
    /**
69
     * @var FileCacheInterface
70
     */
71
    private $fileCache;
72
    /**
73
     * @var ContainerInterface
74
     */
75
    private $dic;
76
77
    /**
78
     * Config constructor.
79
     *
80
     * @param XmlFileStorageInterface $fileStorage
81
     * @param FileCacheInterface      $fileCache
82
     * @param ContainerInterface      $dic
83
     *
84
     * @throws ConfigException
85
     */
86
    public function __construct(XmlFileStorageInterface $fileStorage, FileCacheInterface $fileCache, ContainerInterface $dic)
87
    {
88
        $this->fileCache = $fileCache;
89
        $this->fileStorage = $fileStorage;
90
        $this->context = $dic->get(ContextInterface::class);
91
        $this->dic = $dic;
92
93
        $this->initialize();
94
    }
95
96
    /**
97
     * @throws ConfigException
98
     */
99
    private function initialize()
100
    {
101
        if (!$this->configLoaded) {
102
            try {
103
                if ($this->fileCache->exists()
104
                    && !$this->checkCacheDate()
105
                ) {
106
                    logger('Config cache loaded');
107
                    $this->configData = $this->fileCache->load();
108
                } else {
109
                    if (file_exists($this->fileStorage->getFileHandler()->getFile())) {
110
                        $this->configData = $this->loadConfigFromFile();
111
                        $this->fileCache->save($this->configData);
112
                    } else {
113
                        $this->saveConfig(new ConfigData(), false);
114
                    }
115
116
                    logger('Config loaded');
117
                }
118
119
                self::$timeUpdated = $this->configData->getConfigDate();
120
                $this->configLoaded = true;
121
            } catch (\Exception $e) {
122
                processException($e);
123
124
                throw new ConfigException($e->getMessage(),
125
                    ConfigException::CRITICAL,
126
                    null,
127
                    $e->getCode(),
128
                    $e);
129
            }
130
        }
131
    }
132
133
    /**
134
     * @return bool
135
     */
136
    private function checkCacheDate()
137
    {
138
        try {
139
            return $this->fileCache->isExpiredDate($this->fileStorage->getFileHandler()->getFileTime());
140
        } catch (FileException $e) {
141
            return true;
142
        }
143
    }
144
145
    /**
146
     * Cargar el archivo de configuración
147
     *
148
     * @return ConfigData
149
     * @throws FileException
150
     */
151
    public function loadConfigFromFile()
152
    {
153
        $configData = new ConfigData();
154
155
        // Mapear el array de elementos de configuración con las propiedades de la clase configData
156
        $items = $this->fileStorage->load('config')->getItems();
157
        $reflectionObject = new ReflectionObject($configData);
158
159
        foreach ($reflectionObject->getProperties() as $property) {
160
            $property->setAccessible(true);
161
162
            if (isset($items[$property->getName()])) {
163
                $property->setValue($configData, $items[$property->getName()]);
164
            }
165
166
            $property->setAccessible(false);
167
        }
168
169
        return $configData;
170
    }
171
172
    /**
173
     * Guardar la configuración
174
     *
175
     * @param ConfigData $configData
176
     * @param bool       $backup
177
     *
178
     * @return Config
179
     * @throws FileException
180
     */
181
    public function saveConfig(ConfigData $configData, $backup = true)
182
    {
183
        if ($backup) {
184
            $this->dic->get(ConfigBackupService::class)
185
                ->backup($configData);
186
        }
187
188
        $configData->setConfigDate(time());
189
        $configData->setConfigSaver($this->context->getUserData()->getLogin());
190
        $configData->setConfigHash();
191
192
        $this->fileStorage->save($configData, 'config');
193
        $this->fileCache->save($configData);
194
195
        $this->configData = $configData;
196
197
        return $this;
198
    }
199
200
    /**
201
     * @return int
202
     */
203
    public static function getTimeUpdated()
204
    {
205
        return self::$timeUpdated;
206
    }
207
208
    /**
209
     * Commits a config data
210
     *
211
     * @param ConfigData $configData
212
     *
213
     * @return Config
214
     */
215
    public function updateConfig(ConfigData $configData)
216
    {
217
        $configData->setConfigDate(time());
218
        $configData->setConfigSaver($this->context->getUserData()->getLogin());
219
        $configData->setConfigHash();
220
221
        $this->configData = $configData;
222
223
        self::$timeUpdated = $configData->getConfigDate();
224
225
        return $this;
226
    }
227
228
    /**
229
     * Cargar la configuración desde el contexto
230
     *
231
     * @param bool $reload
232
     *
233
     * @return ConfigData
234
     */
235
    public function loadConfig($reload = false)
236
    {
237
        try {
238
            $configData = $this->fileCache->load();
239
240
            if ($reload === true
241
                || $configData === null
242
                || !$this->checkCacheDate()
243
            ) {
244
                $this->configData = $this->loadConfigFromFile();
245
                $this->fileCache->save($this->configData);
246
247
                return $this->configData;
248
            }
249
250
            return $configData;
251
        } catch (FileException $e) {
252
            processException($e);
253
        }
254
255
        return $this->configData;
256
    }
257
258
    /**
259
     * @return ConfigData
260
     */
261
    public function getConfigData()
262
    {
263
        return clone $this->configData;
264
    }
265
266
    /**
267
     * @return Config
268
     * @throws FileException
269
     * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
270
     */
271
    public function generateUpgradeKey()
272
    {
273
        if (empty($this->configData->getUpgradeKey())) {
274
            logger('Generating upgrade key');
275
276
            return $this->saveConfig($this->configData->setUpgradeKey(PasswordUtil::generateRandomBytes(16)), false);
277
        }
278
279
        return $this;
280
    }
281
}
282