Passed
Push — develop ( 34060b...723b8d )
by Портнов
05:00
created

SecurityPlugin::controllerExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
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
use Phalcon\Text;
27
28
/**
29
 * SecurityPlugin
30
 *
31
 * This is the security plugin which controls that users only have access to the modules they're assigned to
32
 */
33
class SecurityPlugin extends Injectable
34
{
35
36
    /**
37
     * This action is executed before execute any action in the application
38
     *
39
     * @param Event      $event
40
     * @param Dispatcher $dispatcher
41
     *
42
     * @return bool
43
     */
44
    public function beforeDispatch(/** @scrutinizer ignore-unused */ Event $event, Dispatcher $dispatcher): bool
45
    {
46
        $isLoggedIn = $this->checkUserAuth();
47
        $controller = strtoupper($dispatcher->getControllerName());
48
49
        if ( ! $isLoggedIn && $controller !== 'SESSION') {
50
            // AJAX REQUESTS
51
            if ($this->request->isAjax()) {
52
                $this->response->setStatusCode(403, 'Forbidden')->sendHeaders();
53
                $this->response->setContent('This user not authorised');
54
                $this->response->send();
55
56
                return false;
57
            } else { // Usual requests
58
                $dispatcher->forward(
59
                    [
60
                        'controller' => 'session',
61
                        'action'     => 'index',
62
                    ]
63
                );
64
            }
65
66
            return true;
67
        }
68
69
70
        if ( $isLoggedIn && ($controller === 'INDEX' || !$this->controllerExists($dispatcher)) ) {
71
            $dispatcher->forward(
72
                [
73
                    'controller' => 'extensions',
74
                    'action'     => 'index',
75
                ]
76
            );
77
        }
78
79
        return true;
80
    }
81
82
    /**
83
     * Проверка существования класса контроллера.
84
     * @param $dispatcher
85
     * @return bool
86
     */
87
    private function controllerExists($dispatcher):bool
88
    {
89
        $controller = Text::camelize($dispatcher->getControllerName());
90
        return $dispatcher->getNamespaceName().'\\'.$controller.$dispatcher->getHandlerSuffix();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $dispatcher->getN...her->getHandlerSuffix() returns the type string which is incompatible with the type-hinted return boolean.
Loading history...
91
    }
92
93
    /**
94
     * Checks if user already logged in or not
95
     *
96
     * @return bool
97
     */
98
    private function checkUserAuth(): bool
99
    {
100
        // Check if it localhost request
101
        if ($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
102
            return true;
103
        } // Check if user already registered
104
        elseif ($this->session->has('auth')) {
105
            return true;
106
        } // Check if remember me cookie exists
107
        elseif ($this->cookies->has('random_token')) {
108
            $token       = $this->cookies->get('random_token')->getValue();
109
            $currentDate = date("Y-m-d H:i:s", time());
110
            $userTokens  = AuthTokens::find();
111
            foreach ($userTokens as $userToken) {
112
                if ($userToken->expiryDate < $currentDate) {
113
                    $userToken->delete();
114
                } elseif ($this->security->checkHash($token, $userToken->tokenHash)) {
115
                    $sessionParams = json_decode($userToken->sessionParams);
116
                    $this->session->set('auth', $sessionParams);
117
                    return true;
118
                }
119
            }
120
        }
121
122
        return false;
123
    }
124
125
}
126