Passed
Push — develop ( cd3e4b...b998ca )
by Портнов
05:16
created

AdvicesProcessor::checkRegistration()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 31
rs 9.3222
cc 5
nc 7
nop 0
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright (C) 2017-2020 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\PBXCoreREST\Lib;
21
22
use MikoPBX\Common\Providers\ManagedCacheProvider;
23
use MikoPBX\Core\System\Storage;
24
use MikoPBX\Core\System\Util;
25
use MikoPBX\Common\Models\{NetworkFilters, PbxSettings, Sip};
26
use GuzzleHttp;
27
use Phalcon\Di\Injectable;
28
use SimpleXMLElement;
29
use MikoPBX\Service\Main;
30
31
/**
32
 * Class AdvicesProcessor
33
 *
34
 * @package MikoPBX\PBXCoreREST\Lib
35
 *
36
 * @property \MikoPBX\Common\Providers\LicenseProvider license
37
 * @property \MikoPBX\Common\Providers\TranslationProvider translation
38
 * @property \Phalcon\Config                               config
39
 */
40
class AdvicesProcessor extends Injectable
41
{
42
43
    /**
44
     * Processes Advices request
45
     *
46
     * @param array $request
47
     *
48
     * @return PBXApiResult
49
     */
50
    public static function callBack(array $request): PBXApiResult
51
    {
52
        $action = $request['action'];
53
        if('getList' === $action){
54
            $proc = new self();
55
            $res  = $proc->getAdvicesAction();
56
        }else{
57
            $res             = new PBXApiResult();
58
            $res->processor  = __METHOD__;
59
            $res->messages[] = "Unknown action - {$action} in advicesCallBack";
60
        }
61
        $res->function = $action;
62
        return $res;
63
    }
64
65
66
    /**
67
     * Makes list of notifications about system, firewall, passwords, wrong settings
68
     *
69
     * @return PBXApiResult
70
     */
71
    private function getAdvicesAction(): PBXApiResult
72
    {
73
        $res            = new PBXApiResult();
74
        $res->processor = __METHOD__;
75
76
        $arrMessages     = [];
77
        $arrAdvicesTypes = [
78
            ['type' => 'isConnected', 'cacheTime' => 15],
79
            ['type' => 'checkCorruptedFiles', 'cacheTime' => 15],
80
            ['type' => 'checkPasswords', 'cacheTime' => 15],
81
            ['type' => 'checkFirewalls', 'cacheTime' => 15],
82
            ['type' => 'checkStorage', 'cacheTime' => 120],
83
            ['type' => 'checkUpdates', 'cacheTime' => 3600],
84
            ['type' => 'checkRegistration', 'cacheTime' => 86400],
85
        ];
86
87
        $managedCache = $this->getDI()->getShared(ManagedCacheProvider::SERVICE_NAME);
88
        $language = PbxSettings::getValueByKey('WebAdminLanguage');
89
90
        foreach ($arrAdvicesTypes as $adviceType) {
91
            $currentAdvice = $adviceType['type'];
92
            $cacheTime     = $adviceType['cacheTime'];
93
            $cacheKey      = 'AdvicesProcessor:getAdvicesAction:'.$currentAdvice;
94
            if ($managedCache->has($cacheKey)) {
95
                $oldResult = json_decode($managedCache->get($cacheKey), true, 512, JSON_THROW_ON_ERROR);
96
                if ($language === $oldResult['LastLanguage']) {
97
                    $arrMessages[] = $oldResult['LastMessage'];
98
                    continue;
99
                }
100
            }
101
            $newResult = $this->$currentAdvice();
102
            if ( ! empty($newResult)) {
103
                $arrMessages[] = $newResult;
104
            }
105
            $managedCache->set(
106
                $cacheKey,
107
                json_encode([
108
                                'LastLanguage' => $language,
109
                                'LastMessage' => $newResult,
110
                            ], JSON_THROW_ON_ERROR),
111
                $cacheTime
112
            );
113
        }
114
        $res->success = true;
115
        $result       = [];
116
        foreach ($arrMessages as $message) {
117
            foreach ($message as $key => $value) {
118
                if(is_array($value)){
119
                    $result[$key] = array_merge($result[$key], $value);
120
                }elseif ( ! empty($value)) {
121
                    $result[$key][] = $value;
122
                }
123
            }
124
        }
125
        $res->data['advices'] = $result;
126
127
        return $res;
128
    }
129
130
    /**
131
     * Check passwords quality
132
     *
133
     * @return array
134
     * @noinspection PhpUnusedPrivateMethodInspection
135
     */
136
    private function checkPasswords(): array
137
    {
138
        $messages           = [];
139
        $arrOfDefaultValues = PbxSettings::getDefaultArrayValues();
140
        $fields = [
141
            'WebAdminPassword'  => [
142
                'url'  => 'general-settings/modify/#/passwords',
143
                'type' => 'gs_WebPasswordFieldName',
144
                'value'=> $arrOfDefaultValues['WebAdminPassword']
145
            ],
146
            'SSHPassword'       => [
147
                'url'  => 'general-settings/modify/#/ssh',
148
                'type' => 'gs_SshPasswordFieldName',
149
                'value'=> $arrOfDefaultValues['SSHPassword']
150
            ],
151
        ];
152
        if ($arrOfDefaultValues['WebAdminPassword'] === PbxSettings::getValueByKey('WebAdminPassword')) {
153
            $messages['warning'][] = $this->translation->_(
154
                'adv_YouUseDefaultWebPassword',
155
                ['url' => $this->url->get('general-settings/modify/#/passwords')]
156
            );
157
            unset($fields['WebAdminPassword']);
158
        }
159
        if ($arrOfDefaultValues['SSHPassword'] === PbxSettings::getValueByKey('SSHPassword')) {
160
            $messages['warning'][] = $this->translation->_(
161
                'adv_YouUseDefaultSSHPassword',
162
                ['url' => $this->url->get('general-settings/modify/#/ssh')]
163
            );
164
            unset($fields['SSHPassword']);
165
        }elseif(PbxSettings::getValueByKey('SSHPasswordHash') !== md5_file('/etc/passwd')){
166
            $messages['warning'][] = $this->translation->_(
167
                'gs_SSHPPasswordCorrupt',
168
                ['url' => $this->url->get('general-settings/modify/#/ssh')]
169
            );
170
        }
171
172
        $peersData = Sip::find([
173
               "type = 'peer' AND ( disabled <> '1')",
174
               'columns' => 'id,extension,secret']
175
        );
176
        foreach ($peersData as $peer){
177
            $fields[$peer['extension']] = [
178
                'url'  => '/admin-cabinet/extensions/modify/'.$peer['id'],
179
                'type' => 'gs_UserPasswordFieldName',
180
                'value'=> $peer['secret']
181
            ];
182
        }
183
        foreach ($fields as $value){
184
            if(!Util::isSimplePassword($value['value'])){
185
                continue;
186
            }
187
            $messages['warning'][] = $this->translation->_(
188
                'adv_isSimplePassword',
189
                [
190
                    'type' => $this->translation->_($value['type']),
191
                    'url' => $this->url->get($value['url'])
192
                ]
193
            );
194
        }
195
        return $messages;
196
    }
197
198
    /**
199
     * Check passwords quality
200
     *
201
     * @return array
202
     * @noinspection PhpUnusedPrivateMethodInspection
203
     */
204
    private function checkCorruptedFiles(): array
205
    {
206
        $messages           = [];
207
        $files = Main::checkForCorruptedFiles();
208
        if (count($files) !== 0) {
209
            $messages['warning'] = $this->translation->_('The integrity of the system is broken', ['url' => '']).'. '.$this->translation->_('systemBrokenComment', ['url' => '']);
210
        }
211
212
        return $messages;
213
    }
214
215
    /**
216
     * Check firewall status
217
     *
218
     * @return array
219
     * @noinspection PhpUnusedPrivateMethodInspection
220
     */
221
    private function checkFirewalls(): array
222
    {
223
        $messages = [];
224
        if (PbxSettings::getValueByKey('PBXFirewallEnabled') === '0') {
225
            $messages['warning'] = $this->translation->_(
226
                'adv_FirewallDisabled',
227
                ['url' => $this->url->get('firewall/index/')]
228
            );
229
        }
230
        if (NetworkFilters::count() === 0) {
231
            $messages['warning'] = $this->translation->_(
232
                'adv_NetworksNotConfigured',
233
                ['url' => $this->url->get('firewall/index/')]
234
            );
235
        }
236
237
        return $messages;
238
    }
239
240
    /**
241
     * Check storage is mount and how many space available
242
     *
243
     * @return array
244
     *
245
     * @noinspection PhpUnusedPrivateMethodInspection
246
     */
247
    private function checkStorage(): array
248
    {
249
        $messages           = [];
250
        $st                 = new Storage();
251
        $storageDiskMounted = false;
252
        $disks              = $st->getAllHdd();
253
        foreach ($disks as $disk) {
254
            if (array_key_exists('mounted', $disk)
255
                && strpos($disk['mounted'], '/storage/usbdisk') !== false) {
256
                $storageDiskMounted = true;
257
                if ($disk['free_space'] < 500) {
258
                    $messages['warning']
259
                        = $this->translation->_(
260
                        'adv_StorageDiskRunningOutOfFreeSpace',
261
                        ['free' => $disk['free_space']]
262
                    );
263
                }
264
            }
265
        }
266
        if ($storageDiskMounted === false) {
267
            $messages['error'] = $this->translation->_('adv_StorageDiskUnMounted');
268
        }
269
        return $messages;
270
    }
271
272
    /**
273
     * Check new version PBX
274
     *
275
     * @return array
276
     * @throws \GuzzleHttp\Exception\GuzzleException
277
     * @noinspection PhpUnusedPrivateMethodInspection
278
     */
279
    private function checkUpdates(): array
280
    {
281
        $messages   = [];
282
        $PBXVersion = PbxSettings::getValueByKey('PBXVersion');
283
284
        $client = new GuzzleHttp\Client();
285
        $res    = $client->request(
286
            'POST',
287
            'https://releases.mikopbx.com/releases/v1/mikopbx/ifNewReleaseAvailable',
288
            [
289
                'form_params' => [
290
                    'PBXVER' => $PBXVersion,
291
                ],
292
            ]
293
        );
294
        if ($res->getStatusCode() !== 200) {
295
            return [];
296
        }
297
298
        $answer = json_decode($res->getBody(), false);
299
        if ($answer !== null && $answer->newVersionAvailable === true) {
300
            $messages['info'] = $this->translation->_(
301
                'adv_AvailableNewVersionPBX',
302
                [
303
                    'url' => $this->url->get('update/index/'),
304
                    'ver' => $answer->version,
305
                ]
306
            );
307
        }
308
309
        return $messages;
310
    }
311
312
    /**
313
     * Check mikopbx license status
314
     *
315
     * @noinspection PhpUnusedPrivateMethodInspection
316
     */
317
    private function checkRegistration(): array
318
    {
319
        $messages = [];
320
        $licKey   = PbxSettings::getValueByKey('PBXLicense');
321
        $language   = PbxSettings::getValueByKey('WebAdminLanguage');
322
323
        if ( ! empty($licKey)) {
324
            $checkBaseFeature = $this->license->featureAvailable(33);
325
            if ($checkBaseFeature['success'] === false) {
326
                if ($language === 'ru') {
327
                    $url = 'https://wiki.mikopbx.com/licensing#faq_chavo';
328
                } else {
329
                    $url = "https://wiki.mikopbx.com/{$language}:licensing#faq_chavo";
330
                }
331
                $textError = (string)($checkBaseFeature['error']??'');
332
                $messages['warning'] = $this->translation->_(
333
                    'adv_ThisCopyHasLicensingTroubles',
334
                    [
335
                        'url'   => $url,
336
                        'error' => $this->license->translateLicenseErrorMessage($textError),
337
                    ]
338
                );
339
            }
340
341
            $licenseInfo = $this->license->getLicenseInfo($licKey);
342
            if ($licenseInfo instanceof SimpleXMLElement) {
343
                file_put_contents('/tmp/licenseInfo', json_encode($licenseInfo->attributes()));
344
            }
345
        }
346
347
        return $messages;
348
    }
349
350
    /**
351
     * Checks whether internet connection is available or not
352
     *
353
     * @return array
354
     * @noinspection PhpUnusedPrivateMethodInspection
355
     */
356
    private function isConnected(): array
357
    {
358
        $messages = [];
359
        $connected = @fsockopen("www.google.com", 443);
360
        if ($connected !== false) {
361
            fclose($connected);
362
        } else {
363
            $messages['warning'] = $this->translation->_('adv_ProblemWithInternetConnection');
364
        }
365
        return $messages;
366
    }
367
}