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

SessionController::flushCache()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 3
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\Controllers;
21
22
use MikoPBX\AdminCabinet\Forms\LoginForm;
23
use MikoPBX\Common\Models\AuthTokens;
24
use MikoPBX\Common\Models\PbxSettings;
25
use MikoPBX\Common\Providers\ManagedCacheProvider;
26
use MikoPBX\Common\Providers\ModelsCacheProvider;
27
use MikoPBX\Core\System\Util;
28
29
/**
30
 * SessionController
31
 *
32
 * Allows to authenticate users
33
 */
34
class SessionController extends BaseController
35
{
36
    public function indexAction(): void
37
    {
38
        $this->view->NameFromSettings
39
                          = PbxSettings::getValueByKey('Name');
40
        $this->view->DescriptionFromSettings
41
                          = PbxSettings::getValueByKey('Description');
42
        $this->view->form = new LoginForm();
43
    }
44
45
    /**
46
     * This action authenticate and logs an user into the application
47
     *
48
     */
49
    public function startAction(): void
50
    {
51
        if ( ! $this->request->isPost()) {
52
            $this->forward('session/index');
53
        }
54
        $loginFromUser = $this->request->getPost('login');
55
        $passFromUser  = $this->request->getPost('password');
56
        $this->flash->clear();
57
        $login    = PbxSettings::getValueByKey('WebAdminLogin');
58
        $password = PbxSettings::getValueByKey('WebAdminPassword');
59
        if ($password === $passFromUser && $login === $loginFromUser) {
60
            $this->_registerSession('admins');
61
            $this->updateSystemLanguage();
62
            $this->view->success = true;
63
            $this->view->reload  = 'index/index';
64
        } else {
65
            $this->view->success = false;
66
            $this->flash->error($this->translation->_('auth_WrongLoginPassword'));
67
            $remoteAddress = $this->request->getClientAddress(true);
68
            $userAgent     = $this->request->getUserAgent();
69
            $this->loggerAuth->warning("From: {$remoteAddress} UserAgent:{$userAgent} Cause: Wrong password");
70
            $this->clearAuthCookies();
71
        }
72
    }
73
74
    /**
75
     * Register an authenticated user into session data
76
     *
77
     * @param  $role
78
     */
79
    private function _registerSession($role): void
80
    {
81
        $sessionParams = [
82
            'role' => $role,
83
        ];
84
        $this->session->set('auth', $sessionParams);
85
86
        if ($this->request->getPost('rememberMeCheckBox') === 'on') {
87
            $this->updateRememberMeCookies($sessionParams);
88
        } else {
89
            $this->clearAuthCookies();
90
        }
91
    }
92
93
    /**
94
     * Setups random password and selector to browser cookie storage to remember me facility
95
     */
96
    private function updateRememberMeCookies(array $sessionParams): void
97
    {
98
        $cookieExpirationTime = time() + (30 * 24 * 60 * 60);  // for 1 month
99
100
        $randomPassword = $this->security->getToken();
101
        $this->cookies->set("random_token", $randomPassword, $cookieExpirationTime);
102
103
        $randomPasswordHash = $this->security->hash($randomPassword, PASSWORD_DEFAULT);
0 ignored issues
show
Bug introduced by
MikoPBX\AdminCabinet\Controllers\PASSWORD_DEFAULT of type string is incompatible with the type integer expected by parameter $workFactor of Phalcon\Security::hash(). ( Ignorable by Annotation )

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

103
        $randomPasswordHash = $this->security->hash($randomPassword, /** @scrutinizer ignore-type */ PASSWORD_DEFAULT);
Loading history...
104
105
        $expiryDate = date("Y-m-d H:i:s", $cookieExpirationTime);
106
107
        // Get token for username
108
        $parameters = [
109
            'conditions' => 'tokenHash = :tokenHash:',
110
            'binds'      => [
111
                'tokenHash' => $randomPasswordHash,
112
            ],
113
        ];
114
        $userToken  = AuthTokens::findFirst($parameters);
115
        if ($userToken === null) {
116
            $userToken = new AuthTokens();
117
        }
118
        // Insert new token
119
        $userToken->passwordHash = $randomPasswordHash;
0 ignored issues
show
Bug Best Practice introduced by
The property passwordHash does not exist on MikoPBX\Common\Models\AuthTokens. Since you implemented __set, consider adding a @property annotation.
Loading history...
120
        $userToken->expiryDate   = $expiryDate;
121
        $userToken->role         = json_encode($sessionParams);
0 ignored issues
show
Bug Best Practice introduced by
The property role does not exist on MikoPBX\Common\Models\AuthTokens. Since you implemented __set, consider adding a @property annotation.
Loading history...
122
        $userToken->save();
123
    }
124
125
    /**
126
     * Clears remember me cookies
127
     */
128
    private function clearAuthCookies(): void
129
    {
130
        if ($this->cookies->has('random_token')) {
131
            $this->cookies->delete('random_token');
132
        }
133
    }
134
135
    /**
136
     * Updates system settings for language
137
     *
138
     */
139
    private function updateSystemLanguage(): void
140
    {
141
        $newLanguage = $this->session->get('WebAdminLanguage');
142
        if ( ! isset($newLanguage)) {
143
            return;
144
        }
145
        $languageSettings = PbxSettings::findFirstByKey('WebAdminLanguage');
146
        if ($languageSettings === null) {
147
            $languageSettings        = new PbxSettings();
148
            $languageSettings->key   = 'WebAdminLanguage';
149
            $languageSettings->value = PbxSettings::getDefaultArrayValues()['WebAdminLanguage'];
150
        }
151
        if ($newLanguage !== $languageSettings->value) {
152
            $languageSettings->value = $newLanguage;
153
            $languageSettings->save();
154
        }
155
    }
156
157
    /**
158
     * Process language change
159
     */
160
    public function changeLanguageAction(): void
161
    {
162
        $newLanguage = $this->request->getPost('newLanguage', 'string');
163
        if (array_key_exists($newLanguage, $this->elements->getAvailableWebAdminLanguages())) {
164
            $this->session->set('WebAdminLanguage', $newLanguage);
165
            if ($this->session->has('auth')) {
166
                $this->updateSystemLanguage();
167
            }
168
            $this->view->success = true;
169
        } else {
170
            $this->view->success = false;
171
        }
172
    }
173
174
    /**
175
     * Finishes the active session redirecting to the index
176
     *
177
     */
178
    public function endAction(): void
179
    {
180
        $this->clearAuthCookies();
181
        $this->session->remove('auth');
182
        $this->session->destroy();
183
    }
184
}
185