* Invision Power Services * IP.Board v3.4.9 * Permissions management * Last Updated: $Date: 2012-12-21 13:31:16 -0500 (Fri, 21 Dec 2012) $ * * * @author $Author: AndyMillne $ * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://www.invisionpower.com/company/standards.php#license * @package IP.Board * @subpackage Members * @link http://www.invisionpower.com * @version $Revision: 11748 $ */ if ( ! defined( 'IN_ACP' ) ) { print "

Incorrect access

You cannot access this file directly. If you have recently upgraded, make sure you upgraded 'admin.php'."; exit(); } class admin_members_groups_permissions extends ipsCommand { /** * Skin object * * @var object Skin templates */ protected $html; /** * Shortcut for url * * @var string URL shortcut */ protected $form_code; /** * Shortcut for url (javascript) * * @var string JS URL shortcut */ protected $form_code_js; /** * Main class entry point * * @param object ipsRegistry reference * @return @e void [Outputs to screen] */ public function doExecute( ipsRegistry $registry ) { /* Load Skin and Lang */ $this->html = $this->registry->output->loadTemplate('cp_skin_permissions'); $this->registry->class_localization->loadLanguageFile( array( 'admin_permissions' ) ); /* URL Bits */ $this->form_code = $this->html->form_code = 'module=groups&section=permissions&'; $this->form_code_js = $this->html->form_code_js = 'module=groups§ion=permissions&'; /* What to do */ switch( $this->request['do'] ) { case 'delete_set': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_delete' ); $this->_doDeleteSet(); break; case 'do_create_set': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->_doCreatePermissionSet(); break; case 'do_edit_set': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->_permissionSaveForm(); break; case 'edit_set_form': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->_permissionSetForm(); break; case 'view_perm_users': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->permissionSetUsers(); break; case 'remove_mask': $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->removePermissionSet(); break; case 'overview': default: $this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'perms_manage' ); $this->_mainScreen(); break; } /* Output */ $this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper(); $this->registry->getClass('output')->sendOutput(); } /** * Removes permission set(s) from a user * * @return @e void */ public function removePermissionSet() { /* INI */ $member_id = intval( $this->request['id'] ); $perm_id = $this->request['pid']; if( ! $member_id ) { $this->registry->output->showError( $this->lang->words['per_memid'], 11338 ); } /* Get the member */ $this->DB->build( array( 'select' => 'member_id, members_display_name, org_perm_id', 'from' => 'members', 'where' => "member_id={$member_id}" ) ); $this->DB->execute(); if( ! $mem = $this->DB->fetch() ) { $this->registry->output->showError( $this->lang->words['per_memid'], 11339 ); } /* Remove all permission sets */ if( $perm_id == 'all' ) { $this->DB->update( 'members', array( 'org_perm_id' => 0 ), "member_id={$member_id}" ); } /* Remove specific permission set */ else { /* Make Safe */ $perm_id = intval( $perm_id ); /* Get an array of permission ids */ $pid_array = explode( ",", IPSText::cleanPermString( $mem['org_perm_id'] ) ); /* If there's only one, then we can just remove it */ if( count( $pid_array ) < 2 ) { $this->DB->update( 'members', array( 'org_perm_id' => 0 ), "member_id={$member_id}" ); } else { /* Remove the specified element */ unset( $pid_array[ array_search( $perm_id, $pid_array ) ] ); /* Update the database */ $this->DB->update( 'members', array( 'org_perm_id' => implode( ",", $pid_array ) ), "member_id={$member_id}" ); } } /* Output */ $this->registry->output->html .= $this->html->permissionSetRemoveDone( $mem['members_display_name'] ); $this->registry->output->printPopupWindow(); } /** * Show users that are assigned the specified permission set * * @return @e void */ public function permissionSetUsers() { /* Check ID */ $perm_id = intval( $this->request['id'] ); if( ! $perm_id ) { $this->registry->output->showError( $this->lang->words['per_setid'], 11340 ); } /* Query the permission set */ $this->DB->build( array( 'select' => '*', 'from' => 'forum_perms', 'where' => "perm_id={$perm_id}" ) ); $this->DB->execute(); if ( ! $perms = $this->DB->fetch() ) { $this->registry->output->showError( $this->lang->words['per_setid'], 11341 ); } /* Query the users who have this set */ $this->DB->build( array( 'select' => 'member_id, members_display_name, email, posts, org_perm_id', 'from' => 'members', 'where' => "(org_perm_id IS NOT NULL AND org_perm_id != '')", 'order' => 'name' ) ); $outer = $this->DB->execute(); /* Loop through the users */ $rows = array(); while( $r = $this->DB->fetch( $outer ) ) { /* Arrayize the perm ids */ $exp_pid = explode( ",", IPSText::cleanPermString( $r['org_perm_id'] ) ); /* Loop through the ids */ foreach( $exp_pid as $pid ) { /* Is the perm id we are looking for? */ if( $pid == $perm_id ) { /* What other sets is this member using? */ if( count( $exp_pid ) > 1 ) { /* INI the extra field */ $extra = ""; /* Query the set names */ $this->DB->build( array( 'select' => '*', 'from' => 'forum_perms', 'where' => "perm_id IN (" . IPSText::cleanPermString( $r['org_perm_id'] ) . ") AND perm_id <> {$perm_id}" ) ); $this->DB->execute(); /* Add each set to the extra field */ while( $mr = $this->DB->fetch() ) { $extra .= $mr['perm_name'].","; } /* Finish the extra field */ $extra = rtrim( $extra, ',' ); $extra .= ""; } /* No other sets in use */ else { $extra = ""; } /* Add to array */ $r['_extra'] = $extra; $rows[] = $r; } } } /* Output */ $this->registry->output->html .= $this->html->permissionSetUsers( $perm_id, $perms['perm_name'], $rows ); $this->registry->output->printPopupWindow(); } /** * Deletes a permission set * * @return @e void [Outputs to screen] */ protected function _doDeleteSet() { /* INIT */ $id = $this->request['id']; /* Permissions Class */ $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/class_public_permissions.php', 'classPublicPermissions' ); $perm_obj = new $classToLoad( $this->registry ); /* Loop through applications */ $where = array(); foreach( $this->registry->getApplications() as $app ) { /* Check to see if there is a permission map */ $_file = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/coreExtensions.php'; if( is_file( $_file ) ) { /* Get the permission mappings */ $_PERM_CONFIG = array(); require_once( $_file );/*noLibHook*/ /* Check for a config array */ if( is_array( $_PERM_CONFIG ) && count( $_PERM_CONFIG ) ) { /* Loop through the types */ foreach( $_PERM_CONFIG as $perm_type ) { $where[] = " app='{$app['app_directory']}' AND perm_type='" . strtolower( $perm_type ) . "' "; } } } } /* Query Permission Rows */ $this->DB->build( array( 'select' => '*', 'from' => 'permission_index', 'where' => implode( ' OR ', $where ) ) ); $outer = $this->DB->execute(); while( $r = $this->DB->fetch( $outer ) ) { foreach( array( 'perm_view', 'perm_2', 'perm_3', 'perm_4', 'perm_5', 'perm_6', 'perm_7' ) as $p ) { if( $r[$p] != '*' ) { $_perm_arr = explode( ',', IPSText::cleanPermString( $r[$p] ) ); if( in_array( $id, $_perm_arr ) ) { unset( $_perm_arr[ array_search( $id, $_perm_arr ) ] ); } $r[$p] = ',' . implode( ',', $_perm_arr ) . ','; } } $update = $r; unset( $update['perm_id'] ); /* Update */ $this->DB->update( 'permission_index', $update, "perm_id={$r['perm_id']}" ); } /* Delete */ $this->DB->delete( 'forum_perms', "perm_id=" . $id ); /* Fire callbacks */ $this->_fireAppCallbacks(); /* Done */ $this->registry->output->global_message = $this->lang->words['per_removed']; $this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code ); } /** * Creates a nwe permission set * * @return @e void [Outputs to screen] */ protected function _doCreatePermissionSet() { /* INIT */ $set_name = $this->request['new_perm_name']; $base_on = $this->request['new_perm_copy']; if( ! $set_name ) { $this->registry->output->global_message = $this->words['err_specify_set_name']; $this->_mainScreen(); return; } /* Permissions Class */ $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/class_public_permissions.php', 'classPublicPermissions' ); $perm_obj = new $classToLoad( $this->registry ); /* Loop through applications */ $where = array(); foreach( $this->registry->getApplications() as $app ) { /* Check to see if there is a permission map */ $_file = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/coreExtensions.php'; if( is_file( $_file ) ) { /* Get the permission mappings */ $_PERM_CONFIG = array(); require_once( $_file );/*noLibHook*/ /* Check for a config array */ if( is_array( $_PERM_CONFIG ) && count( $_PERM_CONFIG ) ) { /* Loop through the types */ foreach( $_PERM_CONFIG as $perm_type ) { $where[] = " app='{$app['app_directory']}' AND perm_type='" . strtolower( $perm_type ) . "' "; } } } } /* Create the set */ $this->DB->insert( 'forum_perms', array( 'perm_name' => $set_name ) ); $new_set_id = $this->DB->getInsertId(); /* Query Permission Rows */ $this->DB->build( array( 'select' => '*', 'from' => 'permission_index', 'where' => implode( ' OR ', $where ) ) ); $outer = $this->DB->execute(); while( $r = $this->DB->fetch( $outer ) ) { $perm_id = $r['perm_id']; foreach( array( 'perm_view', 'perm_2', 'perm_3', 'perm_4', 'perm_5', 'perm_6', 'perm_7' ) as $p ) { if( $r[$p] != '*' ) { if( in_array( $base_on, explode( ',', IPSText::cleanPermString( $r[$p] ) ) ) ) { $r[$p] .= $new_set_id . ','; } } } /* Unset main ID */ unset( $r['perm_id'] ); /* Update */ $this->DB->update( 'permission_index', $r, "perm_id=" . $perm_id ); } /* Fire callbacks */ $this->_fireAppCallbacks(); /* Done */ $this->registry->output->global_message = $this->lang->words['per_saved']; $this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . 'do=edit_set_form&id=' . $new_set_id ); } /** * Saves the global permission set form * * @return @e void [Outputs to screen] */ protected function _permissionSaveForm() { /* ID */ $id = intval( $this->request['id'] ); $matricies = array(); /* Query Set Name */ $set_data = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'forum_perms', 'where' => "perm_id={$id}" ) ); /* Permissions Class */ $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/class_public_permissions.php', 'classPublicPermissions' ); $perm_obj = new $classToLoad( $this->registry ); /* Save */ $perm_obj->saveItemPermMatrix( $this->request['perms'], $id, $this->request['apps'] ); if( $this->request['perm_name'] != $set_data['perm_name'] ) { $this->DB->update( 'forum_perms', array( 'perm_name' => $this->request['perm_name'] ), "perm_id={$id}" ); } /* Fire callbacks */ $this->_fireAppCallbacks(); /* Done */ $this->registry->output->global_message = $this->lang->words['per_saved']; $this->registry->output->silentRedirectWithMessage( $this->settings['base_url'] . $this->form_code . '&_from=' . $this->request['_from'] ); } /** * Form for modifying a permission set * * @return @e void [Outputs to screen] */ protected function _permissionSetForm() { /* ID */ $id = intval( $this->request['id'] ); $matricies = array(); $apps = array(); /* Query Set Name */ $set_data = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'forum_perms', 'where' => "perm_id={$id}" ) ); /* Permissions Class */ $classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/class_public_permissions.php', 'classPublicPermissions' ); $perm_obj = new $classToLoad( $this->registry ); /* Loop through applications */ foreach( $this->registry->getApplications() as $app ) { /* Check to see if there is a permission map */ $_file = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/coreExtensions.php'; if( is_file( $_file ) ) { /* Get the permission mappings */ $_PERM_CONFIG = array(); require_once( $_file );/*noLibHook*/ /* Check for a config array */ if( is_array( $_PERM_CONFIG ) && count( $_PERM_CONFIG ) ) { /* Loop through the types */ foreach( $_PERM_CONFIG as $perm_type ) { /* Check for a class */ $classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/coreExtensions.php', $app['app_directory'] . 'PermMapping' . $perm_type, $app['app_directory'] ); if( class_exists( $classToLoad ) ) { /* Create the object */ $perm_map = new $classToLoad; /* Make sure the function exists */ if( method_exists( $perm_map, 'getPermItems' ) ) { $_key = count($_PERM_CONFIG) > 1 ? $app['app_title'] . ' ' . $perm_type : $app['app_title']; $matricies[ $_key ] = $perm_obj->adminItemPermMatrix( $perm_map, $perm_map->getPermItems(), $id, $app['app_directory'], $perm_type ); $apps[$app['app_directory']][ $perm_type ] = $perm_type; } } } } } } /* Output */ $this->registry->output->extra_nav[] = array( "{$this->settings['base_url']}&{$this->form_code}", $this->lang->words['menu__manage_perms'] ); $this->registry->output->html .= $this->html->permissionEditor( $set_data['perm_name'], $matricies, $id, $apps ); } /** * List permission masks * * @return @e void [Outputs to screen] */ protected function _mainScreen() { /* INIT */ $perms = array(); $mems = array(); $groups = array(); $dlist = ""; $content = ""; /* Get the names for the perm masks w/id */ $this->DB->build( array( 'select' => '*', 'from' => 'forum_perms', 'order' => 'perm_name ASC' ) ); $this->DB->execute(); while( $r = $this->DB->fetch() ) { $perms[ $r['perm_id'] ] = $r['perm_name']; } /* Number of users using this mask as an override */ $this->DB->build( array( 'select' => 'COUNT(member_id) as count, org_perm_id', 'from' => 'members', 'where' => "(org_perm_id " . $this->DB->buildIsNull( false ) . " AND org_perm_id != '')", 'group' => 'org_perm_id', ) ); $this->DB->execute(); while( $r = $this->DB->fetch() ) { if ( strstr( $r['org_perm_id'] , "," ) ) { foreach( explode( ",", $r['org_perm_id'] ) as $pid ) { $mems[ $pid ] = ! isset( $mems[ $pid ] ) ? 0 : $mems[ $pid ]; $mems[ $pid ] += $r['count']; } } else { $mems[ $r['org_perm_id'] ] += $r['count']; } } /* Groups using this mask */ $this->DB->build( array( 'select' => 'g_id, g_title, g_perm_id', 'from' => 'groups' ) ); $this->DB->execute(); while( $r = $this->DB->fetch() ) { if ( strstr( $r['g_perm_id'] , "," ) ) { foreach( explode( ",", $r['g_perm_id'] ) as $pid ) { $groups[ $pid ][] = $r['g_title']; } } else { $groups[ $r['g_perm_id'] ][] = $r['g_title']; } } /* Build the output data */ $display_groups = array(); foreach( $perms as $id => $name ) { $groups_used = ""; $mems_used = 0; $is_active = 0; $dlist .= "\n"; if ( isset( $groups[ $id ] ) AND is_array( $groups[ $id ] ) ) { foreach( $groups[ $id ] as $g_title ) { $groups_used .= '· ' . $g_title . "
"; } $is_active = 1; } else { $groups_used = "{$this->lang->words['per_none']}"; } if ( !empty($mems[ $id ]) ) { $is_active = 1; } $r['id'] = $id; $r['name'] = $name; $r['isactive'] = $is_active; $r['groups'] = $groups_used; $r['mems'] = isset( $mems[ $id ] ) ? intval( $mems[ $id ] ) : 0; $display_groups[] = $r; } /** * Wow this is convoluted... */ if( $this->request['_from'] ) { $from = explode( '-', $this->request['_from'] ); if( $from[1] ) { $this->registry->class_localization->loadLanguageFile( array( 'admin_groups' ), 'members' ); $this->registry->output->html .= $this->html->groupAdminConfirm( $from[1] ); } } $this->registry->output->html .= $this->html->permissionsSplash( $display_groups, $dlist ); } /** * Fire any application callbacks as needed * * @return @e void */ protected function _fireAppCallbacks() { //----------------------------------------- // Loop through each application //----------------------------------------- foreach( $this->registry->getApplications() as $app ) { // Let's skip the app_enabled check to be sure everything is always recached! //----------------------------------------- // Check for callback file //----------------------------------------- $_file = IPSLib::getAppDir( $app['app_directory'] ) . '/extensions/permissionsSync.php'; if( is_file( $_file ) ) { $classToLoad = IPSLib::loadLibrary( $_file, $app['app_directory'] . 'PermissionsSync', $app['app_directory'] ); $_callback = new $classToLoad( $this->registry ); $_callback->updatePermissions(); } } } }