Completed
Push — master ( 35bbd7...f1d334 )
by Andrii
05:32
created

User::getIsAlphaTester()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 0
cts 9
cp 0
rs 9.4285
cc 2
eloc 10
nc 2
nop 0
crap 6
1
<?php
2
/**
3
 * HiPanel core package.
4
 *
5
 * @link      https://hipanel.com/
6
 * @package   hipanel-core
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2014-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\components;
12
13
use Yii;
14
use yii\base\InvalidCallException;
15
use yii\base\InvalidConfigException;
16
17
class User extends \yii\web\User
18
{
19
    public $isGuestAllowed = false;
20
21
    /**
22
     * @var string the seller login
23
     */
24
    public $seller;
25
26
    public function init()
27
    {
28
        parent::init();
29
        if (empty($this->seller)) {
30
            throw new InvalidConfigException('User "seller" must be set');
31
        }
32
    }
33
34
    public function not($key)
35
    {
36
        $identity = $this->getIdentity();
37
        if (!$identity) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $identity of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
38
            throw new InvalidCallException();
39
        }
40
41
        return $identity->not($key);
0 ignored issues
show
Bug introduced by
The method not cannot be called on $identity (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
42
    }
43
44
    public function is($key)
45
    {
46
        $identity = $this->getIdentity();
47
        if (!$identity) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $identity of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
48
            throw new InvalidCallException();
49
        }
50
51
        return $identity->is($key);
0 ignored issues
show
Bug introduced by
The method is cannot be called on $identity (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     * XXX fixes redirect loop when identity is set but the object is empty.
57
     * @return bool
58
     */
59
    public function getIsGuest()
60
    {
61
        return empty($this->getIdentity()->id);
62
    }
63
64
    public function getIsAlphaTester()
65
    {
66
        $identity = $this->getIdentity();
67
        if (!$identity) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $identity of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
68
            return false;
69
        }
70
71
        return in_array($identity->username, [
72
            'sol', 'solex',
73
            'tofid', 'tafid',
74
            'silverfire', 'rubbertire',
75
            'bladeroot', 'phoenix',
76
        ], true);
77
    }
78
79
    public function getIsBetaTester()
80
    {
81
        if ($this->isAlphaTester) {
0 ignored issues
show
Documentation introduced by
The property isAlphaTester does not exist on object<hipanel\components\User>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
82
            return true;
83
        }
84
        $identity = $this->getIdentity();
85
        if (!$identity) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $identity of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
86
            return false;
87
        }
88
89
        return in_array($identity->username, ['andre', 'shurik'], true);
90
    }
91
92
    /**
93
     * Prepares authorization data.
94
     * Redirects to authorization if necessary.
95
     * @return array
96
     */
97
    public function getAuthData()
98
    {
99
        if ($this->isGuest) {
100
            if ($this->isGuestAllowed) {
101
                return [];
102
            } else {
103
                $this->redirectLogin();
104
            }
105
        }
106
107
        $token = $this->identity->getAccessToken();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface yii\web\IdentityInterface as the method getAccessToken() does only exist in the following implementations of said interface: hipanel\models\User.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
108
        if (empty($token)) {
109
            /// logout() is very important here, else - redirect loop
110
            $this->logout();
111
            $this->redirectLogin();
112
        }
113
114
        return [
115
            'access_token' => $token,
116
            'auth_ip' => Yii::$app->request->getUserIP(),
117
        ];
118
    }
119
120
    public function redirectLogin()
121
    {
122
        $this->loginRequired();
123
        Yii::$app->end();
124
    }
125
}
126