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 © 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')) { |
|
|
|
|
33
|
|
|
$this->container->db->createTable('rbac_role', [ |
|
|
|
|
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', |
|
|
|
|
56
|
|
|
['id' => $userId]) |
57
|
|
|
) { |
58
|
|
|
return $this->container->db->insert('rbac_user', ['role' => $name, 'user' => $userId]); |
|
|
|
|
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])) { |
|
|
|
|
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])) { |
|
|
|
|
100
|
|
|
return false; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
if (null !== $based && !$this->container->db->exists('rbac_role', ['name' => $based])) { |
|
|
|
|
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; |
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return $this->container->db->insert('rbac_role', |
|
|
|
|
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); |
|
|
|
|
134
|
|
|
if ($tree) { |
135
|
|
|
$this->recursiveDelete($tree); |
|
|
|
|
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); |
|
|
|
|
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']]); |
|
|
|
|
172
|
|
|
$this->container->db->delete('rbac_role', 'name=:name', ['name' => $element['name']]); |
|
|
|
|
173
|
|
|
|
174
|
|
|
if (!empty($tree['childs'])) { |
175
|
|
|
$this->recursiveDelete($element['childs']); |
176
|
|
|
} |
177
|
|
|
unset($tree[$key]); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
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.