[ Index ] |
PHP Cross Reference of phpBB 3.0 Beta 3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id: auth.php,v 1.28 2006/10/14 14:56:43 acydburn Exp $ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 */ 13 if (!defined('IN_PHPBB')) 14 { 15 exit; 16 } 17 18 /** 19 * ACP Permission/Auth class 20 * @package phpBB3 21 */ 22 class auth_admin extends auth 23 { 24 var $option_ids = array(); 25 26 /** 27 * Init auth settings 28 */ 29 function auth_admin() 30 { 31 global $db, $cache; 32 33 if (($this->acl_options = $cache->get('acl_options')) === false) 34 { 35 $sql = 'SELECT auth_option, is_global, is_local 36 FROM ' . ACL_OPTIONS_TABLE . ' 37 ORDER BY auth_option_id'; 38 $result = $db->sql_query($sql); 39 40 $global = $local = 0; 41 $this->acl_options = array(); 42 while ($row = $db->sql_fetchrow($result)) 43 { 44 if ($row['is_global']) 45 { 46 $this->acl_options['global'][$row['auth_option']] = $global++; 47 } 48 49 if ($row['is_local']) 50 { 51 $this->acl_options['local'][$row['auth_option']] = $local++; 52 } 53 } 54 $db->sql_freeresult($result); 55 56 $cache->put('acl_options', $this->acl_options); 57 } 58 59 if (!sizeof($this->option_ids)) 60 { 61 $sql = 'SELECT auth_option_id, auth_option 62 FROM ' . ACL_OPTIONS_TABLE; 63 $result = $db->sql_query($sql); 64 65 $this->option_ids = array(); 66 while ($row = $db->sql_fetchrow($result)) 67 { 68 $this->option_ids[$row['auth_option']] = $row['auth_option_id']; 69 } 70 $db->sql_freeresult($result); 71 } 72 } 73 74 /** 75 * Get permission mask 76 * This function only supports getting permissions of one type (for example a_) 77 * 78 * @param set|view $mode defines the permissions we get, view gets effective permissions (checking user AND group permissions), set only gets the user or group permission set alone 79 * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least) 80 * @param mixed $group_id group ids to search for, return group related settings (a user_id or a group_id has to be specified at least) 81 * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings 82 * @param string $auth_option the auth_option defines the permission setting to look for (a_ for example) 83 * @param local|global $scope the scope defines the permission scope. If local, a forum_id is additionally required 84 * @param ACL_NEVER|ACL_NO|ACL_YES $acl_fill defines the mode those permissions not set are getting filled with 85 */ 86 function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false, $acl_fill = ACL_NEVER) 87 { 88 global $db, $user; 89 90 $hold_ary = array(); 91 $view_user_mask = ($mode == 'view' && $group_id === false) ? true : false; 92 93 if ($auth_option === false || $scope === false) 94 { 95 return array(); 96 } 97 98 $acl_user_function = ($mode == 'set') ? 'acl_user_raw_data' : 'acl_raw_data'; 99 100 if (!$view_user_mask) 101 { 102 if ($forum_id !== false) 103 { 104 $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', $forum_id) : $this->$acl_user_function($user_id, $auth_option . '%', $forum_id); 105 } 106 else 107 { 108 $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', ($scope == 'global') ? 0 : false) : $this->$acl_user_function($user_id, $auth_option . '%', ($scope == 'global') ? 0 : false); 109 } 110 } 111 112 // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups) 113 $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id); 114 $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : (($scope == 'global') ? array(0) : array()); 115 116 // Only those options we need 117 $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array('')); 118 119 // If forum_ids is false and the scope is local we actually want to have all forums within the array 120 if ($scope == 'local' && !sizeof($forum_ids)) 121 { 122 $sql = 'SELECT forum_id 123 FROM ' . FORUMS_TABLE; 124 $result = $db->sql_query($sql, 120); 125 126 while ($row = $db->sql_fetchrow($result)) 127 { 128 $forum_ids[] = $row['forum_id']; 129 } 130 $db->sql_freeresult($result); 131 } 132 133 if ($view_user_mask) 134 { 135 $auth2 = null; 136 137 $sql = 'SELECT user_id, user_permissions, user_type 138 FROM ' . USERS_TABLE . ' 139 WHERE ' . $db->sql_in_set('user_id', $ug_id); 140 $result = $db->sql_query($sql); 141 142 while ($userdata = $db->sql_fetchrow($result)) 143 { 144 if ($user->data['user_id'] != $userdata['user_id']) 145 { 146 $auth2 = new auth(); 147 $auth2->acl($userdata); 148 } 149 else 150 { 151 global $auth; 152 $auth2 = &$auth; 153 } 154 155 156 $hold_ary[$userdata['user_id']] = array(); 157 foreach ($forum_ids as $f_id) 158 { 159 $hold_ary[$userdata['user_id']][$f_id] = array(); 160 foreach ($compare_options as $option) 161 { 162 $hold_ary[$userdata['user_id']][$f_id][$option] = $auth2->acl_get($option, $f_id); 163 } 164 } 165 } 166 $db->sql_freeresult($result); 167 168 unset($userdata); 169 unset($auth2); 170 } 171 172 foreach ($ug_id as $_id) 173 { 174 if (!isset($hold_ary[$_id])) 175 { 176 $hold_ary[$_id] = array(); 177 } 178 179 foreach ($forum_ids as $f_id) 180 { 181 if (!isset($hold_ary[$_id][$f_id])) 182 { 183 $hold_ary[$_id][$f_id] = array(); 184 } 185 } 186 } 187 188 // Now, we need to fill the gaps with $acl_fill. ;) 189 190 // Now switch back to keys 191 if (sizeof($compare_options)) 192 { 193 $compare_options = array_combine($compare_options, array_fill(1, sizeof($compare_options), $acl_fill)); 194 } 195 196 // Defining the user-function here to save some memory 197 $return_acl_fill = create_function('$value', 'return ' . $acl_fill . ';'); 198 199 // Actually fill the gaps 200 if (sizeof($hold_ary)) 201 { 202 foreach ($hold_ary as $ug_id => $row) 203 { 204 foreach ($row as $id => $options) 205 { 206 // Do not include the global auth_option 207 unset($options[$auth_option]); 208 209 // Not a "fine" solution, but at all it's a 1-dimensional 210 // array_diff_key function filling the resulting array values with zeros 211 // The differences get merged into $hold_ary (all permissions having $acl_fill set) 212 $hold_ary[$ug_id][$id] = array_merge($options, 213 214 array_map($return_acl_fill, 215 array_flip( 216 array_diff( 217 array_keys($compare_options), array_keys($options) 218 ) 219 ) 220 ) 221 ); 222 } 223 } 224 } 225 else 226 { 227 $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options; 228 } 229 230 return $hold_ary; 231 } 232 233 /** 234 * Get permission mask for roles 235 * This function only supports getting masks for one role 236 */ 237 function get_role_mask($role_id) 238 { 239 global $db; 240 241 $hold_ary = array(); 242 243 // Get users having this role set... 244 $sql = 'SELECT user_id, forum_id 245 FROM ' . ACL_USERS_TABLE . ' 246 WHERE auth_role_id = ' . $role_id . ' 247 ORDER BY forum_id'; 248 $result = $db->sql_query($sql); 249 250 while ($row = $db->sql_fetchrow($result)) 251 { 252 $hold_ary[$row['forum_id']]['users'][] = $row['user_id']; 253 } 254 $db->sql_freeresult($result); 255 256 // Now grab groups... 257 $sql = 'SELECT group_id, forum_id 258 FROM ' . ACL_GROUPS_TABLE . ' 259 WHERE auth_role_id = ' . $role_id . ' 260 ORDER BY forum_id'; 261 $result = $db->sql_query($sql); 262 263 while ($row = $db->sql_fetchrow($result)) 264 { 265 $hold_ary[$row['forum_id']]['groups'][] = $row['group_id']; 266 } 267 $db->sql_freeresult($result); 268 269 return $hold_ary; 270 } 271 272 /** 273 * Display permission mask (assign to template) 274 */ 275 function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true) 276 { 277 global $template, $user, $db, $phpbb_root_path, $phpEx; 278 279 // Define names for template loops, might be able to be set 280 $tpl_pmask = 'p_mask'; 281 $tpl_fmask = 'f_mask'; 282 $tpl_category = 'category'; 283 $tpl_mask = 'mask'; 284 285 $l_acl_type = (isset($user->lang['ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type)])) ? $user->lang['ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type)] : 'ACL_TYPE_' . (($local) ? 'LOCAL' : 'GLOBAL') . '_' . strtoupper($permission_type); 286 287 // Allow trace for viewing permissions and in user mode 288 $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false; 289 290 // Get names 291 if ($user_mode == 'user') 292 { 293 $sql = 'SELECT user_id as ug_id, username as ug_name 294 FROM ' . USERS_TABLE . ' 295 WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . ' 296 ORDER BY username ASC'; 297 } 298 else 299 { 300 $sql = 'SELECT group_id as ug_id, group_name as ug_name, group_type 301 FROM ' . GROUPS_TABLE . ' 302 WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . ' 303 ORDER BY group_type DESC, group_name ASC'; 304 } 305 $result = $db->sql_query($sql); 306 307 $ug_names_ary = array(); 308 while ($row = $db->sql_fetchrow($result)) 309 { 310 $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['ug_name']] : $row['ug_name']); 311 } 312 $db->sql_freeresult($result); 313 314 // Get used forums 315 $forum_ids = array(); 316 foreach ($hold_ary as $ug_id => $row) 317 { 318 $forum_ids = array_merge($forum_ids, array_keys($row)); 319 } 320 $forum_ids = array_unique($forum_ids); 321 322 $forum_names_ary = array(); 323 if ($local) 324 { 325 $forum_names_ary = make_forum_select(false, false, true, false, false, false, true); 326 } 327 else 328 { 329 $forum_names_ary[0] = $l_acl_type; 330 } 331 332 // Get available roles 333 $sql = 'SELECT * 334 FROM ' . ACL_ROLES_TABLE . " 335 WHERE role_type = '" . $db->sql_escape($permission_type) . "' 336 ORDER BY role_order ASC"; 337 $result = $db->sql_query($sql); 338 339 $roles = array(); 340 while ($row = $db->sql_fetchrow($result)) 341 { 342 $roles[$row['role_id']] = $row; 343 } 344 $db->sql_freeresult($result); 345 346 $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary)); 347 348 // Build js roles array (role data assignments) 349 $s_role_js_array = ''; 350 351 if (sizeof($roles)) 352 { 353 $s_role_js_array = array(); 354 355 // Make sure every role (even if empty) has its array defined 356 foreach ($roles as $_role_id => $null) 357 { 358 $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n"; 359 } 360 361 $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting 362 FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o 363 WHERE o.auth_option_id = r.auth_option_id 364 AND ' . $db->sql_in_set('r.role_id', array_keys($roles)); 365 $result = $db->sql_query($sql); 366 367 while ($row = $db->sql_fetchrow($result)) 368 { 369 $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1); 370 if ($flag == $row['auth_option']) 371 { 372 continue; 373 } 374 375 $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . $row['auth_option'] . '\'] = ' . $row['auth_setting'] . '; '; 376 } 377 $db->sql_freeresult($result); 378 379 $s_role_js_array = implode('', $s_role_js_array); 380 } 381 382 $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array); 383 384 // Now obtain memberships 385 $user_groups_default = $user_groups_custom = array(); 386 if ($user_mode == 'user' && $group_display) 387 { 388 $sql = 'SELECT group_id, group_name, group_type 389 FROM ' . GROUPS_TABLE . ' 390 ORDER BY group_type DESC, group_name ASC'; 391 $result = $db->sql_query($sql); 392 393 $groups = array(); 394 while ($row = $db->sql_fetchrow($result)) 395 { 396 $groups[$row['group_id']] = $row; 397 } 398 $db->sql_freeresult($result); 399 400 $memberships = group_memberships(false, array_keys($hold_ary), false); 401 402 // User is not a member of any group? Bad admin, bad bad admin... 403 if ($memberships) 404 { 405 foreach ($memberships as $row) 406 { 407 if ($groups[$row['group_id']]['group_type'] == GROUP_SPECIAL) 408 { 409 $user_groups_default[$row['user_id']][] = $user->lang['G_' . $groups[$row['group_id']]['group_name']]; 410 } 411 else 412 { 413 $user_groups_custom[$row['user_id']][] = $groups[$row['group_id']]['group_name']; 414 } 415 } 416 } 417 unset($memberships, $groups); 418 } 419 420 // If we only have one forum id to display or being in local mode and more than one user/group to display, 421 // we switch the complete interface to group by user/usergroup instead of grouping by forum 422 // To achive this, we need to switch the array a bit 423 if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1)) 424 { 425 $hold_ary_temp = $hold_ary; 426 $hold_ary = array(); 427 foreach ($hold_ary_temp as $ug_id => $row) 428 { 429 foreach ($row as $forum_id => $auth_row) 430 { 431 $hold_ary[$forum_id][$ug_id] = $auth_row; 432 } 433 } 434 unset($hold_ary_temp); 435 436 foreach ($hold_ary as $forum_id => $forum_array) 437 { 438 $content_array = $categories = array(); 439 $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary)); 440 441 $template->assign_block_vars($tpl_pmask, array( 442 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], 443 'CATEGORIES' => implode('</th><th>', $categories), 444 445 'L_ACL_TYPE' => $l_acl_type, 446 447 'S_LOCAL' => ($local) ? true : false, 448 'S_GLOBAL' => (!$local) ? true : false, 449 'S_NUM_CATS' => sizeof($categories), 450 'S_VIEW' => ($mode == 'view') ? true : false, 451 'S_NUM_OBJECTS' => sizeof($content_array), 452 'S_USER_MODE' => ($user_mode == 'user') ? true : false, 453 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) 454 ); 455 456 foreach ($content_array as $ug_id => $ug_array) 457 { 458 // Build role dropdown options 459 $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; 460 461 $s_role_options = ''; 462 foreach ($roles as $role_id => $role_row) 463 { 464 $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); 465 $title = ($role_description) ? ' title="' . $role_description . '"' : ''; 466 $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_row['role_name'] . '</option>'; 467 } 468 469 if ($s_role_options) 470 { 471 $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; 472 } 473 474 $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( 475 'NAME' => $ug_names_ary[$ug_id], 476 'S_ROLE_OPTIONS' => $s_role_options, 477 'UG_ID' => $ug_id, 478 'FORUM_ID' => $forum_id) 479 ); 480 481 $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace); 482 } 483 } 484 } 485 else 486 { 487 foreach ($ug_names_ary as $ug_id => $ug_name) 488 { 489 if (!isset($hold_ary[$ug_id])) 490 { 491 continue; 492 } 493 494 $content_array = $categories = array(); 495 $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary)); 496 497 $template->assign_block_vars($tpl_pmask, array( 498 'NAME' => $ug_name, 499 'CATEGORIES' => implode('</th><th>', $categories), 500 501 'USER_GROUPS_DEFAULT' => ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode(', ', $user_groups_default[$ug_id]) : '', 502 'USER_GROUPS_CUSTOM' => ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode(', ', $user_groups_custom[$ug_id]) : '', 503 'L_ACL_TYPE' => $l_acl_type, 504 505 'S_LOCAL' => ($local) ? true : false, 506 'S_GLOBAL' => (!$local) ? true : false, 507 'S_NUM_CATS' => sizeof($categories), 508 'S_VIEW' => ($mode == 'view') ? true : false, 509 'S_NUM_OBJECTS' => sizeof($content_array), 510 'S_USER_MODE' => ($user_mode == 'user') ? true : false, 511 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) 512 ); 513 514 foreach ($content_array as $forum_id => $forum_array) 515 { 516 // Build role dropdown options 517 $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; 518 519 $s_role_options = ''; 520 foreach ($roles as $role_id => $role_row) 521 { 522 $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); 523 $title = ($role_description) ? ' title="' . $role_description . '"' : ''; 524 $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_row['role_name'] . '</option>'; 525 } 526 527 if ($s_role_options) 528 { 529 $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; 530 } 531 532 if (!$forum_id) 533 { 534 $folder_image = ''; 535 } 536 else 537 { 538 if ($forum_names_ary[$forum_id]['forum_status'] == ITEM_LOCKED) 539 { 540 $folder_image = '<img src="images/icon_folder_lock_small.gif" width="19" height="18" alt="' . $user->lang['FORUM_LOCKED'] . '" />'; 541 } 542 else 543 { 544 switch ($forum_names_ary[$forum_id]['forum_type']) 545 { 546 case FORUM_LINK: 547 $folder_image = '<img src="images/icon_folder_link_small.gif" width="22" height="18" alt="' . $user->lang['FORUM_LINK'] . '" />'; 548 break; 549 550 default: 551 $folder_image = ($forum_names_ary[$forum_id]['left_id'] + 1 != $forum_names_ary[$forum_id]['right_id']) ? '<img src="images/icon_folder_sub_small.gif" width="22" height="18" alt="' . $user->lang['SUBFORUM'] . '" />' : '<img src="images/icon_folder_small.gif" width="19" height="18" alt="' . $user->lang['FOLDER'] . '" />'; 552 break; 553 } 554 } 555 } 556 557 $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( 558 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], 559 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'], 560 'FOLDER_IMAGE' => $folder_image, 561 'S_ROLE_OPTIONS' => $s_role_options, 562 'UG_ID' => $ug_id, 563 'FORUM_ID' => $forum_id) 564 ); 565 566 $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, $show_trace); 567 } 568 } 569 } 570 } 571 572 /** 573 * Display permission mask for roles 574 */ 575 function display_role_mask(&$hold_ary) 576 { 577 global $db, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx; 578 579 if (!sizeof($hold_ary)) 580 { 581 return; 582 } 583 584 // Get forum names 585 $sql = 'SELECT forum_id, forum_name 586 FROM ' . FORUMS_TABLE . ' 587 WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)); 588 $result = $db->sql_query($sql); 589 590 $forum_names = array(); 591 while ($row = $db->sql_fetchrow($result)) 592 { 593 $forum_names[$row['forum_id']] = $row['forum_name']; 594 } 595 $db->sql_freeresult($result); 596 597 foreach ($hold_ary as $forum_id => $auth_ary) 598 { 599 $template->assign_block_vars('role_mask', array( 600 'NAME' => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_names[$forum_id], 601 'FORUM_ID' => $forum_id) 602 ); 603 604 if (isset($auth_ary['users']) && sizeof($auth_ary['users'])) 605 { 606 $sql = 'SELECT user_id, username 607 FROM ' . USERS_TABLE . ' 608 WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . ' 609 ORDER BY username'; 610 $result = $db->sql_query($sql); 611 612 while ($row = $db->sql_fetchrow($result)) 613 { 614 $template->assign_block_vars('role_mask.users', array( 615 'USER_ID' => $row['user_id'], 616 'USERNAME' => $row['username'], 617 'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u={$row['user_id']}")) 618 ); 619 } 620 $db->sql_freeresult($result); 621 } 622 623 if (isset($auth_ary['groups']) && sizeof($auth_ary['groups'])) 624 { 625 $sql = 'SELECT group_id, group_name, group_type 626 FROM ' . GROUPS_TABLE . ' 627 WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . ' 628 ORDER BY group_type ASC, group_name'; 629 $result = $db->sql_query($sql); 630 631 while ($row = $db->sql_fetchrow($result)) 632 { 633 $template->assign_block_vars('role_mask.groups', array( 634 'GROUP_ID' => $row['group_id'], 635 'GROUP_NAME' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'], 636 'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&g={$row['group_id']}")) 637 ); 638 } 639 $db->sql_freeresult($result); 640 } 641 } 642 } 643 644 /** 645 * NOTE: this function is not in use atm 646 * Add a new option to the list ... $options is a hash of form -> 647 * $options = array( 648 * 'local' => array('option1', 'option2', ...), 649 * 'global' => array('optionA', 'optionB', ...) 650 * ); 651 */ 652 function acl_add_option($options) 653 { 654 global $db, $cache; 655 656 if (!is_array($options)) 657 { 658 return false; 659 } 660 661 $cur_options = array(); 662 663 $sql = 'SELECT auth_option, is_global, is_local 664 FROM ' . ACL_OPTIONS_TABLE . ' 665 ORDER BY auth_option_id'; 666 $result = $db->sql_query($sql); 667 668 while ($row = $db->sql_fetchrow($result)) 669 { 670 if ($row['is_global']) 671 { 672 $cur_options['global'][] = $row['auth_option']; 673 } 674 675 if ($row['is_local']) 676 { 677 $cur_options['local'][] = $row['auth_option']; 678 } 679 } 680 $db->sql_freeresult($result); 681 682 // Here we need to insert new options ... this requires discovering whether 683 // an options is global, local or both and whether we need to add an permission 684 // set flag (x_) 685 $new_options = array('local' => array(), 'global' => array()); 686 687 foreach ($options as $type => $option_ary) 688 { 689 $option_ary = array_unique($option_ary); 690 691 foreach ($option_ary as $option_value) 692 { 693 if (!in_array($option_value, $cur_options[$type])) 694 { 695 $new_options[$type][] = $option_value; 696 } 697 698 $flag = substr($option_value, 0, strpos($option_value, '_') + 1); 699 700 if (!in_array($flag, $cur_options[$type]) && !in_array($flag, $new_options[$type])) 701 { 702 $new_options[$type][] = $flag; 703 } 704 } 705 } 706 unset($options); 707 708 $options = array(); 709 $options['local'] = array_diff($new_options['local'], $new_options['global']); 710 $options['global'] = array_diff($new_options['global'], $new_options['local']); 711 $options['local_global'] = array_intersect($new_options['local'], $new_options['global']); 712 713 $sql_ary = array(); 714 715 foreach ($options as $type => $option_ary) 716 { 717 foreach ($option_ary as $option) 718 { 719 $sql_ary[] = array( 720 'auth_option' => $option, 721 'is_global' => ($type == 'global' || $type == 'local_global') ? 1 : 0, 722 'is_local' => ($type == 'local' || $type == 'local_global') ? 1 : 0 723 ); 724 } 725 } 726 727 $db->sql_multi_insert(ACL_OPTIONS_TABLE, $sql_ary); 728 729 $cache->destroy('acl_options'); 730 $this->acl_clear_prefetch(); 731 732 return true; 733 } 734 735 /** 736 * Set a user or group ACL record 737 */ 738 function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true) 739 { 740 global $db; 741 742 // One or more forums 743 if (!is_array($forum_id)) 744 { 745 $forum_id = array($forum_id); 746 } 747 748 // One or more users 749 if (!is_array($ug_id)) 750 { 751 $ug_id = array($ug_id); 752 } 753 754 $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id)); 755 $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id)); 756 757 // Instead of updating, inserting, removing we just remove all current settings and re-set everything... 758 $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; 759 $id_field = $ug_type . '_id'; 760 761 // Get any flags as required 762 reset($auth); 763 $flag = key($auth); 764 $flag = substr($flag, 0, strpos($flag, '_') + 1); 765 766 // This ID (the any-flag) is set if one or more permissions are true... 767 $any_option_id = (int) $this->option_ids[$flag]; 768 769 // Remove any-flag from auth ary 770 if (isset($auth[$flag])) 771 { 772 unset($auth[$flag]); 773 } 774 775 // Remove current auth options... 776 $auth_option_ids = array(); 777 foreach ($auth as $auth_option => $auth_setting) 778 { 779 $auth_option_ids[] = (int) $this->option_ids[$auth_option]; 780 } 781 782 $sql = "DELETE FROM $table 783 WHERE $forum_sql 784 AND $ug_id_sql 785 AND auth_option_id IN ($any_option_id, " . implode(', ', $auth_option_ids) . ')'; 786 $db->sql_query($sql); 787 788 // Remove those having a role assigned... the correct type of course... 789 $sql = 'SELECT role_id 790 FROM ' . ACL_ROLES_TABLE . " 791 WHERE role_type = '" . $db->sql_escape($flag) . "'"; 792 $result = $db->sql_query($sql); 793 794 $role_ids = array(); 795 while ($row = $db->sql_fetchrow($result)) 796 { 797 $role_ids[] = $row['role_id']; 798 } 799 $db->sql_freeresult($result); 800 801 if (sizeof($role_ids)) 802 { 803 $sql = "DELETE FROM $table 804 WHERE $forum_sql 805 AND $ug_id_sql 806 AND auth_option_id = 0 807 AND " . $db->sql_in_set('auth_role_id', $role_ids); 808 $db->sql_query($sql); 809 } 810 811 // Ok, include the any-flag if one or more auth options are set to yes... 812 foreach ($auth as $auth_option => $setting) 813 { 814 if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) 815 { 816 $auth[$flag] = ACL_YES; 817 } 818 } 819 820 $sql_ary = array(); 821 foreach ($forum_id as $forum) 822 { 823 $forum = (int) $forum; 824 825 if ($role_id) 826 { 827 foreach ($ug_id as $id) 828 { 829 $sql_ary[] = array( 830 $id_field => (int) $id, 831 'forum_id' => (int) $forum, 832 'auth_option_id' => 0, 833 'auth_setting' => 0, 834 'auth_role_id' => $role_id 835 ); 836 } 837 } 838 else 839 { 840 foreach ($auth as $auth_option => $setting) 841 { 842 $auth_option_id = (int) $this->option_ids[$auth_option]; 843 844 if ($setting != ACL_NO) 845 { 846 foreach ($ug_id as $id) 847 { 848 $sql_ary[] = array( 849 $id_field => (int) $id, 850 'forum_id' => (int) $forum, 851 'auth_option_id' => (int) $auth_option_id, 852 'auth_setting' => (int) $setting 853 ); 854 } 855 } 856 } 857 } 858 } 859 860 $db->sql_multi_insert($table, $sql_ary); 861 862 if ($clear_prefetch) 863 { 864 $this->acl_clear_prefetch(); 865 } 866 } 867 868 /** 869 * Set a role-specific ACL record 870 */ 871 function acl_set_role($role_id, $auth) 872 { 873 global $db; 874 875 // Get any-flag as required 876 reset($auth); 877 $flag = key($auth); 878 $flag = substr($flag, 0, strpos($flag, '_') + 1); 879 880 // Remove any-flag from auth ary 881 if (isset($auth[$flag])) 882 { 883 unset($auth[$flag]); 884 } 885 886 // Re-set any flag... 887 foreach ($auth as $auth_option => $setting) 888 { 889 if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) 890 { 891 $auth[$flag] = ACL_YES; 892 } 893 } 894 895 $sql_ary = array(); 896 foreach ($auth as $auth_option => $setting) 897 { 898 $auth_option_id = (int) $this->option_ids[$auth_option]; 899 900 if ($setting != ACL_NO) 901 { 902 $sql_ary[] = array( 903 'role_id' => (int) $role_id, 904 'auth_option_id' => (int) $auth_option_id, 905 'auth_setting' => (int) $setting 906 ); 907 } 908 } 909 910 // If no data is there, we set the any-flag to ACL_NEVER... 911 if (!sizeof($sql_ary)) 912 { 913 $sql_ary[] = array( 914 'role_id' => (int) $role_id, 915 'auth_option_id' => $this->option_ids[$flag], 916 'auth_setting' => ACL_NEVER 917 ); 918 } 919 920 // Remove current auth options... 921 $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' 922 WHERE role_id = ' . $role_id; 923 $db->sql_query($sql); 924 925 // Now insert the new values 926 $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); 927 928 $this->acl_clear_prefetch(); 929 } 930 931 /** 932 * Remove local permission 933 */ 934 function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false) 935 { 936 global $db; 937 938 if ($ug_id === false && $forum_id === false) 939 { 940 return; 941 } 942 943 $option_id_ary = array(); 944 $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; 945 $id_field = $mode . '_id'; 946 947 $where_sql = array(); 948 949 if ($forum_id !== false) 950 { 951 $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id)); 952 } 953 954 if ($ug_id !== false) 955 { 956 $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id)); 957 } 958 959 // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly 960 if ($permission_type !== false) 961 { 962 // Get permission type 963 $sql = 'SELECT auth_option, auth_option_id 964 FROM ' . ACL_OPTIONS_TABLE . " 965 WHERE auth_option LIKE '" . $db->sql_escape(str_replace('_', "\_", $permission_type)) . "%'"; 966 $sql .= ($db->sql_layer == 'mssql' || $db->sql_layer == 'mssql_odbc') ? " ESCAPE '\\'" : ''; 967 968 $result = $db->sql_query($sql); 969 970 $auth_id_ary = array(); 971 while ($row = $db->sql_fetchrow($result)) 972 { 973 $option_id_ary[] = $row['auth_option_id']; 974 $auth_id_ary[$row['auth_option']] = ACL_NO; 975 } 976 $db->sql_freeresult($result); 977 978 // First of all, lets grab the items having roles with the specified auth options assigned 979 $sql = "SELECT auth_role_id, $id_field, forum_id 980 FROM $table, " . ACL_ROLES_TABLE . " r 981 WHERE auth_role_id <> 0 982 AND auth_role_id = r.role_id 983 AND r.role_type = '{$permission_type}' 984 AND " . implode(' AND ', $where_sql) . ' 985 ORDER BY auth_role_id'; 986 $result = $db->sql_query($sql); 987 988 $cur_role_auth = array(); 989 while ($row = $db->sql_fetchrow($result)) 990 { 991 $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field]; 992 } 993 $db->sql_freeresult($result); 994 995 // Get role data for resetting data 996 if (sizeof($cur_role_auth)) 997 { 998 $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting 999 FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd 1000 WHERE ao.auth_option_id = rd.auth_option_id 1001 AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth)); 1002 $result = $db->sql_query($sql); 1003 1004 $auth_settings = array(); 1005 while ($row = $db->sql_fetchrow($result)) 1006 { 1007 // We need to fill all auth_options, else setting it will fail... 1008 if (!isset($auth_settings[$row['role_id']])) 1009 { 1010 $auth_settings[$row['role_id']] = $auth_id_ary; 1011 } 1012 $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting']; 1013 } 1014 $db->sql_freeresult($result); 1015 1016 // Set the options 1017 foreach ($cur_role_auth as $role_id => $auth_row) 1018 { 1019 foreach ($auth_row as $f_id => $ug_row) 1020 { 1021 $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false); 1022 } 1023 } 1024 } 1025 } 1026 1027 // Now, normally remove permissions... 1028 if ($permission_type !== false) 1029 { 1030 $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary)); 1031 } 1032 1033 $sql = "DELETE FROM $table 1034 WHERE " . implode(' AND ', $where_sql); 1035 $db->sql_query($sql); 1036 1037 $this->acl_clear_prefetch(); 1038 } 1039 1040 /** 1041 * Assign category to template 1042 * used by display_mask() 1043 */ 1044 function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $show_trace = false) 1045 { 1046 global $template, $user, $phpbb_admin_path, $phpEx; 1047 1048 foreach ($category_array as $cat => $cat_array) 1049 { 1050 $template->assign_block_vars($tpl_cat, array( 1051 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false, 1052 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false, 1053 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false, 1054 1055 'CAT_NAME' => $user->lang['permission_cat'][$cat]) 1056 ); 1057 1058 foreach ($cat_array['permissions'] as $permission => $allowed) 1059 { 1060 $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array( 1061 'S_YES' => ($allowed == ACL_YES) ? true : false, 1062 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, 1063 'S_NO' => ($allowed == ACL_NO) ? true : false, 1064 1065 'UG_ID' => $ug_id, 1066 'FORUM_ID' => $forum_id, 1067 'FIELD_NAME' => $permission, 1068 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']', 1069 1070 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission") : '', 1071 1072 'PERMISSION' => $user->lang['acl_' . $permission]['lang']) 1073 ); 1074 } 1075 } 1076 } 1077 1078 /** 1079 * Building content array from permission rows with explicit key ordering 1080 * used by display_mask() 1081 */ 1082 function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array) 1083 { 1084 global $user; 1085 1086 foreach ($key_sort_array as $forum_id) 1087 { 1088 if (!isset($permission_row[$forum_id])) 1089 { 1090 continue; 1091 } 1092 1093 $permissions = $permission_row[$forum_id]; 1094 ksort($permissions); 1095 1096 foreach ($permissions as $permission => $auth_setting) 1097 { 1098 if (!isset($user->lang['acl_' . $permission])) 1099 { 1100 $user->lang['acl_' . $permission] = array( 1101 'cat' => 'misc', 1102 'lang' => '{ acl_' . $permission . ' }' 1103 ); 1104 } 1105 1106 $cat = $user->lang['acl_' . $permission]['cat']; 1107 1108 // Build our categories array 1109 if (!isset($categories[$cat])) 1110 { 1111 $categories[$cat] = $user->lang['permission_cat'][$cat]; 1112 } 1113 1114 // Build our content array 1115 if (!isset($content_array[$forum_id])) 1116 { 1117 $content_array[$forum_id] = array(); 1118 } 1119 1120 if (!isset($content_array[$forum_id][$cat])) 1121 { 1122 $content_array[$forum_id][$cat] = array( 1123 'S_YES' => false, 1124 'S_NEVER' => false, 1125 'S_NO' => false, 1126 'permissions' => array(), 1127 ); 1128 } 1129 1130 $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false; 1131 $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false; 1132 $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false; 1133 1134 $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting; 1135 } 1136 } 1137 } 1138 1139 /** 1140 * Use permissions from another user. This transferes a permission set from one user to another. 1141 * The other user is always able to revert back to his permission set. 1142 * This function does not check for lower/higher permissions, it is possible for the user to gain 1143 * "more" permissions by this. 1144 * Admin permissions will not be copied. 1145 */ 1146 function ghost_permissions($from_user_id, $to_user_id) 1147 { 1148 global $db; 1149 1150 if ($to_user_id == ANONYMOUS) 1151 { 1152 return false; 1153 } 1154 1155 $hold_ary = $this->acl_raw_data($from_user_id, false, false); 1156 1157 if (isset($hold_ary[$from_user_id])) 1158 { 1159 $hold_ary = $hold_ary[$from_user_id]; 1160 } 1161 1162 // Key 0 in $hold_ary are global options, all others are forum_ids 1163 1164 // We disallow copying admin permissions 1165 foreach ($this->acl_options['global'] as $opt => $id) 1166 { 1167 if (strpos($opt, 'a_') === 0) 1168 { 1169 $hold_ary[0][$opt] = ACL_NEVER; 1170 } 1171 } 1172 1173 // Force a_switchperm to be allowed 1174 $hold_ary[0]['a_switchperm'] = ACL_YES; 1175 1176 $user_permissions = $this->build_bitstring($hold_ary); 1177 1178 if (!$user_permissions) 1179 { 1180 return false; 1181 } 1182 1183 $sql = 'UPDATE ' . USERS_TABLE . " 1184 SET user_permissions = '" . $db->sql_escape($user_permissions) . "', 1185 user_perm_from = $from_user_id 1186 WHERE user_id = " . $to_user_id; 1187 $db->sql_query($sql); 1188 1189 return true; 1190 } 1191 } 1192 1193 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 22 00:35:05 2006 | Cross-referenced by PHPXref 0.6 |