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