GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 9e304b...e448f2 )
by Steeven
03:32
created

User::hasAccess()   C

Complexity

Conditions 16
Paths 21

Size

Total Lines 71
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 45
c 0
b 0
f 0
nc 21
nop 1
dl 0
loc 71
rs 5.5666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Framework\Libraries\AccessControl;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Security\Authentication\User\Account;
19
use O2System\Security\Authentication\User\Role;
20
use O2System\Spl\Exceptions\RuntimeException;
21
22
/**
23
 * Class User
24
 * @package O2System\Framework\Libraries\AccessControl
25
 */
26
class User extends \O2System\Security\Authentication\User
27
{
28
    /**
29
     * User::$app
30
     *
31
     * @var string
32
     */
33
    protected $app = 'app';
34
35
    /**
36
     * User::__construct
37
     *
38
     * @throws \O2System\Spl\Exceptions\RuntimeException
39
     */
40
    public function __construct()
41
    {
42
        parent::__construct();
43
44
        if ($config = config()->loadFile('AccessControl', true)) {
0 ignored issues
show
Bug introduced by
The method loadFile() does not exist on O2System\Kernel\DataStructures\Config. ( Ignorable by Annotation )

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

44
        if ($config = config()->/** @scrutinizer ignore-call */ loadFile('AccessControl', true)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
45
            $this->setConfig($config->getArrayCopy());
46
        }
47
48
        if ( ! models('users')) {
49
            throw new RuntimeException('ACL_E_UNDEFINED_USERS_MODEL');
50
        }
51
    }
52
53
    // ------------------------------------------------------------------------
54
55
    /**
56
     * User::setApp
57
     *
58
     * @param string $app
59
     *
60
     * @return static
61
     */
62
    public function setApp($app)
63
    {
64
        if ($app = modules()->getApp($app)) {
0 ignored issues
show
Bug introduced by
The method getApp() does not exist on O2System\Framework\Conta...s\DataStructures\Module. ( Ignorable by Annotation )

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

64
        if ($app = modules()->/** @scrutinizer ignore-call */ getApp($app)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
65
            $this->app = $app;
0 ignored issues
show
Documentation Bug introduced by
It seems like $app can also be of type true. However, the property $app is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
66
        }
67
68
        return $this;
69
    }
70
71
    // ------------------------------------------------------------------------
72
73
    /**
74
     * User::authenticate
75
     *
76
     * @param string $username
77
     * @param string $password
78
     *
79
     * @return bool
80
     */
81
    public function authenticate($username, $password)
82
    {
83
        if ($user = $this->find($username)) {
84
            if ($user->account) {
0 ignored issues
show
Bug introduced by
The property account does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
Bug introduced by
The property account does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
85
                if ($this->passwordVerify($password, $user->account->password)) {
86
                    if ($this->passwordRehash($password)) {
87
                        $user->account->update([
88
                            'id'       => $user->id,
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
Bug introduced by
The property id does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
89
                            'password' => $this->passwordHash($password),
90
                        ]);
91
                    }
92
93
                    $account = $user->account->getArrayCopy();
94
                }
95
            } elseif ($this->passwordVerify($password, $user->password)) {
0 ignored issues
show
Bug introduced by
The property password does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
Bug introduced by
The property password does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
96
                $account = $user->getArrayCopy();
97
            }
98
99
            if (isset($account)) {
100
                foreach ($account as $key => $value) {
101
                    if (strpos($key, 'record') !== false) {
102
                        unset($account[ $key ]);
103
                    } elseif (in_array($key,
104
                        ['password', 'pin', 'token', 'sso', 'id_sys_user', 'id_sys_module', 'id_sys_module_role'])) {
105
                        unset($account[ $key ]);
106
                    }
107
                }
108
109
                $this->login($account);
110
111
                return true;
112
            }
113
        }
114
115
        return false;
116
    }
117
118
    // ------------------------------------------------------------------------
119
120
    /**
121
     * User::find
122
     *
123
     * @param string $username
124
     *
125
     * @return bool|mixed|\O2System\Database\DataObjects\Result|\O2System\Framework\Models\Sql\DataObjects\Result
126
     */
127
    public function find($username)
128
    {
129
        $column = 'username';
130
        if (is_numeric($username)) {
131
            $column = 'id';
132
        } elseif (filter_var($username, FILTER_VALIDATE_EMAIL)) {
133
            $column = 'email';
134
        } elseif (preg_match($this->config[ 'msisdnRegex' ], $username)) {
135
            $column = 'msisdn';
136
        }
137
138
        if ($user = models('users')->findWhere([
0 ignored issues
show
Bug introduced by
The method findWhere() does not exist on O2System\Framework\Containers\Models. ( Ignorable by Annotation )

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

138
        if ($user = models('users')->/** @scrutinizer ignore-call */ findWhere([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
            $column => $username,
140
        ], 1)) {
141
            return $user;
142
        }
143
144
        return false;
145
    }
146
147
    // ------------------------------------------------------------------------
148
149
    /**
150
     * User::loggedIn
151
     *
152
     * @return bool
153
     * @throws \Psr\Cache\InvalidArgumentException
154
     */
155
    public function loggedIn()
156
    {
157
        if (parent::loggedIn()) {
158
            if(is_object($_SESSION['account'])) {
159
                $account = new Account($_SESSION['account']->getArrayCopy());
160
                $username = $account->user->username;
161
            } else {
162
                $account = new Account();
0 ignored issues
show
Bug introduced by
The call to O2System\Security\Authen...\Account::__construct() has too few arguments starting with account. ( Ignorable by Annotation )

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

162
                $account = /** @scrutinizer ignore-call */ new Account();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
163
                $username = $_SESSION['account']['username'];
164
            }
165
166
            if ($user = models('users')->findWhere(['username' => $username], 1)) {
167
                if ($profile = $user->profile) {
0 ignored issues
show
Bug introduced by
The property profile does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
Bug introduced by
The property profile does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
168
                    $account->store('profile', $profile);
169
                }
170
171
                if ($employee = $user->employee) {
0 ignored issues
show
Bug introduced by
The property employee does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
Bug introduced by
The property employee does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
172
                    $account->store('employee', $employee);
173
                }
174
175
                if ($role = $user->role) {
0 ignored issues
show
Bug introduced by
The property role does not seem to exist on O2System\Database\DataObjects\Result.
Loading history...
Bug introduced by
The property role does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
176
                    $user->store('role', $role);
0 ignored issues
show
Bug introduced by
The method store() does not exist on O2System\Framework\Models\Sql\DataObjects\Result. ( Ignorable by Annotation )

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

176
                    $user->/** @scrutinizer ignore-call */ 
177
                           store('role', $role);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method store() does not exist on O2System\Database\DataObjects\Result. ( Ignorable by Annotation )

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

176
                    $user->/** @scrutinizer ignore-call */ 
177
                           store('role', $role);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
177
                }
178
179
                $account->store('user', $user);
180
181
                session()->set('account', $account);
182
            }
183
184
            // Store Globals Account
185
            globals()->store('account', $account);
186
187
            // Store Presenter Account
188
            if (services()->has('view')) {
189
                presenter()->store('account', $account);
190
            }
191
192
            return true;
193
        }
194
195
        return false;
196
    }
197
198
    // ------------------------------------------------------------------------
199
200
    /**
201
     * User::forceLogin
202
     *
203
     * @param string $username
204
     * @param string $column
205
     *
206
     * @return bool
207
     */
208
    public function forceLogin($username, $column = 'username')
209
    {
210
        if (is_numeric($username)) {
211
            $column = 'id';
212
        } elseif (filter_var($username, FILTER_VALIDATE_EMAIL)) {
213
            $column = 'email';
214
        } elseif (preg_match($this->config[ 'msisdnRegex' ], $username)) {
215
            $column = 'msisdn';
216
        } elseif (strpos($username, 'token-') !== false) {
217
            $username = str_replace('token-', '', $username);
218
            $column = 'token';
219
        } elseif (strpos($username, 'sso-') !== false) {
220
            $username = str_replace('sso-', '', $username);
221
            $column = 'sso';
222
        }
223
224
        if ($account = models('users')->findWhere([$column => $username], 1)) {
225
            $account = $account->getArrayCopy();
226
227
            foreach ($account as $key => $value) {
228
                if (strpos($key, 'record') !== false) {
229
                    unset($account[ $key ]);
230
                } elseif (in_array($key, ['password', 'pin', 'token', 'sso'])) {
231
                    unset($account[ $key ]);
232
                }
233
            }
234
235
            if ($column === 'token') {
236
                models('users')->update([
0 ignored issues
show
Bug introduced by
The method update() does not exist on O2System\Framework\Containers\Models. ( Ignorable by Annotation )

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

236
                models('users')->/** @scrutinizer ignore-call */ update([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method update() does not exist on O2System\Framework\Models\NoSql\Model. ( Ignorable by Annotation )

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

236
                models('users')->/** @scrutinizer ignore-call */ update([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
237
                    'id'    => $account[ 'id' ],
238
                    'token' => null,
239
                ]);
240
            }
241
242
            $this->login($account);
243
244
            return true;
245
        }
246
247
        return false;
248
    }
249
250
    // ------------------------------------------------------------------------
251
252
    /**
253
     * User::hasAccess
254
     *
255
     * @param array $segments
256
     *
257
     * @return bool
258
     */
259
    public function hasAccess(array $segments)
260
    {
261
        if ($this->loggedIn()) {
262
            if ($account = globals()->offsetGet('account')) {
263
                if (in_array($account->user->role->id, [1, 2])) {
264
                    return true;
265
                }
266
267
                if ($model = models('modules')) {
268
                    if ($segment = $model->segments->find(implode('/', $segments), 'segments')) {
0 ignored issues
show
Bug introduced by
The method find() does not exist on O2System\Framework\Models\Sql\DataObjects\Result. ( Ignorable by Annotation )

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

268
                    if ($segment = $model->segments->/** @scrutinizer ignore-call */ find(implode('/', $segments), 'segments')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Models\Sql\Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Models\NoSql\Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The method find() does not exist on O2System\Framework\Model...\DataObjects\Result\Row. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

268
                    if ($segment = $model->segments->/** @scrutinizer ignore-call */ find(implode('/', $segments), 'segments')) {
Loading history...
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Containers\Models. Since you implemented __get, consider adding a @property annotation.
Loading history...
269
                        if ($authority = $model->segments->authorities->users->findWhere([
0 ignored issues
show
Bug Best Practice introduced by
The property authorities does not exist on O2System\Framework\Model...\DataObjects\Result\Row. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The property authorities does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
270
                            'id_sys_module_segment' => $segment->id,
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on O2System\Framework\Model...\DataObjects\Result\Row. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The property id does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
271
                            'id_sys_module_user'    => $account->user->moduleUser->id,
272
                        ])) {
273
                            if ($authority->first()->permission === 'WRITE') {
274
                                return true;
275
                            } elseif ($authority->first()->permission === 'GRANTED') {
276
                                // Access only granted cannot do modifier access
277
                                foreach ([
278
                                             'form',
279
                                             'add',
280
                                             'add-as-new',
281
                                             'edit',
282
                                             'update',
283
                                             'insert',
284
                                             'create',
285
                                             'delete',
286
                                         ] as $segment
287
                                ) {
288
                                    if (in_array($segment, $segments)) {
289
                                        return false;
290
                                    }
291
                                }
292
293
                                return true;
294
                            }
295
                        }
296
297
                        if ($authority = $model->segments->authorities->roles->findWhere([
298
                            'id_sys_module_segment' => $segment->id,
299
                            'id_sys_module_role'    => $account->user->role->id,
300
                        ])) {
301
                            if ($authority->first()->permission === 'WRITE') {
302
                                return true;
303
                            } elseif ($authority->first()->permission === 'GRANTED') {
304
                                // Access only granted cannot do modifier access
305
                                foreach ([
306
                                             'form',
307
                                             'add',
308
                                             'add-as-new',
309
                                             'edit',
310
                                             'update',
311
                                             'insert',
312
                                             'create',
313
                                             'delete',
314
                                         ] as $segment
315
                                ) {
316
                                    if (in_array($segment, $segments)) {
317
                                        return false;
318
                                    }
319
                                }
320
321
                                return true;
322
                            }
323
                        }
324
                    }
325
                }
326
            }
327
        }
328
329
        return false;
330
    }
331
332
    // ------------------------------------------------------------------------
333
334
    /**
335
     * User::hasWriteAccess
336
     *
337
     * @return bool
338
     * @throws \Psr\Cache\InvalidArgumentException
339
     */
340
    public function hasWriteAccess()
341
    {
342
        $segments = server_request()->getUri()->getSegments()->getParts();
343
344
        if ($this->loggedIn()) {
345
            if ($account = globals()->offsetGet('account')) {
346
                if (in_array($account->user->role->id, [1, 2])) {
347
                    return true;
348
                }
349
350
                if ($model = models('modules')) {
351
352
                    if ($segment = $model->segments->find(implode('/', $segments), 'segments')) {
0 ignored issues
show
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Models\Sql\Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Models\NoSql\Model. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property segments does not exist on O2System\Framework\Containers\Models. Since you implemented __get, consider adding a @property annotation.
Loading history...
353
                        if ($authority = $model->segments->authorities->users->findWhere([
0 ignored issues
show
Bug Best Practice introduced by
The property authorities does not exist on O2System\Framework\Model...\DataObjects\Result\Row. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The property authorities does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
354
                            'id_sys_module_segment' => $segment->id,
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on O2System\Framework\Model...\DataObjects\Result\Row. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The property id does not seem to exist on O2System\Framework\Models\Sql\DataObjects\Result.
Loading history...
355
                            'id_sys_module_user'    => $account->user->moduleUser->id,
356
                        ])) {
357
                            if ($authority->first()->permission === 'WRITE') {
358
                                return true;
359
                            }
360
                        }
361
362
                        if ($authority = $model->segments->authorities->roles->findWhere([
363
                            'id_sys_module_segment' => $segment->id,
364
                            'id_sys_module_role'    => $account->user->role->id,
365
                        ])) {
366
                            if ($authority->first()->permission === 'WRITE') {
367
                                return true;
368
                            }
369
                        }
370
                    }
371
                }
372
            }
373
        }
374
375
        return false;
376
    }
377
378
    // ------------------------------------------------------------------------
379
380
    /**
381
     * User::getIframeCode
382
     *
383
     * @return string
384
     * @throws \Psr\Cache\InvalidArgumentException
385
     */
386
    public function getIframeCode()
387
    {
388
        if ($this->signedOn() && $this->loggedIn() === false) {
389
            return '<iframe id="sign-on-iframe" width="1" height="1" src="' . rtrim($this->config[ 'sso' ][ 'server' ],
390
                    '/') . '" style="display: none; visibility: hidden;"></iframe>';
391
        }
392
393
        return '';
394
    }
395
}