Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 86 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
PermissionQueryBuilder | |
0.00% |
0 / 86 |
|
0.00% |
0 / 9 |
870 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
groups | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
account | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
units | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
apps | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
categories | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
modules | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
permission | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
query | |
0.00% |
0 / 71 |
|
0.00% |
0 / 1 |
462 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package Modules\Admin\Models |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace Modules\Admin\Models; |
16 | |
17 | use phpOMS\Account\PermissionType; |
18 | use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; |
19 | use phpOMS\DataStorage\Database\Query\Builder; |
20 | use phpOMS\DataStorage\Database\Query\Where; |
21 | |
22 | /** |
23 | * Query builder for selects which immediately check if a user/group has the appropriate permissions |
24 | * |
25 | * @package Modules\Admin\Models |
26 | * @license OMS License 2.0 |
27 | * @link https://jingga.app |
28 | * @since 1.0.0 |
29 | */ |
30 | final class PermissionQueryBuilder |
31 | { |
32 | /** |
33 | * Database connection |
34 | * |
35 | * @var ConnectionAbstract |
36 | * @since 1.0.0 |
37 | */ |
38 | private ConnectionAbstract $connection; |
39 | |
40 | /** |
41 | * Group ids. |
42 | * |
43 | * @var array |
44 | * @since 1.0.0 |
45 | */ |
46 | private array $groups = []; |
47 | |
48 | /** |
49 | * Account id. |
50 | * |
51 | * @var int |
52 | */ |
53 | public int $account = 0; |
54 | |
55 | /** |
56 | * Unit ids. |
57 | * |
58 | * @var array |
59 | * @since 1.0.0 |
60 | */ |
61 | private array $units = [null]; |
62 | |
63 | /** |
64 | * Ap ids. |
65 | * |
66 | * @var array |
67 | * @since 1.0.0 |
68 | */ |
69 | private array $apps = [null]; |
70 | |
71 | /** |
72 | * Module names. |
73 | * |
74 | * @var array |
75 | * @since 1.0.0 |
76 | */ |
77 | private array $modules = [null]; |
78 | |
79 | /** |
80 | * Category ids. |
81 | * |
82 | * @var array |
83 | * @since 1.0.0 |
84 | */ |
85 | private array $categories = [null]; |
86 | |
87 | /** |
88 | * Permission flag |
89 | * |
90 | * @var int |
91 | * @since 1.0.0 |
92 | */ |
93 | private int $permission = 0; |
94 | |
95 | /** |
96 | * Constructor. |
97 | * |
98 | * @param ConnectionAbstract $connection Database connection |
99 | * |
100 | * @since 1.0.0 |
101 | */ |
102 | public function __construct(ConnectionAbstract $connection) |
103 | { |
104 | $this->connection = $connection; |
105 | } |
106 | |
107 | /** |
108 | * Set group ids |
109 | * |
110 | * @param array $groups Group ids |
111 | * |
112 | * @return self |
113 | * |
114 | * @since 1.0.0 |
115 | */ |
116 | public function groups(array $groups) : self |
117 | { |
118 | $this->groups = $groups; |
119 | |
120 | return $this; |
121 | } |
122 | |
123 | /** |
124 | * Set account id |
125 | * |
126 | * @param int $account Account id |
127 | * |
128 | * @return self |
129 | * |
130 | * @since 1.0.0 |
131 | */ |
132 | public function account(int $account) : self |
133 | { |
134 | $this->account = $account; |
135 | |
136 | return $this; |
137 | } |
138 | |
139 | /** |
140 | * Set unit ids |
141 | * |
142 | * @param array $units Unit ids |
143 | * |
144 | * @return self |
145 | * |
146 | * @since 1.0.0 |
147 | */ |
148 | public function units(array $units) : self |
149 | { |
150 | $this->units = $units; |
151 | |
152 | return $this; |
153 | } |
154 | |
155 | /** |
156 | * Set app ids |
157 | * |
158 | * @param array $apps App ids |
159 | * |
160 | * @return self |
161 | * |
162 | * @since 1.0.0 |
163 | */ |
164 | public function apps(array $apps) : self |
165 | { |
166 | $this->apps = $apps; |
167 | |
168 | return $this; |
169 | } |
170 | |
171 | /** |
172 | * Set category ids |
173 | * |
174 | * @param array $categories Category ids |
175 | * |
176 | * @return self |
177 | * |
178 | * @since 1.0.0 |
179 | */ |
180 | public function categories(array $categories) : self |
181 | { |
182 | $this->categories = $categories; |
183 | |
184 | return $this; |
185 | } |
186 | |
187 | /** |
188 | * Set module ids |
189 | * |
190 | * @param array $modules Module ids |
191 | * |
192 | * @return self |
193 | * |
194 | * @since 1.0.0 |
195 | */ |
196 | public function modules(array $modules) : self |
197 | { |
198 | $this->modules = $modules; |
199 | |
200 | return $this; |
201 | } |
202 | |
203 | /** |
204 | * Set permission flags |
205 | * |
206 | * @param int $permission Permission flags |
207 | * |
208 | * @return self |
209 | * |
210 | * @since 1.0.0 |
211 | */ |
212 | public function permission(int $permission) : self |
213 | { |
214 | $this->permission = $permission; |
215 | |
216 | return $this; |
217 | } |
218 | |
219 | /** |
220 | * Create permission sub query for |
221 | * |
222 | * The sub query checks permissons only for specific models/db entries. |
223 | * More general permissions for an entier module etc. are handled differently. |
224 | * The reason individual models/db entries are handled this way is because this process is very slow and therefore the general check should be done first and only if that doesn't give results this very specifc solution should be used. |
225 | * |
226 | * @param string $idField Table column which contains the primary id (this is the field the permission is associated with) |
227 | * |
228 | * @return Builder |
229 | * |
230 | * @since 1.0.0 |
231 | */ |
232 | public function query(string $idField) : Builder |
233 | { |
234 | $where = new Where($this->connection); |
235 | |
236 | $hasRead = ($this->permission & PermissionType::READ) === PermissionType::READ; |
237 | $hasCreate = ($this->permission & PermissionType::CREATE) === PermissionType::CREATE; |
238 | $hasModify = ($this->permission & PermissionType::MODIFY) === PermissionType::MODIFY; |
239 | $hasDelete = ($this->permission & PermissionType::DELETE) === PermissionType::DELETE; |
240 | $hasPermission = ($this->permission & PermissionType::PERMISSION) === PermissionType::PERMISSION; |
241 | |
242 | // Handle account permissions |
243 | if (!empty($this->account)) { |
244 | $accountPermission = new Builder($this->connection); |
245 | $accountPermission->select('account_permission_element') |
246 | ->from('account_permission') |
247 | ->where('account_permission_account', '=', $this->account); |
248 | |
249 | $subWhere = new Where($this->connection); |
250 | foreach ($this->units as $unit) { |
251 | $subWhere->orWhere('account_permission_unit', '=', $unit); |
252 | } |
253 | |
254 | $accountPermission->where($subWhere); |
255 | |
256 | $subWhere = new Where($this->connection); |
257 | foreach ($this->apps as $app) { |
258 | $subWhere->orWhere('account_permission_app', '=', $app); |
259 | } |
260 | |
261 | $accountPermission->where($subWhere); |
262 | |
263 | $subWhere = new Where($this->connection); |
264 | foreach ($this->modules as $module) { |
265 | $subWhere->orWhere('account_permission_module', '=', $module); |
266 | } |
267 | |
268 | $accountPermission->where($subWhere); |
269 | |
270 | $subWhere = new Where($this->connection); |
271 | foreach ($this->categories as $category) { |
272 | $subWhere->orWhere('account_permission_category', '=', $category); |
273 | } |
274 | |
275 | $accountPermission->where($subWhere); |
276 | |
277 | if ($hasRead) { |
278 | $accountPermission->where('account_permission_hasread', '=', $hasRead); |
279 | } |
280 | |
281 | if ($hasCreate) { |
282 | $accountPermission->where('account_permission_hascreate', '=', $hasCreate); |
283 | } |
284 | |
285 | if ($hasModify) { |
286 | $accountPermission->where('account_permission_hasmodify', '=', $hasModify); |
287 | } |
288 | |
289 | if ($hasDelete) { |
290 | $accountPermission->where('account_permission_hasdelete', '=', $hasDelete); |
291 | } |
292 | |
293 | if ($hasPermission) { |
294 | $accountPermission->where('account_permission_haspermission', '=', $hasPermission); |
295 | } |
296 | |
297 | $where->where($idField, 'in', $accountPermission); |
298 | } |
299 | |
300 | // Handle group permissions |
301 | if (!empty($this->groups)) { |
302 | $groupPermission = new Builder($this->connection); |
303 | $groupPermission->select('group_permission_element') |
304 | ->from('group_permission') |
305 | ->where('group_permission_group', 'IN', $this->groups); |
306 | |
307 | $subWhere = new Where($this->connection); |
308 | foreach ($this->units as $unit) { |
309 | $subWhere->orWhere('group_permission_unit', '=', $unit); |
310 | } |
311 | |
312 | $groupPermission->where($subWhere); |
313 | |
314 | $subWhere = new Where($this->connection); |
315 | foreach ($this->apps as $app) { |
316 | $subWhere->orWhere('group_permission_app', '=', $app); |
317 | } |
318 | |
319 | $groupPermission->where($subWhere); |
320 | |
321 | $subWhere = new Where($this->connection); |
322 | foreach ($this->modules as $module) { |
323 | $subWhere->orWhere('group_permission_module', '=', $module); |
324 | } |
325 | |
326 | $groupPermission->where($subWhere); |
327 | |
328 | $subWhere = new Where($this->connection); |
329 | foreach ($this->categories as $category) { |
330 | $subWhere->orWhere('group_permission_category', '=', $category); |
331 | } |
332 | |
333 | $groupPermission->where($subWhere); |
334 | |
335 | if ($hasRead) { |
336 | $groupPermission->where('group_permission_hasread', '=', $hasRead); |
337 | } |
338 | |
339 | if ($hasCreate) { |
340 | $groupPermission->where('group_permission_hascreate', '=', $hasCreate); |
341 | } |
342 | |
343 | if ($hasModify) { |
344 | $groupPermission->where('group_permission_hasmodify', '=', $hasModify); |
345 | } |
346 | |
347 | if ($hasDelete) { |
348 | $groupPermission->where('group_permission_hasdelete', '=', $hasDelete); |
349 | } |
350 | |
351 | if ($hasPermission) { |
352 | $groupPermission->where('group_permission_haspermission', '=', $hasPermission); |
353 | } |
354 | |
355 | $where->orWhere($idField, 'in', $groupPermission); |
356 | } |
357 | |
358 | return $where; |
359 | } |
360 | } |