Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
73.29% |
236 / 322 |
|
33.33% |
4 / 12 |
CRAP | |
0.00% |
0 / 1 |
permission | |
73.29% |
236 / 322 |
|
33.33% |
4 / 12 |
182.16 | |
0.00% |
0 / 1 |
__construct | |
87.50% |
7 / 8 |
|
0.00% |
0 / 1 |
2.01 | |||
get_name | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
exists | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
add | |
100.00% |
31 / 31 |
|
100.00% |
1 / 1 |
9 | |||
remove | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
7 | |||
role_exists | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
3 | |||
role_add | |
94.12% |
16 / 17 |
|
0.00% |
0 / 1 |
3.00 | |||
role_update | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
role_remove | |
95.24% |
40 / 42 |
|
0.00% |
0 / 1 |
7 | |||
permission_set | |
95.24% |
80 / 84 |
|
0.00% |
0 / 1 |
18 | |||
permission_unset | |
0.00% |
0 / 50 |
|
0.00% |
0 / 1 |
110 | |||
reverse | |
32.26% |
10 / 31 |
|
0.00% |
0 / 1 |
41.09 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\db\migration\tool; |
15 | |
16 | /** |
17 | * Migration permission management tool |
18 | */ |
19 | class permission implements \phpbb\db\migration\tool\tool_interface |
20 | { |
21 | /** @var \phpbb\auth\auth */ |
22 | protected $auth; |
23 | |
24 | /** @var \auth_admin */ |
25 | protected $auth_admin; |
26 | |
27 | /** @var \phpbb\cache\service */ |
28 | protected $cache; |
29 | |
30 | /** @var \phpbb\db\driver\driver_interface */ |
31 | protected $db; |
32 | |
33 | /** @var string */ |
34 | protected $phpbb_root_path; |
35 | |
36 | /** @var string */ |
37 | protected $php_ext; |
38 | |
39 | /** |
40 | * Constructor |
41 | * |
42 | * @param \phpbb\db\driver\driver_interface $db |
43 | * @param \phpbb\cache\service $cache |
44 | * @param \phpbb\auth\auth $auth |
45 | * @param string $phpbb_root_path |
46 | * @param string $php_ext |
47 | */ |
48 | public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) |
49 | { |
50 | $this->db = $db; |
51 | $this->cache = $cache; |
52 | $this->auth = $auth; |
53 | $this->phpbb_root_path = $phpbb_root_path; |
54 | $this->php_ext = $php_ext; |
55 | |
56 | if (!class_exists('auth_admin')) |
57 | { |
58 | include($this->phpbb_root_path . 'includes/acp/auth.' . $this->php_ext); |
59 | } |
60 | $this->auth_admin = new \auth_admin(); |
61 | } |
62 | |
63 | /** |
64 | * {@inheritdoc} |
65 | */ |
66 | public function get_name() |
67 | { |
68 | return 'permission'; |
69 | } |
70 | |
71 | /** |
72 | * Permission Exists |
73 | * |
74 | * Check if a permission (auth) setting exists |
75 | * |
76 | * @param string $auth_option The name of the permission (auth) option |
77 | * @param bool $global True for checking a global permission setting, |
78 | * False for a local permission setting |
79 | * @return bool true if it exists, false if not |
80 | */ |
81 | public function exists($auth_option, $global = true) |
82 | { |
83 | if ($global) |
84 | { |
85 | $type_sql = ' AND is_global = 1'; |
86 | } |
87 | else |
88 | { |
89 | $type_sql = ' AND is_local = 1'; |
90 | } |
91 | |
92 | $sql = 'SELECT auth_option_id |
93 | FROM ' . ACL_OPTIONS_TABLE . " |
94 | WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" |
95 | . $type_sql; |
96 | $result = $this->db->sql_query($sql); |
97 | |
98 | $row = $this->db->sql_fetchrow($result); |
99 | $this->db->sql_freeresult($result); |
100 | |
101 | if ($row) |
102 | { |
103 | return true; |
104 | } |
105 | |
106 | return false; |
107 | } |
108 | |
109 | /** |
110 | * Permission Add |
111 | * |
112 | * Add a permission (auth) option |
113 | * |
114 | * @param string $auth_option The name of the permission (auth) option |
115 | * @param bool $global True for checking a global permission setting, |
116 | * False for a local permission setting |
117 | * @param int|false $copy_from If set, contains the id of the permission from which to copy the new one. |
118 | * @return void |
119 | */ |
120 | public function add($auth_option, $global = true, $copy_from = false) |
121 | { |
122 | if ($this->exists($auth_option, $global)) |
123 | { |
124 | return; |
125 | } |
126 | |
127 | // We have to add a check to see if the !$global (if global, local, and if local, global) permission already exists. If it does, acl_add_option currently has a bug which would break the ACL system, so we are having a work-around here. |
128 | if ($this->exists($auth_option, !$global)) |
129 | { |
130 | $sql_ary = array( |
131 | 'is_global' => 1, |
132 | 'is_local' => 1, |
133 | ); |
134 | $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' |
135 | SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . " |
136 | WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'"; |
137 | $this->db->sql_query($sql); |
138 | } |
139 | else |
140 | { |
141 | if ($global) |
142 | { |
143 | $this->auth_admin->acl_add_option(array('global' => array($auth_option))); |
144 | } |
145 | else |
146 | { |
147 | $this->auth_admin->acl_add_option(array('local' => array($auth_option))); |
148 | } |
149 | } |
150 | |
151 | // The permission has been added, now we can copy it if needed |
152 | if ($copy_from && isset($this->auth_admin->acl_options['id'][$copy_from])) |
153 | { |
154 | $old_id = $this->auth_admin->acl_options['id'][$copy_from]; |
155 | $new_id = $this->auth_admin->acl_options['id'][$auth_option]; |
156 | |
157 | $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); |
158 | |
159 | foreach ($tables as $table) |
160 | { |
161 | $sql = 'SELECT * |
162 | FROM ' . $table . ' |
163 | WHERE auth_option_id = ' . $old_id; |
164 | $result = $this->db->sql_query($sql); |
165 | |
166 | $sql_ary = array(); |
167 | while ($row = $this->db->sql_fetchrow($result)) |
168 | { |
169 | $row['auth_option_id'] = $new_id; |
170 | $sql_ary[] = $row; |
171 | } |
172 | $this->db->sql_freeresult($result); |
173 | |
174 | if (!empty($sql_ary)) |
175 | { |
176 | $this->db->sql_multi_insert($table, $sql_ary); |
177 | } |
178 | } |
179 | |
180 | $this->auth_admin->acl_clear_prefetch(); |
181 | } |
182 | } |
183 | |
184 | /** |
185 | * Permission Remove |
186 | * |
187 | * Remove a permission (auth) option |
188 | * |
189 | * @param string $auth_option The name of the permission (auth) option |
190 | * @param bool $global True for checking a global permission setting, |
191 | * False for a local permission setting |
192 | * @return void |
193 | */ |
194 | public function remove($auth_option, $global = true) |
195 | { |
196 | if (!$this->exists($auth_option, $global)) |
197 | { |
198 | return; |
199 | } |
200 | |
201 | if ($global) |
202 | { |
203 | $type_sql = ' AND is_global = 1'; |
204 | } |
205 | else |
206 | { |
207 | $type_sql = ' AND is_local = 1'; |
208 | } |
209 | $sql = 'SELECT auth_option_id, is_global, is_local |
210 | FROM ' . ACL_OPTIONS_TABLE . " |
211 | WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" . |
212 | $type_sql; |
213 | $result = $this->db->sql_query($sql); |
214 | $row = $this->db->sql_fetchrow($result); |
215 | $this->db->sql_freeresult($result); |
216 | |
217 | $id = (int) $row['auth_option_id']; |
218 | |
219 | // If it is a local and global permission, do not remove the row! :P |
220 | if ($row['is_global'] && $row['is_local']) |
221 | { |
222 | $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' |
223 | SET ' . (($global) ? 'is_global = 0' : 'is_local = 0') . ' |
224 | WHERE auth_option_id = ' . $id; |
225 | $this->db->sql_query($sql); |
226 | } |
227 | else |
228 | { |
229 | // Delete time |
230 | $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE, ACL_OPTIONS_TABLE); |
231 | foreach ($tables as $table) |
232 | { |
233 | $this->db->sql_query('DELETE FROM ' . $table . ' |
234 | WHERE auth_option_id = ' . $id); |
235 | } |
236 | } |
237 | |
238 | // Purge the auth cache |
239 | $this->cache->destroy('_acl_options'); |
240 | $this->auth->acl_clear_prefetch(); |
241 | } |
242 | |
243 | /** |
244 | * Check if a permission role exists |
245 | * |
246 | * @param string $role_name The role name |
247 | * |
248 | * @return int The id of the role if it exists, 0 otherwise |
249 | */ |
250 | public function role_exists($role_name) |
251 | { |
252 | $sql = 'SELECT role_id |
253 | FROM ' . ACL_ROLES_TABLE . " |
254 | WHERE role_name = '" . $this->db->sql_escape($role_name) . "'"; |
255 | $result = $this->db->sql_query($sql); |
256 | $role_id = (int) $this->db->sql_fetchfield('role_id'); |
257 | $this->db->sql_freeresult($result); |
258 | |
259 | // Try falling back to searching by role description for standard role titles |
260 | if (!$role_id && preg_match('/ROLE_(?<title>([A-Z]+_?)+)/', $role_name, $matches)) |
261 | { |
262 | $role_description = 'ROLE_DESCRIPTION_' . $matches['title']; |
263 | $sql = 'SELECT role_id |
264 | FROM ' . ACL_ROLES_TABLE . " |
265 | WHERE role_description = '" . $this->db->sql_escape($role_description) . "'"; |
266 | $result = $this->db->sql_query($sql); |
267 | $role_id = (int) $this->db->sql_fetchfield('role_id'); |
268 | $this->db->sql_freeresult($result); |
269 | } |
270 | |
271 | return $role_id; |
272 | } |
273 | |
274 | /** |
275 | * Add a new permission role |
276 | * |
277 | * @param string $role_name The new role name |
278 | * @param string $role_type The type (u_, m_, a_) |
279 | * @param string $role_description Description of the new role |
280 | * |
281 | * @return int|null Inserted SQL id or null if role already exists |
282 | */ |
283 | public function role_add($role_name, $role_type, $role_description = '') |
284 | { |
285 | if ($this->role_exists($role_name)) |
286 | { |
287 | return null; |
288 | } |
289 | |
290 | $sql = 'SELECT MAX(role_order) AS max_role_order |
291 | FROM ' . ACL_ROLES_TABLE . " |
292 | WHERE role_type = '" . $this->db->sql_escape($role_type) . "'"; |
293 | $this->db->sql_query($sql); |
294 | $role_order = (int) $this->db->sql_fetchfield('max_role_order'); |
295 | $role_order = (!$role_order) ? 1 : $role_order + 1; |
296 | |
297 | $sql_ary = array( |
298 | 'role_name' => $role_name, |
299 | 'role_description' => $role_description, |
300 | 'role_type' => $role_type, |
301 | 'role_order' => $role_order, |
302 | ); |
303 | |
304 | $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); |
305 | $this->db->sql_query($sql); |
306 | |
307 | return (int) $this->db->sql_nextid(); |
308 | } |
309 | |
310 | /** |
311 | * Update the name on a permission role |
312 | * |
313 | * @param string $old_role_name The old role name |
314 | * @param string $new_role_name The new role name |
315 | * @return void |
316 | * @throws \phpbb\db\migration\exception |
317 | */ |
318 | public function role_update($old_role_name, $new_role_name) |
319 | { |
320 | if (!$this->role_exists($old_role_name)) |
321 | { |
322 | throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $old_role_name); |
323 | } |
324 | |
325 | $sql = 'UPDATE ' . ACL_ROLES_TABLE . " |
326 | SET role_name = '" . $this->db->sql_escape($new_role_name) . "' |
327 | WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; |
328 | $this->db->sql_query($sql); |
329 | } |
330 | |
331 | /** |
332 | * Remove a permission role |
333 | * |
334 | * @param string $role_name The role name to remove |
335 | * @return void |
336 | */ |
337 | public function role_remove($role_name) |
338 | { |
339 | if (!($role_id = $this->role_exists($role_name))) |
340 | { |
341 | return; |
342 | } |
343 | |
344 | // Get the role type |
345 | $sql = 'SELECT role_type |
346 | FROM ' . ACL_ROLES_TABLE . ' |
347 | WHERE role_id = ' . (int) $role_id; |
348 | $result = $this->db->sql_query($sql); |
349 | $role_type = $this->db->sql_fetchfield('role_type'); |
350 | $this->db->sql_freeresult($result); |
351 | |
352 | // Get complete auth array |
353 | $sql = 'SELECT auth_option, auth_option_id |
354 | FROM ' . ACL_OPTIONS_TABLE . " |
355 | WHERE auth_option " . $this->db->sql_like_expression($role_type . $this->db->get_any_char()); |
356 | $result = $this->db->sql_query($sql); |
357 | |
358 | $auth_settings = []; |
359 | while ($row = $this->db->sql_fetchrow($result)) |
360 | { |
361 | $auth_settings[$row['auth_option']] = ACL_NO; |
362 | } |
363 | $this->db->sql_freeresult($result); |
364 | |
365 | // Get the role auth settings we need to re-set... |
366 | $sql = 'SELECT o.auth_option, r.auth_setting |
367 | FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o |
368 | WHERE o.auth_option_id = r.auth_option_id |
369 | AND r.role_id = ' . (int) $role_id; |
370 | $result = $this->db->sql_query($sql); |
371 | |
372 | while ($row = $this->db->sql_fetchrow($result)) |
373 | { |
374 | $auth_settings[$row['auth_option']] = $row['auth_setting']; |
375 | } |
376 | $this->db->sql_freeresult($result); |
377 | |
378 | // Get role assignments |
379 | $hold_ary = $this->auth_admin->get_role_mask($role_id); |
380 | |
381 | // Re-assign permissions |
382 | foreach ($hold_ary as $forum_id => $forum_ary) |
383 | { |
384 | if (isset($forum_ary['users'])) |
385 | { |
386 | $this->auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false); |
387 | } |
388 | |
389 | if (isset($forum_ary['groups'])) |
390 | { |
391 | $this->auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false); |
392 | } |
393 | } |
394 | |
395 | // Remove role from users and groups just to be sure (happens through acl_set) |
396 | $sql = 'DELETE FROM ' . ACL_USERS_TABLE . ' |
397 | WHERE auth_role_id = ' . $role_id; |
398 | $this->db->sql_query($sql); |
399 | |
400 | $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' |
401 | WHERE auth_role_id = ' . $role_id; |
402 | $this->db->sql_query($sql); |
403 | |
404 | $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' |
405 | WHERE role_id = ' . $role_id; |
406 | $this->db->sql_query($sql); |
407 | |
408 | $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' |
409 | WHERE role_id = ' . $role_id; |
410 | $this->db->sql_query($sql); |
411 | |
412 | $this->auth->acl_clear_prefetch(); |
413 | } |
414 | |
415 | /** |
416 | * Permission Set |
417 | * |
418 | * Allows you to set permissions for a certain group/role |
419 | * |
420 | * @param string $name The name of the role/group |
421 | * @param string|array $auth_option The auth_option or array of |
422 | * auth_options you would like to set |
423 | * @param string $type The type (role|group) |
424 | * @param bool $has_permission True if you want to give them permission, |
425 | * false if you want to deny them permission |
426 | * @return void |
427 | * @throws \phpbb\db\migration\exception |
428 | */ |
429 | public function permission_set($name, $auth_option, $type = 'role', $has_permission = true) |
430 | { |
431 | if (!is_array($auth_option)) |
432 | { |
433 | $auth_option = array($auth_option); |
434 | } |
435 | |
436 | $new_auth = array(); |
437 | $sql = 'SELECT auth_option_id |
438 | FROM ' . ACL_OPTIONS_TABLE . ' |
439 | WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); |
440 | $result = $this->db->sql_query($sql); |
441 | while ($row = $this->db->sql_fetchrow($result)) |
442 | { |
443 | $new_auth[] = (int) $row['auth_option_id']; |
444 | } |
445 | $this->db->sql_freeresult($result); |
446 | |
447 | $type = (string) $type; // Prevent PHP bug. |
448 | if (empty($new_auth) || !in_array($type, ['role','group'])) |
449 | { |
450 | return; |
451 | } |
452 | |
453 | $current_auth = array(); |
454 | |
455 | switch ($type) |
456 | { |
457 | case 'role': |
458 | if (!($role_id = $this->role_exists($name))) |
459 | { |
460 | throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name); |
461 | } |
462 | |
463 | $sql = 'SELECT auth_option_id, auth_setting |
464 | FROM ' . ACL_ROLES_DATA_TABLE . ' |
465 | WHERE role_id = ' . $role_id; |
466 | $result = $this->db->sql_query($sql); |
467 | while ($row = $this->db->sql_fetchrow($result)) |
468 | { |
469 | $current_auth[$row['auth_option_id']] = $row['auth_setting']; |
470 | } |
471 | $this->db->sql_freeresult($result); |
472 | break; |
473 | |
474 | case 'group': |
475 | $sql = 'SELECT group_id |
476 | FROM ' . GROUPS_TABLE . " |
477 | WHERE group_name = '" . $this->db->sql_escape($name) . "'"; |
478 | $this->db->sql_query($sql); |
479 | $group_id = (int) $this->db->sql_fetchfield('group_id'); |
480 | |
481 | if (!$group_id) |
482 | { |
483 | throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name); |
484 | } |
485 | |
486 | // If the group has a role set for them we will add the requested permissions to that role. |
487 | $sql = 'SELECT auth_role_id |
488 | FROM ' . ACL_GROUPS_TABLE . ' |
489 | WHERE group_id = ' . $group_id . ' |
490 | AND auth_role_id <> 0 |
491 | AND forum_id = 0'; |
492 | $this->db->sql_query($sql); |
493 | $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); |
494 | if ($role_id) |
495 | { |
496 | $sql = 'SELECT role_name, role_type |
497 | FROM ' . ACL_ROLES_TABLE . ' |
498 | WHERE role_id = ' . $role_id; |
499 | $this->db->sql_query($sql); |
500 | $role_data = $this->db->sql_fetchrow(); |
501 | if (!$role_data) |
502 | { |
503 | throw new \phpbb\db\migration\exception('ROLE_ASSIGNED_NOT_EXIST', $name, $role_id); |
504 | } |
505 | |
506 | $role_name = $role_data['role_name']; |
507 | $role_type = $role_data['role_type']; |
508 | |
509 | // Filter new auth options to match the role type: a_ | f_ | m_ | u_ |
510 | // Set new auth options to the role only if options matching the role type were found |
511 | $auth_option = array_filter($auth_option, |
512 | function ($option) use ($role_type) |
513 | { |
514 | return strpos($option, $role_type) === 0; |
515 | } |
516 | ); |
517 | |
518 | if (count($auth_option)) |
519 | { |
520 | $this->permission_set($role_name, $auth_option, 'role', $has_permission); |
521 | return; |
522 | } |
523 | } |
524 | |
525 | $sql = 'SELECT auth_option_id, auth_setting |
526 | FROM ' . ACL_GROUPS_TABLE . ' |
527 | WHERE group_id = ' . $group_id; |
528 | $result = $this->db->sql_query($sql); |
529 | while ($row = $this->db->sql_fetchrow($result)) |
530 | { |
531 | $current_auth[$row['auth_option_id']] = $row['auth_setting']; |
532 | } |
533 | $this->db->sql_freeresult($result); |
534 | break; |
535 | } |
536 | |
537 | $sql_ary = $auth_update_list = []; |
538 | $table = $type == 'role' ? ACL_ROLES_DATA_TABLE : ACL_GROUPS_TABLE; |
539 | foreach ($new_auth as $auth_option_id) |
540 | { |
541 | if (!isset($current_auth[$auth_option_id])) |
542 | { |
543 | $sql_ary[] = [ |
544 | $type . '_id' => ${$type . '_id'}, |
545 | 'auth_option_id' => $auth_option_id, |
546 | 'auth_setting' => (int) $has_permission, |
547 | ]; |
548 | } |
549 | else |
550 | { |
551 | $auth_update_list[] = $auth_option_id; |
552 | } |
553 | } |
554 | $this->db->sql_multi_insert($table, $sql_ary); |
555 | |
556 | if (count($auth_update_list)) |
557 | { |
558 | $sql = 'UPDATE ' . $table . ' |
559 | SET auth_setting = ' . (int) $has_permission . ' |
560 | WHERE ' . $this->db->sql_in_set('auth_option_id', $auth_update_list) . ' |
561 | AND ' . $type . '_id = ' . (int) ${$type . '_id'}; |
562 | $this->db->sql_query($sql); |
563 | } |
564 | |
565 | $this->auth->acl_clear_prefetch(); |
566 | } |
567 | |
568 | /** |
569 | * Permission Unset |
570 | * |
571 | * Allows you to unset (remove) permissions for a certain group/role |
572 | * |
573 | * @param string $name The name of the role/group |
574 | * @param string|array $auth_option The auth_option or array of |
575 | * auth_options you would like to set |
576 | * @param string $type The type (role|group) |
577 | * @return void |
578 | * @throws \phpbb\db\migration\exception |
579 | */ |
580 | public function permission_unset($name, $auth_option, $type = 'role') |
581 | { |
582 | if (!is_array($auth_option)) |
583 | { |
584 | $auth_option = array($auth_option); |
585 | } |
586 | |
587 | $to_remove = array(); |
588 | $sql = 'SELECT auth_option_id |
589 | FROM ' . ACL_OPTIONS_TABLE . ' |
590 | WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); |
591 | $result = $this->db->sql_query($sql); |
592 | while ($row = $this->db->sql_fetchrow($result)) |
593 | { |
594 | $to_remove[] = (int) $row['auth_option_id']; |
595 | } |
596 | $this->db->sql_freeresult($result); |
597 | |
598 | if (empty($to_remove)) |
599 | { |
600 | return; |
601 | } |
602 | |
603 | $type = (string) $type; // Prevent PHP bug. |
604 | |
605 | switch ($type) |
606 | { |
607 | case 'role': |
608 | if (!($role_id = $this->role_exists($name))) |
609 | { |
610 | throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name); |
611 | } |
612 | |
613 | $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' |
614 | WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove) . ' |
615 | AND role_id = ' . (int) $role_id; |
616 | $this->db->sql_query($sql); |
617 | break; |
618 | |
619 | case 'group': |
620 | $sql = 'SELECT group_id |
621 | FROM ' . GROUPS_TABLE . " |
622 | WHERE group_name = '" . $this->db->sql_escape($name) . "'"; |
623 | $this->db->sql_query($sql); |
624 | $group_id = (int) $this->db->sql_fetchfield('group_id'); |
625 | |
626 | if (!$group_id) |
627 | { |
628 | throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name); |
629 | } |
630 | |
631 | // If the group has a role set for them we will remove the requested permissions from that role. |
632 | $sql = 'SELECT auth_role_id |
633 | FROM ' . ACL_GROUPS_TABLE . ' |
634 | WHERE group_id = ' . $group_id . ' |
635 | AND auth_role_id <> 0'; |
636 | $this->db->sql_query($sql); |
637 | $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); |
638 | if ($role_id) |
639 | { |
640 | $sql = 'SELECT role_name |
641 | FROM ' . ACL_ROLES_TABLE . ' |
642 | WHERE role_id = ' . $role_id; |
643 | $this->db->sql_query($sql); |
644 | $role_name = $this->db->sql_fetchfield('role_name'); |
645 | if (!$role_name) |
646 | { |
647 | throw new \phpbb\db\migration\exception('ROLE_ASSIGNED_NOT_EXIST', $name, $role_id); |
648 | } |
649 | |
650 | $this->permission_unset($role_name, $auth_option, 'role'); |
651 | return; |
652 | } |
653 | |
654 | $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' |
655 | WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); |
656 | $this->db->sql_query($sql); |
657 | break; |
658 | } |
659 | |
660 | $this->auth->acl_clear_prefetch(); |
661 | } |
662 | |
663 | /** |
664 | * {@inheritdoc} |
665 | */ |
666 | public function reverse() |
667 | { |
668 | $arguments = func_get_args(); |
669 | $original_call = array_shift($arguments); |
670 | |
671 | $call = false; |
672 | switch ($original_call) |
673 | { |
674 | case 'add': |
675 | $call = 'remove'; |
676 | break; |
677 | |
678 | case 'remove': |
679 | $call = 'add'; |
680 | break; |
681 | |
682 | case 'permission_set': |
683 | $call = 'permission_unset'; |
684 | break; |
685 | |
686 | case 'permission_unset': |
687 | $call = 'permission_set'; |
688 | break; |
689 | |
690 | case 'role_add': |
691 | $call = 'role_remove'; |
692 | break; |
693 | |
694 | case 'role_remove': |
695 | $call = 'role_add'; |
696 | break; |
697 | |
698 | case 'role_update': |
699 | // Set to the original value if the current value is what we compared to originally |
700 | $arguments = array( |
701 | $arguments[1], |
702 | $arguments[0], |
703 | ); |
704 | break; |
705 | |
706 | case 'reverse': |
707 | // Reversing a reverse is just the call itself |
708 | $call = array_shift($arguments); |
709 | break; |
710 | } |
711 | |
712 | return $call ? call_user_func_array(array(&$this, $call), $arguments) : null; |
713 | } |
714 | } |