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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
permission.php
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