[ Index ]

PHP Cross Reference of phpBB-3.2.8-deutsch

title

Body

[close]

/phpbb/db/migration/tool/ -> permission.php (source)

   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      * Add a new permission role
 245      *
 246      * @param string $role_name The new role name
 247      * @param string $role_type The type (u_, m_, a_)
 248      * @param string $role_description Description of the new role
 249      *
 250      * @return null
 251      */
 252  	public function role_add($role_name, $role_type, $role_description = '')
 253      {
 254          $sql = 'SELECT role_id
 255              FROM ' . ACL_ROLES_TABLE . "
 256              WHERE role_name = '" . $this->db->sql_escape($role_name) . "'";
 257          $this->db->sql_query($sql);
 258          $role_id = (int) $this->db->sql_fetchfield('role_id');
 259  
 260          if ($role_id)
 261          {
 262              return;
 263          }
 264  
 265          $sql = 'SELECT MAX(role_order) AS max_role_order
 266              FROM ' . ACL_ROLES_TABLE . "
 267              WHERE role_type = '" . $this->db->sql_escape($role_type) . "'";
 268          $this->db->sql_query($sql);
 269          $role_order = (int) $this->db->sql_fetchfield('max_role_order');
 270          $role_order = (!$role_order) ? 1 : $role_order + 1;
 271  
 272          $sql_ary = array(
 273              'role_name'            => $role_name,
 274              'role_description'    => $role_description,
 275              'role_type'            => $role_type,
 276              'role_order'        => $role_order,
 277          );
 278  
 279          $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary);
 280          $this->db->sql_query($sql);
 281      }
 282  
 283      /**
 284      * Update the name on a permission role
 285      *
 286      * @param string $old_role_name The old role name
 287      * @param string $new_role_name The new role name
 288      * @return null
 289      * @throws \phpbb\db\migration\exception
 290      */
 291  	public function role_update($old_role_name, $new_role_name)
 292      {
 293          $sql = 'SELECT role_id
 294              FROM ' . ACL_ROLES_TABLE . "
 295              WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'";
 296          $this->db->sql_query($sql);
 297          $role_id = (int) $this->db->sql_fetchfield('role_id');
 298  
 299          if (!$role_id)
 300          {
 301              throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $old_role_name);
 302          }
 303  
 304          $sql = 'UPDATE ' . ACL_ROLES_TABLE . "
 305              SET role_name = '" . $this->db->sql_escape($new_role_name) . "'
 306              WHERE role_name = '" . $this->db->sql_escape($old_role_name) . "'";
 307          $this->db->sql_query($sql);
 308      }
 309  
 310      /**
 311      * Remove a permission role
 312      *
 313      * @param string $role_name The role name to remove
 314      * @return null
 315      */
 316  	public function role_remove($role_name)
 317      {
 318          $sql = 'SELECT role_id
 319              FROM ' . ACL_ROLES_TABLE . "
 320              WHERE role_name = '" . $this->db->sql_escape($role_name) . "'";
 321          $this->db->sql_query($sql);
 322          $role_id = (int) $this->db->sql_fetchfield('role_id');
 323  
 324          if (!$role_id)
 325          {
 326              return;
 327          }
 328  
 329          $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
 330              WHERE role_id = ' . $role_id;
 331          $this->db->sql_query($sql);
 332  
 333          $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . '
 334              WHERE role_id = ' . $role_id;
 335          $this->db->sql_query($sql);
 336  
 337          $this->auth->acl_clear_prefetch();
 338      }
 339  
 340      /**
 341      * Permission Set
 342      *
 343      * Allows you to set permissions for a certain group/role
 344      *
 345      * @param string $name The name of the role/group
 346      * @param string|array $auth_option The auth_option or array of
 347      *     auth_options you would like to set
 348      * @param string $type The type (role|group)
 349      * @param bool $has_permission True if you want to give them permission,
 350      *     false if you want to deny them permission
 351      * @return null
 352      * @throws \phpbb\db\migration\exception
 353      */
 354  	public function permission_set($name, $auth_option, $type = 'role', $has_permission = true)
 355      {
 356          if (!is_array($auth_option))
 357          {
 358              $auth_option = array($auth_option);
 359          }
 360  
 361          $new_auth = array();
 362          $sql = 'SELECT auth_option_id
 363              FROM ' . ACL_OPTIONS_TABLE . '
 364              WHERE ' . $this->db->sql_in_set('auth_option', $auth_option);
 365          $result = $this->db->sql_query($sql);
 366          while ($row = $this->db->sql_fetchrow($result))
 367          {
 368              $new_auth[] = (int) $row['auth_option_id'];
 369          }
 370          $this->db->sql_freeresult($result);
 371  
 372          if (empty($new_auth))
 373          {
 374              return;
 375          }
 376  
 377          $current_auth = array();
 378  
 379          $type = (string) $type; // Prevent PHP bug.
 380  
 381          switch ($type)
 382          {
 383              case 'role':
 384                  $sql = 'SELECT role_id
 385                      FROM ' . ACL_ROLES_TABLE . "
 386                      WHERE role_name = '" . $this->db->sql_escape($name) . "'";
 387                  $this->db->sql_query($sql);
 388                  $role_id = (int) $this->db->sql_fetchfield('role_id');
 389  
 390                  if (!$role_id)
 391                  {
 392                      throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name);
 393                  }
 394  
 395                  $sql = 'SELECT auth_option_id, auth_setting
 396                      FROM ' . ACL_ROLES_DATA_TABLE . '
 397                      WHERE role_id = ' . $role_id;
 398                  $result = $this->db->sql_query($sql);
 399                  while ($row = $this->db->sql_fetchrow($result))
 400                  {
 401                      $current_auth[$row['auth_option_id']] = $row['auth_setting'];
 402                  }
 403                  $this->db->sql_freeresult($result);
 404              break;
 405  
 406              case 'group':
 407                  $sql = 'SELECT group_id
 408                      FROM ' . GROUPS_TABLE . "
 409                      WHERE group_name = '" . $this->db->sql_escape($name) . "'";
 410                  $this->db->sql_query($sql);
 411                  $group_id = (int) $this->db->sql_fetchfield('group_id');
 412  
 413                  if (!$group_id)
 414                  {
 415                      throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name);
 416                  }
 417  
 418                  // If the group has a role set for them we will add the requested permissions to that role.
 419                  $sql = 'SELECT auth_role_id
 420                      FROM ' . ACL_GROUPS_TABLE . '
 421                      WHERE group_id = ' . $group_id . '
 422                          AND auth_role_id <> 0
 423                          AND forum_id = 0';
 424                  $this->db->sql_query($sql);
 425                  $role_id = (int) $this->db->sql_fetchfield('auth_role_id');
 426                  if ($role_id)
 427                  {
 428                      $sql = 'SELECT role_name, role_type
 429                          FROM ' . ACL_ROLES_TABLE . '
 430                          WHERE role_id = ' . $role_id;
 431                      $this->db->sql_query($sql);
 432                      $role_data = $this->db->sql_fetchrow();
 433                      $role_name = $role_data['role_name'];
 434                      $role_type = $role_data['role_type'];
 435  
 436                      // Filter new auth options to match the role type: a_ | f_ | m_ | u_
 437                      // Set new auth options to the role only if options matching the role type were found
 438                      $auth_option = array_filter($auth_option,
 439                          function ($option) use ($role_type)
 440                          {
 441                              return strpos($option, $role_type) === 0;
 442                          }
 443                      );
 444  
 445                      if (count($auth_option))
 446                      {
 447                          return $this->permission_set($role_name, $auth_option, 'role', $has_permission);
 448                      }
 449                  }
 450  
 451                  $sql = 'SELECT auth_option_id, auth_setting
 452                      FROM ' . ACL_GROUPS_TABLE . '
 453                      WHERE group_id = ' . $group_id;
 454                  $result = $this->db->sql_query($sql);
 455                  while ($row = $this->db->sql_fetchrow($result))
 456                  {
 457                      $current_auth[$row['auth_option_id']] = $row['auth_setting'];
 458                  }
 459                  $this->db->sql_freeresult($result);
 460              break;
 461          }
 462  
 463          $sql_ary = array();
 464          switch ($type)
 465          {
 466              case 'role':
 467                  foreach ($new_auth as $auth_option_id)
 468                  {
 469                      if (!isset($current_auth[$auth_option_id]))
 470                      {
 471                          $sql_ary[] = array(
 472                              'role_id'            => $role_id,
 473                              'auth_option_id'    => $auth_option_id,
 474                              'auth_setting'        => $has_permission,
 475                          );
 476                      }
 477                  }
 478  
 479                  $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);
 480              break;
 481  
 482              case 'group':
 483                  foreach ($new_auth as $auth_option_id)
 484                  {
 485                      if (!isset($current_auth[$auth_option_id]))
 486                      {
 487                          $sql_ary[] = array(
 488                              'group_id'            => $group_id,
 489                              'auth_option_id'    => $auth_option_id,
 490                              'auth_setting'        => $has_permission,
 491                          );
 492                      }
 493                  }
 494  
 495                  $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary);
 496              break;
 497          }
 498  
 499          $this->auth->acl_clear_prefetch();
 500      }
 501  
 502      /**
 503      * Permission Unset
 504      *
 505      * Allows you to unset (remove) permissions for a certain group/role
 506      *
 507      * @param string $name The name of the role/group
 508      * @param string|array $auth_option The auth_option or array of
 509      *     auth_options you would like to set
 510      * @param string $type The type (role|group)
 511      * @return null
 512      * @throws \phpbb\db\migration\exception
 513      */
 514  	public function permission_unset($name, $auth_option, $type = 'role')
 515      {
 516          if (!is_array($auth_option))
 517          {
 518              $auth_option = array($auth_option);
 519          }
 520  
 521          $to_remove = array();
 522          $sql = 'SELECT auth_option_id
 523              FROM ' . ACL_OPTIONS_TABLE . '
 524              WHERE ' . $this->db->sql_in_set('auth_option', $auth_option);
 525          $result = $this->db->sql_query($sql);
 526          while ($row = $this->db->sql_fetchrow($result))
 527          {
 528              $to_remove[] = (int) $row['auth_option_id'];
 529          }
 530          $this->db->sql_freeresult($result);
 531  
 532          if (empty($to_remove))
 533          {
 534              return;
 535          }
 536  
 537          $type = (string) $type; // Prevent PHP bug.
 538  
 539          switch ($type)
 540          {
 541              case 'role':
 542                  $sql = 'SELECT role_id
 543                      FROM ' . ACL_ROLES_TABLE . "
 544                      WHERE role_name = '" . $this->db->sql_escape($name) . "'";
 545                  $this->db->sql_query($sql);
 546                  $role_id = (int) $this->db->sql_fetchfield('role_id');
 547  
 548                  if (!$role_id)
 549                  {
 550                      throw new \phpbb\db\migration\exception('ROLE_NOT_EXIST', $name);
 551                  }
 552  
 553                  $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
 554                      WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove) . '
 555                          AND role_id = ' . (int) $role_id;
 556                  $this->db->sql_query($sql);
 557              break;
 558  
 559              case 'group':
 560                  $sql = 'SELECT group_id
 561                      FROM ' . GROUPS_TABLE . "
 562                      WHERE group_name = '" . $this->db->sql_escape($name) . "'";
 563                  $this->db->sql_query($sql);
 564                  $group_id = (int) $this->db->sql_fetchfield('group_id');
 565  
 566                  if (!$group_id)
 567                  {
 568                      throw new \phpbb\db\migration\exception('GROUP_NOT_EXIST', $name);
 569                  }
 570  
 571                  // If the group has a role set for them we will remove the requested permissions from that role.
 572                  $sql = 'SELECT auth_role_id
 573                      FROM ' . ACL_GROUPS_TABLE . '
 574                      WHERE group_id = ' . $group_id . '
 575                          AND auth_role_id <> 0';
 576                  $this->db->sql_query($sql);
 577                  $role_id = (int) $this->db->sql_fetchfield('auth_role_id');
 578                  if ($role_id)
 579                  {
 580                      $sql = 'SELECT role_name
 581                          FROM ' . ACL_ROLES_TABLE . '
 582                          WHERE role_id = ' . $role_id;
 583                      $this->db->sql_query($sql);
 584                      $role_name = $this->db->sql_fetchfield('role_name');
 585  
 586                      return $this->permission_unset($role_name, $auth_option, 'role');
 587                  }
 588  
 589                  $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . '
 590                      WHERE ' . $this->db->sql_in_set('auth_option_id', $to_remove);
 591                  $this->db->sql_query($sql);
 592              break;
 593          }
 594  
 595          $this->auth->acl_clear_prefetch();
 596      }
 597  
 598      /**
 599      * {@inheritdoc}
 600      */
 601  	public function reverse()
 602      {
 603          $arguments = func_get_args();
 604          $original_call = array_shift($arguments);
 605  
 606          $call = false;
 607          switch ($original_call)
 608          {
 609              case 'add':
 610                  $call = 'remove';
 611              break;
 612  
 613              case 'remove':
 614                  $call = 'add';
 615              break;
 616  
 617              case 'permission_set':
 618                  $call = 'permission_unset';
 619              break;
 620  
 621              case 'permission_unset':
 622                  $call = 'permission_set';
 623              break;
 624  
 625              case 'role_add':
 626                  $call = 'role_remove';
 627              break;
 628  
 629              case 'role_remove':
 630                  $call = 'role_add';
 631              break;
 632  
 633              case 'role_update':
 634                  // Set to the original value if the current value is what we compared to originally
 635                  $arguments = array(
 636                      $arguments[1],
 637                      $arguments[0],
 638                  );
 639              break;
 640  
 641              case 'reverse':
 642                  // Reversing a reverse is just the call itself
 643                  $call = array_shift($arguments);
 644              break;
 645          }
 646  
 647          if ($call)
 648          {
 649              return call_user_func_array(array(&$this, $call), $arguments);
 650          }
 651      }
 652  }


Generated: Tue Apr 7 19:42:26 2020 Cross-referenced by PHPXref 0.7.1