Completed
Push — master ( 579af5...b29473 )
by Oleg
07:53
created

DbRbac::check()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 3
1
<?php /** MicroDbRBAC */
2
3
namespace Micro\Auth;
4
5
use Micro\Mvc\Models\Query;
6
7
/**
8
 * Database RBAC class file.
9
 *
10
 * RBAC security logic with DB
11
 *
12
 * @author Oleg Lunegov <[email protected]>
13
 * @link https://github.com/lugnsk/micro
14
 * @copyright Copyright &copy; 2013 Oleg Lunegov
15
 * @license /LICENSE
16
 * @package Micro
17
 * @subpackage Auth
18
 * @version 1.0
19
 * @since 1.0
20
 */
21
class DbRbac extends Rbac
22
{
23
    /**
24
     * Constructor file RBAC
25
     *
26
     * @inheritdoc
27
     */
28
    public function __construct(array $params = [])
29
    {
30
        parent::__construct($params);
31
32 View Code Duplication
        if (!$this->container->db->tableExists('rbac_role')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
33
            $this->container->db->createTable('rbac_role', [
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
34
                '`name` varchar(127) NOT NULL',
35
                '`type` int(11) NOT NULL DEFAULT \'0\'',
36
                '`based` varchar(127)',
37
                '`data` text',
38
                'UNIQUE KEY `name` (`name`)'
39
            ], 'ENGINE=MyISAM DEFAULT CHARSET=utf8');
40
        }
41
    }
42
43
    /**
44
     * Assign RBAC element into user
45
     *
46
     * @access public
47
     *
48
     * @param integer $userId user ID
49
     * @param string $name assign element name
50
     *
51
     * @return bool
52
     */
53
    public function assign($userId, $name)
54
    {
55
        if ($this->container->db->exists('rbac_role', ['name' => $name]) && $this->container->db->exists('user',
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
56
                ['id' => $userId])
57
        ) {
58
            return $this->container->db->insert('rbac_user', ['role' => $name, 'user' => $userId]);
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
59
        }
60
61
        return false;
62
    }
63
64
    /**
65
     * Check privileges to operation
66
     *
67
     * @access public
68
     *
69
     * @param integer $userId user id
70
     * @param string $action checked action
71
     * @param array $data action params
72
     *
73
     * @return boolean
74
     * @throws \Micro\Base\Exception
75
     */
76
    public function check($userId, $action, array $data = [])
77
    {
78
        if (!$this->container->db->exists('rbac_role', ['name' => $action])) {
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
79
            return false;
80
        }
81
82
        return parent::check($userId, $action, $data);
83
    }
84
85
    /**
86
     * Add new element into RBAC rules
87
     *
88
     * @access public
89
     *
90
     * @param string $name element name
91
     * @param int $type element type
92
     * @param string $based based element name
93
     * @param string $data element params
94
     *
95
     * @return bool
96
     */
97
    public function create($name, $type = self::TYPE_ROLE, $based = null, $data = null)
98
    {
99
        if ($this->container->db->exists('rbac_role', ['name' => $name])) {
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
100
            return false;
101
        }
102
103
        if (null !== $based && !$this->container->db->exists('rbac_role', ['name' => $based])) {
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
104
            return false;
105
        }
106
107
        switch ($type) {
108
            case Rbac::TYPE_ROLE:
109
            case Rbac::TYPE_OPERATION:
110
            case Rbac::TYPE_PERMISSION:
111
                break;
112
            default:
113
                return false;
114
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
115
        }
116
117
        return $this->container->db->insert('rbac_role',
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
118
            ['name' => $name, 'type' => $type, 'based' => $based, 'data' => $data]);
119
    }
120
121
    /**
122
     * Delete element from RBAC rules
123
     *
124
     * @access public
125
     *
126
     * @param string $name element name
127
     *
128
     * @result void
129
     * @throws \Micro\Base\Exception
130
     */
131
    public function delete($name)
132
    {
133
        $tree = $this->searchRoleRecursive($this->tree($this->rawRoles()), $name);
0 ignored issues
show
Bug introduced by
$this->rawRoles() cannot be passed to tree() as the parameter $elements expects a reference.
Loading history...
134
        if ($tree) {
135
            $this->recursiveDelete($tree);
0 ignored issues
show
Bug introduced by
It seems like $tree defined by $this->searchRoleRecursi...is->rawRoles()), $name) on line 133 can also be of type boolean; however, Micro\Auth\DbRbac::recursiveDelete() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
136
        }
137
    }
138
139
    /**
140
     * Get raw roles
141
     *
142
     * @access public
143
     *
144
     * @param int $pdo PHPDataObject fetch key
145
     *
146
     * @return mixed
147
     * @throws \Micro\Base\Exception
148
     */
149
    public function rawRoles($pdo = \PDO::FETCH_ASSOC)
150
    {
151
        $query = new Query($this->container->db);
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
152
        $query->table = 'rbac_role';
153
        $query->order = '`type` ASC';
154
        $query->single = false;
155
156
        return $query->run($pdo);
157
    }
158
159
    /**
160
     * Recursive delete roles from array
161
     *
162
     * @access public
163
     *
164
     * @param array $tree elements tree
165
     *
166
     * @return void
167
     */
168
    public function recursiveDelete(&$tree)
169
    {
170
        foreach ($tree AS $key => $element) {
171
            $this->container->db->delete('rbac_user', 'role=:name', ['name' => $element['name']]);
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
172
            $this->container->db->delete('rbac_role', 'name=:name', ['name' => $element['name']]);
0 ignored issues
show
Bug introduced by
Accessing db on the interface Micro\Base\IContainer suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
173
174
            if (!empty($tree['childs'])) {
175
                $this->recursiveDelete($element['childs']);
176
            }
177
            unset($tree[$key]);
178
        }
179
    }
180
}
181