[ Index ] |
PHP Cross Reference of phpBB-3.3.2-deutsch |
[Summary view] [Print] [Text view]
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 \phpbb\cache\service */ 25 protected $cache; 26 27 /** @var \phpbb\db\driver\driver_interface */ 28 protected $db; 29 30 /** @var string */ 31 protected $phpbb_root_path; 32 33 /** @var string */ 34 protected $php_ext; 35 36 /** 37 * Constructor 38 * 39 * @param \phpbb\db\driver\driver_interface $db 40 * @param \phpbb\cache\service $cache 41 * @param \phpbb\auth\auth $auth 42 * @param string $phpbb_root_path 43 * @param string $php_ext 44 */ 45 public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) 46 { 47 $this->db = $db; 48 $this->cache = $cache; 49 $this->auth = $auth; 50 $this->phpbb_root_path = $phpbb_root_path; 51 $this->php_ext = $php_ext; 52 } 53 54 /** 55 * {@inheritdoc} 56 */ 57 public function get_name() 58 { 59 return 'permission'; 60 } 61 62 /** 63 * Permission Exists 64 * 65 * Check if a permission (auth) setting exists 66 * 67 * @param string $auth_option The name of the permission (auth) option 68 * @param bool $global True for checking a global permission setting, 69 * False for a local permission setting 70 * @return bool true if it exists, false if not 71 */ 72 public function exists($auth_option, $global = true) 73 { 74 if ($global) 75 { 76 $type_sql = ' AND is_global = 1'; 77 } 78 else 79 { 80 $type_sql = ' AND is_local = 1'; 81 } 82 83 $sql = 'SELECT auth_option_id 84 FROM ' . ACL_OPTIONS_TABLE . " 85 WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'" 86 . $type_sql; 87 $result = $this->db->sql_query($sql); 88 89 $row = $this->db->sql_fetchrow($result); 90 $this->db->sql_freeresult($result); 91 92 if ($row) 93 { 94 return true; 95 } 96 97 return false; 98 } 99 100 /** 101 * Permission Add 102 * 103 * Add a permission (auth) option 104 * 105 * @param string $auth_option The name of the permission (auth) option 106 * @param bool $global True for checking a global permission setting, 107 * False for a local permission setting 108 * @param int|false $copy_from If set, contains the id of the permission from which to copy the new one. 109 * @return null 110 */ 111 public function add($auth_option, $global = true, $copy_from = false) 112 { 113 if ($this->exists($auth_option, $global)) 114 { 115 return; 116 } 117 118 // We've added permissions, so set to true to notify the user. 119 $this->permissions_added = true; 120 121 if (!class_exists('auth_admin')) 122 { 123 include($this->phpbb_root_path . 'includes/acp/auth.' . $this->php_ext); 124 } 125 $auth_admin = new \auth_admin(); 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 $auth_admin->acl_add_option(array('global' => array($auth_option))); 144 } 145 else 146 { 147 $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($auth_admin->acl_options['id'][$copy_from])) 153 { 154 $old_id = $auth_admin->acl_options['id'][$copy_from]; 155 $new_id = $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 $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 null 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 return $role_id; 260 } 261 262 /** 263 * Add a new permission role 264 * 265 * @param string $role_name The new role name 266 * @param string $role_type The type (u_, m_, a_) 267 * @param string $role_description Description of the new role 268 * 269 * @return null 270 */ 271 public function role_add($role_name, $role_type, $role_description = '') 272 { 273 if ($this->role_exists($role_name)) 274 { 275 return; 276 } 277 278 $sql = 'SELECT MAX(role_order) AS max_role_order 279 FROM ' . ACL_ROLES_TABLE . " 280 WHERE role_type = '" . $this->db->sql_escape($role_type) . "'"; 281 $this->db->sql_query($sql); 282 $role_order = (int) $this->db->sql_fetchfield('max_role_order'); 283 $role_order = (!$role_order) ? 1 : $role_order + 1; 284 285 $sql_ary = array( 286 'role_name' => $role_name, 287 'role_description' => $role_description, 288 'role_type' => $role_type, 289 'role_order' => $role_order, 290 ); 291 292 $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); 293 $this->db->sql_query($sql); 294 } 295 296 /** 297 * Update the name on a permission role 298 * 299 * @param string $old_role_name The old role name 300 * @param string $new_role_name The new role name 301 * @return null 302 * @throws \phpbb\db\migration\exception 303 */ 304 public function role_update($old_role_name, $new_role_name) 305 { 306 if (!$this->role_exists($old_role_name)) 307 { 308 throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $old_role_name); 309 } 310 311 $sql = 'UPDATE ' . ACL_ROLES_TABLE . " 312 SET role_name = '" . $this->db->sql_escape($new_role_name) . "' 313 WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'"; 314 $this->db->sql_query($sql); 315 } 316 317 /** 318 * Remove a permission role 319 * 320 * @param string $role_name The role name to remove 321 * @return null 322 */ 323 public function role_remove($role_name) 324 { 325 if (!($role_id = $this->role_exists($role_name))) 326 { 327 return; 328 } 329 330 $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' 331 WHERE role_id = ' . $role_id; 332 $this->db->sql_query($sql); 333 334 $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' 335 WHERE role_id = ' . $role_id; 336 $this->db->sql_query($sql); 337 338 $this->auth->acl_clear_prefetch(); 339 } 340 341 /** 342 * Permission Set 343 * 344 * Allows you to set permissions for a certain group/role 345 * 346 * @param string $name The name of the role/group 347 * @param string|array $auth_option The auth_option or array of 348 * auth_options you would like to set 349 * @param string $type The type (role|group) 350 * @param bool $has_permission True if you want to give them permission, 351 * false if you want to deny them permission 352 * @return null 353 * @throws \phpbb\db\migration\exception 354 */ 355 public function permission_set($name, $auth_option, $type = 'role', $has_permission = true) 356 { 357 if (!is_array($auth_option)) 358 { 359 $auth_option = array($auth_option); 360 } 361 362 $new_auth = array(); 363 $sql = 'SELECT auth_option_id 364 FROM ' . ACL_OPTIONS_TABLE . ' 365 WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); 366 $result = $this->db->sql_query($sql); 367 while ($row = $this->db->sql_fetchrow($result)) 368 { 369 $new_auth[] = (int) $row['auth_option_id']; 370 } 371 $this->db->sql_freeresult($result); 372 373 if (empty($new_auth)) 374 { 375 return; 376 } 377 378 $current_auth = array(); 379 380 $type = (string) $type; // Prevent PHP bug. 381 382 switch ($type) 383 { 384 case 'role': 385 if (!($role_id = $this->role_exists($name))) 386 { 387 throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name); 388 } 389 390 $sql = 'SELECT auth_option_id, auth_setting 391 FROM ' . ACL_ROLES_DATA_TABLE . ' 392 WHERE role_id = ' . $role_id; 393 $result = $this->db->sql_query($sql); 394 while ($row = $this->db->sql_fetchrow($result)) 395 { 396 $current_auth[$row['auth_option_id']] = $row['auth_setting']; 397 } 398 $this->db->sql_freeresult($result); 399 break; 400 401 case 'group': 402 $sql = 'SELECT group_id 403 FROM ' . GROUPS_TABLE . " 404 WHERE group_name = '" . $this->db->sql_escape($name) . "'"; 405 $this->db->sql_query($sql); 406 $group_id = (int) $this->db->sql_fetchfield('group_id'); 407 408 if (!$group_id) 409 { 410 throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name); 411 } 412 413 // If the group has a role set for them we will add the requested permissions to that role. 414 $sql = 'SELECT auth_role_id 415 FROM ' . ACL_GROUPS_TABLE . ' 416 WHERE group_id = ' . $group_id . ' 417 AND auth_role_id <> 0 418 AND forum_id = 0'; 419 $this->db->sql_query($sql); 420 $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); 421 if ($role_id) 422 { 423 $sql = 'SELECT role_name, role_type 424 FROM ' . ACL_ROLES_TABLE . ' 425 WHERE role_id = ' . $role_id; 426 $this->db->sql_query($sql); 427 $role_data = $this->db->sql_fetchrow(); 428 $role_name = $role_data['role_name']; 429 $role_type = $role_data['role_type']; 430 431 // Filter new auth options to match the role type: a_ | f_ | m_ | u_ 432 // Set new auth options to the role only if options matching the role type were found 433 $auth_option = array_filter($auth_option, 434 function ($option) use ($role_type) 435 { 436 return strpos($option, $role_type) === 0; 437 } 438 ); 439 440 if (count($auth_option)) 441 { 442 return $this->permission_set($role_name, $auth_option, 'role', $has_permission); 443 } 444 } 445 446 $sql = 'SELECT auth_option_id, auth_setting 447 FROM ' . ACL_GROUPS_TABLE . ' 448 WHERE group_id = ' . $group_id; 449 $result = $this->db->sql_query($sql); 450 while ($row = $this->db->sql_fetchrow($result)) 451 { 452 $current_auth[$row['auth_option_id']] = $row['auth_setting']; 453 } 454 $this->db->sql_freeresult($result); 455 break; 456 } 457 458 $sql_ary = array(); 459 switch ($type) 460 { 461 case 'role': 462 foreach ($new_auth as $auth_option_id) 463 { 464 if (!isset($current_auth[$auth_option_id])) 465 { 466 $sql_ary[] = array( 467 'role_id' => $role_id, 468 'auth_option_id' => $auth_option_id, 469 'auth_setting' => $has_permission, 470 ); 471 } 472 } 473 474 $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); 475 break; 476 477 case 'group': 478 foreach ($new_auth as $auth_option_id) 479 { 480 if (!isset($current_auth[$auth_option_id])) 481 { 482 $sql_ary[] = array( 483 'group_id' => $group_id, 484 'auth_option_id' => $auth_option_id, 485 'auth_setting' => $has_permission, 486 ); 487 } 488 } 489 490 $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); 491 break; 492 } 493 494 $this->auth->acl_clear_prefetch(); 495 } 496 497 /** 498 * Permission Unset 499 * 500 * Allows you to unset (remove) permissions for a certain group/role 501 * 502 * @param string $name The name of the role/group 503 * @param string|array $auth_option The auth_option or array of 504 * auth_options you would like to set 505 * @param string $type The type (role|group) 506 * @return null 507 * @throws \phpbb\db\migration\exception 508 */ 509 public function permission_unset($name, $auth_option, $type = 'role') 510 { 511 if (!is_array($auth_option)) 512 { 513 $auth_option = array($auth_option); 514 } 515 516 $to_remove = array(); 517 $sql = 'SELECT auth_option_id 518 FROM ' . ACL_OPTIONS_TABLE . ' 519 WHERE ' . $this->db->sql_in_set('auth_option', $auth_option); 520 $result = $this->db->sql_query($sql); 521 while ($row = $this->db->sql_fetchrow($result)) 522 { 523 $to_remove[] = (int) $row['auth_option_id']; 524 } 525 $this->db->sql_freeresult($result); 526 527 if (empty($to_remove)) 528 { 529 return; 530 } 531 532 $type = (string) $type; // Prevent PHP bug. 533 534 switch ($type) 535 { 536 case 'role': 537 if (!($role_id = $this->role_exists($name))) 538 { 539 throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name); 540 } 541 542 $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' 543 WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove) . ' 544 AND role_id = ' . (int) $role_id; 545 $this->db->sql_query($sql); 546 break; 547 548 case 'group': 549 $sql = 'SELECT group_id 550 FROM ' . GROUPS_TABLE . " 551 WHERE group_name = '" . $this->db->sql_escape($name) . "'"; 552 $this->db->sql_query($sql); 553 $group_id = (int) $this->db->sql_fetchfield('group_id'); 554 555 if (!$group_id) 556 { 557 throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name); 558 } 559 560 // If the group has a role set for them we will remove the requested permissions from that role. 561 $sql = 'SELECT auth_role_id 562 FROM ' . ACL_GROUPS_TABLE . ' 563 WHERE group_id = ' . $group_id . ' 564 AND auth_role_id <> 0'; 565 $this->db->sql_query($sql); 566 $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); 567 if ($role_id) 568 { 569 $sql = 'SELECT role_name 570 FROM ' . ACL_ROLES_TABLE . ' 571 WHERE role_id = ' . $role_id; 572 $this->db->sql_query($sql); 573 $role_name = $this->db->sql_fetchfield('role_name'); 574 575 return $this->permission_unset($role_name, $auth_option, 'role'); 576 } 577 578 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' 579 WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove); 580 $this->db->sql_query($sql); 581 break; 582 } 583 584 $this->auth->acl_clear_prefetch(); 585 } 586 587 /** 588 * {@inheritdoc} 589 */ 590 public function reverse() 591 { 592 $arguments = func_get_args(); 593 $original_call = array_shift($arguments); 594 595 $call = false; 596 switch ($original_call) 597 { 598 case 'add': 599 $call = 'remove'; 600 break; 601 602 case 'remove': 603 $call = 'add'; 604 break; 605 606 case 'permission_set': 607 $call = 'permission_unset'; 608 break; 609 610 case 'permission_unset': 611 $call = 'permission_set'; 612 break; 613 614 case 'role_add': 615 $call = 'role_remove'; 616 break; 617 618 case 'role_remove': 619 $call = 'role_add'; 620 break; 621 622 case 'role_update': 623 // Set to the original value if the current value is what we compared to originally 624 $arguments = array( 625 $arguments[1], 626 $arguments[0], 627 ); 628 break; 629 630 case 'reverse': 631 // Reversing a reverse is just the call itself 632 $call = array_shift($arguments); 633 break; 634 } 635 636 if ($call) 637 { 638 return call_user_func_array(array(&$this, $call), $arguments); 639 } 640 } 641 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:28:18 2020 | Cross-referenced by PHPXref 0.7.1 |