Passed
Push — develop ( 9ff5e0...4357d1 )
by Nikolay
04:17
created

SecurityPlugin::checkUserAuth()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
c 0
b 0
f 0
dl 0
loc 21
rs 9.2222
cc 6
nc 4
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\AdminCabinet\Plugins;
21
22
use MikoPBX\Common\Models\AuthTokens;
23
use Phalcon\Di\Injectable;
24
use Phalcon\Events\Event;
25
use Phalcon\Mvc\Dispatcher;
26
27
/**
28
 * SecurityPlugin
29
 *
30
 * This is the security plugin which controls that users only have access to the modules they're assigned to
31
 */
32
class SecurityPlugin extends Injectable
33
{
34
35
    /**
36
     * This action is executed before execute any action in the application
37
     *
38
     * @param Event      $event
39
     * @param Dispatcher $dispatcher
40
     *
41
     * @return bool
42
     */
43
    public function beforeDispatch(/** @scrutinizer ignore-unused */ Event $event, Dispatcher $dispatcher): bool
44
    {
45
        if ($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
46
            return true;
47
        }
48
        $controller = strtoupper($dispatcher->getControllerName());
49
        if ($this->request->isAjax()) {
50
            if ($controller !== 'SESSION') {
51
                $sessionRo = $this->di->getShared('sessionRO');
52
                if ( ! is_array($sessionRo)
53
                    || ! array_key_exists('auth', $sessionRo)
54
                ) {
55
                    $this->response->setStatusCode(403, 'Forbidden')
56
                        ->sendHeaders();
57
                    $this->response->setContent('The user isn\'t authenticated');
58
                    $this->response->send();
59
60
                    return false;
61
                }
62
            }
63
        } else { // it is not AJAX request
64
            $isLoggedIn = $this->checkUserAuth();
65
            if ( ! $isLoggedIn && $controller !== 'SESSION') {
66
                $dispatcher->forward(
67
                    [
68
                        'controller' => 'session',
69
                        'action'     => 'index',
70
                    ]
71
                );
72
            } elseif ($controller == 'INDEX') {
73
                $dispatcher->forward(
74
                    [
75
                        'controller' => 'extensions',
76
                        'action'     => 'index',
77
                    ]
78
                );
79
            }
80
        }
81
82
        return true;
83
    }
84
85
    /**
86
     * Checks if user already logged in or not
87
     *
88
     * @return bool
89
     */
90
    private function checkUserAuth(): bool
91
    {
92
        // Check if loggedin session and redirect if session exists
93
        if ($this->session->has('auth')) {
94
            return true;
95
        } // Check if loggedin session exists
96
        elseif ($this->cookies->has('random_token')) {
97
            $token       = $this->cookies->get('random_token');
98
            $currentDate = date("Y-m-d H:i:s", time());
99
            $userTokens  = AuthTokens::find();
100
            foreach ($userTokens as $userToken) {
101
                if ($userToken->expiryDate < $currentDate) {
102
                    $userToken->delete();
103
                } elseif ($this->security->checkHash($token, $userToken->passwordHash)) {
0 ignored issues
show
Bug introduced by
$token of type Phalcon\Http\Cookie\CookieInterface is incompatible with the type string expected by parameter $password of Phalcon\Security::checkHash(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
                } elseif ($this->security->checkHash(/** @scrutinizer ignore-type */ $token, $userToken->passwordHash)) {
Loading history...
104
                    $sessionParams = json_decode($userToken->sessionParams);
105
                    $this->session->set('auth', $sessionParams);
106
                    return true;
107
                }
108
            }
109
        }
110
        return false;
111
    }
112
113
}
114