Passed
Push — 2.x ( 8be9c2...fcd99a )
by Terry
02:19
created

User::logout()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
nc 4
nop 0
dl 0
loc 15
rs 10
c 1
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Shieldon\Firewall\Panel;
14
15
use Psr\Http\Message\ResponseInterface;
16
use Shieldon\Firewall\Panel\BaseController;
17
use Shieldon\Firewall\Firewall\Captcha\CaptchaFactory;
18
use Shieldon\Firewall\Captcha\Foundation;
19
use function Shieldon\Firewall\__;
20
use function Shieldon\Firewall\get_request;
21
use function Shieldon\Firewall\get_response;
22
use function Shieldon\Firewall\get_session;
23
use function Shieldon\Firewall\unset_superglobal;
24
25
use function password_verify;
26
27
/**
28
 * User
29
 */
30
class User extends BaseController
31
{
32
    /**
33
     * Constructor.
34
     */
35
    public function __construct() 
36
    {
37
        parent::__construct();
38
    }
39
40
    /**
41
     * Login
42
     * 
43
     * @param string $mode login mode.
44
     *
45
     * @return ResponseInterface
46
     */
47
    public function login($mode = ''): ResponseInterface
48
    {
49
        $this->applyCaptchaForms();
50
        $this->mode = $mode;
51
52
        $postParams = get_request()->getParsedBody();
53
54
        $login = false;
55
        $data['error'] = '';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
56
57
        if (isset($postParams['s_user']) && isset($postParams['s_pass'])) {
58
59
            if ($this->mode === 'demo') {
60
                $loginResult = $this->userLoginAsDemo($postParams['s_user'], $postParams['s_pass']);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $loginResult is correct as $this->userLoginAsDemo($... $postParams['s_pass']) targeting Shieldon\Firewall\Panel\User::userLoginAsDemo() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
61
            } else {
62
                $loginResult = $this->userLoginAsAdmin($postParams['s_user'], $postParams['s_pass']);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $loginResult is correct as $this->userLoginAsAdmin(... $postParams['s_pass']) targeting Shieldon\Firewall\Panel\User::userLoginAsAdmin() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
63
            }
64
    
65
            $login = $loginResult['result'];
66
            $data['error'] = $loginResult['message'];
67
        }
68
69
        if ($login) {
70
            $captchaResult = $this->checkCaptchaValidation();
71
            $login = $captchaResult['result'];
72
            $data['error'] = $captchaResult['message'];
73
74
            if ($login) {
75
                // This session variable is to mark current session as a logged user.
76
                get_session()->set('shieldon_user_login', true);
77
78
                // Redirect to overview page if logged in successfully.
79
                return get_response()->withHeader('Location', $this->url('home/overview'));
80
            }
81
        }
82
83
        // Start to prompt a login form is not logged.
84
        define('SHIELDON_VIEW', true);
85
86
        // `$ui` will be used in `css-default.php`. Do not remove it.
87
        $ui = [
88
            'background_image' => '',
89
            'bg_color'         => '#ffffff',
90
            'header_bg_color'  => '#212531',
91
            'header_color'     => '#ffffff',
92
            'shadow_opacity'   => '0.2',
93
        ];
94
95
        $data['csrf'] = $this->_csrf();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data['csrf'] is correct as $this->_csrf() targeting Shieldon\Firewall\Panel\BaseController::_csrf() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
96
        $data['form'] = get_request()->getUri()->getPath();
97
        $data['captchas'] = $this->captcha;
98
99
        $data['css'] = require $this->kernel::KERNEL_DIR . '/../../templates/frontend/css/default.php';
100
101
        unset($ui);
102
103
        $data['title'] = __('panel', 'title_login', 'Login');
104
105
        return $this->respond(
106
            $this->loadView('frontend/login', $data)
107
        );
108
    }
109
110
    /**
111
     * Logout
112
     *
113
     * @return ResponseInterface
114
     */
115
    public function logout(): ResponseInterface
116
    {
117
        $sessionLoginStatus = get_session()->get('shieldon_user_login');
118
        $sessionPanelLang = get_session()->get('shieldon_panel_lang');
119
        $response = get_response();
120
121
        if (isset($sessionLoginStatus)) {
122
            unset_superglobal('shieldon_user_login', 'session');
123
        }
124
125
        if (isset($sessionPanelLang)) {
126
            unset_superglobal('shieldon_panel_lang', 'session');
127
        }
128
129
        return $response->withHeader('Location', $this->url('user/login'));
130
    }
131
132
    /**
133
     * Set the Captcha modules.
134
     *
135
     * @return void
136
     */
137
    protected function applyCaptchaForms(): void
138
    {
139
        $this->captcha[] = new Foundation();
140
141
        $captchaList = [
142
            'recaptcha',
143
            'image',
144
        ];
145
146
        foreach ($captchaList as $captcha) {
147
            $setting = $this->getConfig('captcha_modules.' . $captcha);
148
149
            if (is_array($setting)) {
150
                if (CaptchaFactory::check($captcha, $setting)) {
151
                    $this->captcha[] = CaptchaFactory::getInstance($captcha, $setting);
152
                }
153
            }
154
            unset($setting);
155
        }
156
    }
157
158
    /**
159
     * Login as demonstration.
160
     *
161
     * @param string $username The username.
162
     * @param string $password The password.
163
     *
164
     * @return void
165
     */
166
    private function userLoginAsDemo($username, $password)
167
    {
168
        $login = false;
169
        $errorMsg = '';
170
171
        if ($username === 'demo' && $password === 'demo') {
172
            $login = true;
173
        }
174
175
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('result' =>...'message' => $errorMsg) returns the type array<string,boolean|string> which is incompatible with the documented return type void.
Loading history...
176
            'result' => $login,
177
            'message' => $errorMsg,
178
        ];
179
    }
180
181
    /**
182
     * Login as administration.
183
     *
184
     * @param string $username The username.
185
     * @param string $password The password.
186
     *
187
     * @return void
188
     */
189
    private function userLoginAsAdmin($username, $password)
190
    {
191
        $admin = $this->getConfig('admin');
192
193
        $login = false;
194
        $errorMsg = '';
195
196
        if (
197
            // Default password, unencrypted.
198
            $admin['user'] === $username && 
199
            $admin['pass'] === $password
200
        ) {
201
            $login = true;
202
203
        } elseif (
204
            // User has already changed password, encrypted.
205
            $admin['user'] === $username && 
206
            password_verify($password, $admin['pass'])
207
        ) {
208
            $login = true;
209
210
        } else {
211
            $errorMsg = __('panel', 'login_message_invalid_user_or_pass', 'Invalid username or password.');
212
        }
213
214
        // Check the response from Captcha modules.
215
 
216
217
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('result' =>...'message' => $errorMsg) returns the type array<string,boolean|string> which is incompatible with the documented return type void.
Loading history...
218
            'result' => $login,
219
            'message' => $errorMsg,
220
        ];
221
    }
222
223
    /**
224
     * Check Captcha.
225
     *
226
     * @return array
227
     */
228
    private function checkCaptchaValidation(): array
229
    {
230
        $login = true;
231
        $errorMsg = '';
232
233
        foreach ($this->captcha as $captcha) {
234
            if (!$captcha->response()) {
235
                $login = false;
236
                $errorMsg = __('panel', 'login_message_invalid_captcha', 'Invalid Captcha code.');
237
            }
238
        }
239
240
        return [
241
            'result' => $login,
242
            'message' => $errorMsg,
243
        ];
244
    }
245
}
246
247