Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

permission.php

Zuletzt modifiziert: 09.10.2024, 12:55 - Dateigröße: 16.25 KiB


 001  <?php
 002  /**
 003  *
 004  * This file is part of the phpBB Forum Software package.
 005  *
 006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 007  * @license GNU General Public License, version 2 (GPL-2.0)
 008  *
 009  * For full copyright and license information, please see
 010  * the docs/CREDITS.txt file.
 011  *
 012  */
 013   
 014  namespace phpbb\db\migration\tool;
 015   
 016  /**
 017  * Migration permission management tool
 018  */
 019  class permission implements \phpbb\db\migration\tool\tool_interface
 020  {
 021      /** @var \phpbb\auth\auth */
 022      protected $auth;
 023   
 024      /** @var \phpbb\cache\service */
 025      protected $cache;
 026   
 027      /** @var \phpbb\db\driver\driver_interface */
 028      protected $db;
 029   
 030      /** @var string */
 031      protected $phpbb_root_path;
 032   
 033      /** @var string */
 034      protected $php_ext;
 035   
 036      /**
 037      * Constructor
 038      *
 039      * @param \phpbb\db\driver\driver_interface $db
 040      * @param \phpbb\cache\service $cache
 041      * @param \phpbb\auth\auth $auth
 042      * @param string $phpbb_root_path
 043      * @param string $php_ext
 044      */
 045      public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext)
 046      {
 047          $this->db = $db;
 048          $this->cache = $cache;
 049          $this->auth = $auth;
 050          $this->phpbb_root_path = $phpbb_root_path;
 051          $this->php_ext = $php_ext;
 052      }
 053   
 054      /**
 055      * {@inheritdoc}
 056      */
 057      public function get_name()
 058      {
 059          return 'permission';
 060      }
 061   
 062      /**
 063      * Permission Exists
 064      *
 065      * Check if a permission (auth) setting exists
 066      *
 067      * @param string $auth_option The name of the permission (auth) option
 068      * @param bool $global True for checking a global permission setting,
 069      *     False for a local permission setting
 070      * @return bool true if it exists, false if not
 071      */
 072      public function exists($auth_option, $global = true)
 073      {
 074          if ($global)
 075          {
 076              $type_sql = ' AND is_global = 1';
 077          }
 078          else
 079          {
 080              $type_sql = ' AND is_local = 1';
 081          }
 082   
 083          $sql = 'SELECT auth_option_id
 084              FROM ' . ACL_OPTIONS_TABLE . "
 085              WHERE auth_option = '" . $this->db->sql_escape($auth_option) . "'"
 086                  . $type_sql;
 087          $result = $this->db->sql_query($sql);
 088   
 089          $row = $this->db->sql_fetchrow($result);
 090          $this->db->sql_freeresult($result);
 091   
 092          if ($row)
 093          {
 094              return true;
 095          }
 096   
 097          return false;
 098      }
 099   
 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 (sizeof($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  }
 653