Completed
Push — master ( 1bbe3a...a1970e )
by Oleg
08:32
created

DbAcl::createRole()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 3
Ratio 50 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 3
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
1
<?php /** MicroDbACL */
2
3
namespace Micro\Auth\Drivers;
4
5
use Micro\Db\IConnection;
6
use Micro\Mvc\Models\Query;
7
8
/**
9
 * Database ACL class file.
10
 *
11
 * ACL security logic with DB
12
 *
13
 * @author Oleg Lunegov <[email protected]>
14
 * @link https://github.com/linpax/microphp-framework
15
 * @copyright Copyright (c) 2013 Oleg Lunegov
16
 * @license https://github.com/linpax/microphp-framework/blob/master/LICENSE
17
 * @package Micro
18
 * @subpackage Auth\Drivers
19
 * @version 1.0
20
 * @since 1.0
21
 */
22
class DbAcl extends Acl
23
{
24
    /**
25
     * Constructor DB acl
26
     *
27
     * @access public
28
     *
29
     * @param IConnection $db
30
     * @param array $params config array
31
     *
32
     * @result void
33
     */
34
    public function __construct(IConnection $db, array $params = [])
35
    {
36
        parent::__construct($db, $params);
37
38
        /** @var array $tables */
39
        $tables = $this->db->listTables();
40
41
        if (empty($tables['acl_role'])) {
42
            $this->db->createTable('acl_role', [
43
                '`id` int(10) unsigned NOT NULL AUTO_INCREMENT',
44
                '`name` varchar(255) NOT NULL',
45
                'PRIMARY KEY (`id`)'
46
            ], 'ENGINE=MyISAM DEFAULT CHARSET=utf8');
47
        }
48 View Code Duplication
        if (empty($tables['acl_perm'])) {
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...
49
            $this->db->createTable('acl_perm', [
50
                '`id` int(10) unsigned NOT NULL AUTO_INCREMENT',
51
                '`name` varchar(255) NOT NULL',
52
                'PRIMARY KEY (`id`)'
53
            ], 'ENGINE=MyISAM DEFAULT CHARSET=utf8');
54
        }
55 View Code Duplication
        if (empty($tables['acl_role_perm'])) {
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...
56
            $this->db->createTable('acl_role_perm', [
57
                '`id` int(10) unsigned NOT NULL AUTO_INCREMENT',
58
                '`role` int(11) unsigned DEFAULT NOT NULL',
59
                '`perm` int(11) unsigned DEFAULT NOT NULL',
60
                'PRIMARY KEY (`id`)'
61
            ], 'ENGINE=MyISAM DEFAULT CHARSET=utf8');
62
        }
63
    }
64
65
    /**
66
     * Check user access to permission
67
     *
68
     * @access public
69
     *
70
     * @param integer $userId user id
71
     * @param string $permission checked permission
72
     * @param array $data for compatible, not used!
73
     *
74
     * @return bool
75
     * @throws \Micro\Base\Exception
76
     */
77
    public function check($userId, $permission, array $data = [])
78
    {
79
        $query = new Query($this->db);
80
        $query->select = '*';
81
        $query->table = '`acl_user` AS `au`';
82
83
        $query->addJoin('`acl_perm` AS  `ap`', '`ap`.`id` =  `au`.`perm`');
84
        $query->addJoin('`acl_role_perm` AS  `arp`', '`arp`.`role` =  `au`.`role`');
85
        $query->addJoin('`acl_perm` AS  `ap1`', '`ap1`.`id` =  `arp`.`perm`');
86
87
        $query->addWhere('`au`.`user`='.$userId);
88
        $query->addWhere('`ap`.`name`=:perm OR `ap1`.`name`=:perm');
89
90
        $query->limit = 1;
91
92
        $query->params = [':perm' => $permission];
93
        $query->single = true;
94
95
        return (bool)$query->run();
96
    }
97
98
    /**
99
     * Create new role
100
     *
101
     * @access public
102
     *
103
     * @param string $name role name
104
     *
105
     * @return void
106
     */
107
    public function createRole($name)
108
    {
109 View Code Duplication
        if (!$this->db->exists('acl_role', ['name' => $name])) {
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...
110
            $this->db->insert('acl_role', ['name' => $name]);
111
        }
112
    }
113
114
    /**
115
     * Create new permission
116
     *
117
     * @access public
118
     *
119
     * @param string $name permission name
120
     *
121
     * @return void
122
     */
123
    public function createPermission($name)
124
    {
125 View Code Duplication
        if (!$this->db->exists('acl_role', ['name' => $name])) {
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...
126
            $this->db->insert('acl_role', ['name' => $name]);
127
        }
128
    }
129
130
    /**
131
     * Delete permission by name
132
     *
133
     * @access public
134
     *
135
     * @param string $name permission name
136
     *
137
     * @return void
138
     */
139
    public function deletePermission($name)
140
    {
141
        $this->db->delete('acl_perm', ['name' => $name]);
0 ignored issues
show
Documentation introduced by
array('name' => $name) is of type array<string,string,{"name":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
142
    }
143
144
    /**
145
     * Delete role by name
146
     *
147
     * @access public
148
     *
149
     * @param string $name role name
150
     *
151
     * @return void
152
     * @throws \Micro\Base\Exception
153
     */
154
    public function deleteRole($name)
155
    {
156
        foreach ($this->rolePerms($name) AS $perm) {
157
            $this->db->delete('acl_role_perm', ['id' => $perm['perm']]);
0 ignored issues
show
Documentation introduced by
array('id' => $perm['perm']) is of type array<string,?,{"id":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158
        }
159
160
        $this->db->delete('acl_role', ['name' => $name]);
0 ignored issues
show
Documentation introduced by
array('name' => $name) is of type array<string,string,{"name":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
161
    }
162
163
    /**
164
     * Get role perms
165
     *
166
     * @access public
167
     *
168
     * @param string $role role name
169
     *
170
     * @return array
171
     * @throws \Micro\Base\Exception
172
     */
173 View Code Duplication
    protected function rolePerms($role)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
174
    {
175
        $query = new Query($this->db);
176
        $query->select = '*';
177
        $query->table = 'acl_role_perm';
178
        $query->addWhere('role='.$role);
179
        $query->single = false;
180
181
        return $query->run();
182
    }
183
184
    /**
185
     * Assign role permission
186
     *
187
     * @access public
188
     *
189
     * @param string $role role name
190
     * @param string $permission permission name
191
     *
192
     * @return void
193
     */
194
    public function assignRolePermission($role, $permission)
195
    {
196
        $this->db->insert('acl_role_perm', ['role' => $role, 'perm' => $permission]);
197
    }
198
199
    /**
200
     * Revoke role permission
201
     *
202
     * @access public
203
     *
204
     * @param string $role role name
205
     * @param string $permission permission name
206
     *
207
     * @return void
208
     */
209
    public function revokeRolePermission($role, $permission)
210
    {
211
        $this->db->delete('acl_role_perm', ['role' => $role, 'perm' => $permission]);
0 ignored issues
show
Documentation introduced by
array('role' => $role, 'perm' => $permission) is of type array<string,string,{"ro...ring","perm":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
212
    }
213
214
    /**
215
     * Grant privilege to user
216
     *
217
     * @access public
218
     *
219
     * @param integer $userId user ID
220
     * @param integer $privilege privilege ID
221
     * @param boolean $asRole as role?
222
     *
223
     * @return void
224
     */
225
    public function grantPrivilege($userId, $privilege = null, $asRole = true)
226
    {
227
        if ($asRole) {
228
            $this->db->insert('acl_user', ['user' => $userId, 'role' => $privilege]);
229
        } else {
230
            $this->db->insert('acl_user', ['user' => $userId, 'perm' => $privilege]);
231
        }
232
    }
233
234
    /**
235
     * Forbid privilege
236
     *
237
     * @access public
238
     *
239
     * @param integer $userId user ID
240
     * @param integer $privilege privilege ID
241
     * @param bool $asRole as role?
242
     */
243
    public function forbidPrivilege($userId, $privilege = null, $asRole = true)
244
    {
245
        if ($asRole) {
246
            $this->db->delete('acl_user', '`user`="'.$userId.'" AND `role`="'.$privilege.'"');
247
        } else {
248
            $this->db->delete('acl_user', '`user`="'.$userId.'" AND `perm`="'.$privilege.'"');
249
        }
250
    }
251
}
252