* Invision Power Services * IP.Board v3.4.8 * ACP Restrictions * Last Updated: $Date: 2013-01-22 16:10:36 -0500 (Tue, 22 Jan 2013) $ * * * @author $Author: AndyMillne $ * @copyright (c) 2001 - 2009 Invision Power Services, Inc. * @license http://www.invisionpower.com/company/standards.php#license * @package IP.Board * @link http://www.invisionpower.com * @since 1st march 2002 * @version $Revision: 11883 $ * */ class class_permissions { /**#@+ * Registry objects * * @access protected * @var object */ protected $registry; protected $DB; protected $settings; protected $request; protected $lang; protected $member; protected $memberData; protected $cache; protected $caches; /**#@-*/ /** * Restrictions row * * @access public * @var array */ public $restrictions_row = array(); /** * Is restricted or not? * * @access protected * @var boolean */ protected $restricted = false; /** * Return or error out flag * * @access public * @var boolean */ public $return = true; /** * In dev flag (allow all) * * @access public * @var boolean */ public $in_dev = false; public $editDetailsOnly = false; /** * Constructor * * @access public * @param object ipsRegistry reference * @param array [Optional] Member permissions array to use (otherwise loads the current member's from the db) * @return @e void */ public function __construct( ipsRegistry $registry, $permissions=array() ) { $this->registry = $registry; $this->DB = $this->registry->DB(); $this->settings =& $this->registry->fetchSettings(); $this->request =& $this->registry->fetchRequest(); $this->lang = $this->registry->getClass('class_localization'); $this->member = $this->registry->member(); $this->memberData =& $this->registry->member()->fetchMemberData(); if( is_array($permissions) AND count($permissions) ) { $this->restrictions_row = $permissions; $this->restricted = true; } else { //----------------------------------------- // Don't do this on login //----------------------------------------- if( !$this->memberData['member_id'] ) { return false; } //----------------------------------------- // Get restrictions //----------------------------------------- $primaryGroupIsRestricted = FALSE; $memberIsRestricted = FALSE; $groups[] = $this->memberData['member_group_id']; if( $this->memberData['mgroup_others'] ) { $groups = array_merge( $groups, explode( ',', IPSText::cleanPermString( $this->memberData['mgroup_others'] ) ) ); } $this->DB->build( array( 'select' => '*', 'from' => 'admin_permission_rows', 'where' => "(row_id_type='member' AND row_id=" . $this->memberData['member_id'] . ") OR (row_id_type='group' AND row_id IN(" . implode( ',', $groups ) . "))" ) ); $this->DB->execute(); while( $r = $this->DB->fetch() ) { //----------------------------------------- // Member restrictions should override group restrictions //----------------------------------------- if( $r['row_id_type'] == 'member' ) { $this->restrictions_row = unserialize($r['row_perm_cache']); $this->restricted = true; $memberIsRestricted = TRUE; break; } elseif ( $r['row_id'] == $this->memberData['member_group_id'] ) { $primaryGroupIsRestricted = TRUE; } $this->restrictions_row = array_merge( $this->restrictions_row, unserialize($r['row_perm_cache']) ); $this->restricted = true; } //----------------------------------------- // The primary group may not be restricted // but it may not be able to access ACP either //----------------------------------------- $cache = ipsRegistry::cache()->getCache('group_cache'); if( ! $cache[$this->memberData['member_group_id']]['g_access_cp'] ) { $primaryGroupIsRestricted = TRUE; } //----------------------------------------- // If the primary group is unrestricted // then we don't have any restrictions //----------------------------------------- if ( !$primaryGroupIsRestricted and !$memberIsRestricted ) { $this->restricted = false; } } /* Add in permissions for change my details, if we have restrictions, but not acess to that module */ if( is_array( $this->restrictions_row ) && count( $this->restrictions_row ) ) { $coreId = ipsRegistry::$applications[ 'core' ]['app_id']; foreach( ipsRegistry::$modules['core'] as $module ) { if( $module['sys_module_key'] == 'mycp' ) { $this->mycpModule = $module['sys_module_id']; continue; } } if( ! in_array( $coreId, $this->restrictions_row['applications'] ) ) { $this->restrictions_row['applications'][] = $coreId; } if( ! in_array( $this->mycpModule, $this->restrictions_row['modules'] ) ) { $this->restrictions_row['modules'][] = $this->mycpModule; $this->editDetailsOnly = true; } } } /** * Check Application Access * * Checks the permission for the member * * @access public * @param string [ Application Key ] * @return mixed Boolean member has access or not, or print error if $this->return is false */ public function checkForAppAccess( $app='' ) { //----------------------------------------- // IN DEV check? //----------------------------------------- if ( $this->in_dev and IN_DEV ) { return TRUE; } //----------------------------------------- // INIT //----------------------------------------- $app = ( $app ) ? $app : ipsRegistry::$current_application; $app_id = ipsRegistry::$applications[ $app ]['app_id']; $return = $this->restricted ? false : true; if( is_array($this->restrictions_row) AND count($this->restrictions_row) ) { if( isset($this->restrictions_row['applications']) ) { if( in_array( $app_id, $this->restrictions_row['applications'] ) ) { $return = TRUE; } } } //----------------------------------------- // I can haz teh permishuns? //----------------------------------------- if ( $this->return ) { return $return; } else { if ( $return === FALSE ) { ipsRegistry::getClass('output')->showError( $this->lang->words['no_permission'], 1002 ); } else { return $return; } } } /** * Check Module Access * * Checks the permission for the member * * @access public * @param string [ Application Key ] * @param string [ Module Key ] * @return mixed Boolean has access or not, or outputs HTML error message */ public function checkForModuleAccess( $app='', $module='' ) { //----------------------------------------- // IN DEV check? //----------------------------------------- if ( $this->in_dev and IN_DEV ) { return TRUE; } $auto_access = array( 'ajax', 'api', 'search', 'palette', 'login' ); if ( IN_ACP ) { $auto_access[] = 'attach'; } if ( in_array( $module, $auto_access ) ) { return TRUE; } //----------------------------------------- // INIT //----------------------------------------- $app = ( $app ) ? $app : ipsRegistry::$current_application; $app_id = ipsRegistry::$applications[ $app ]['app_id']; $module = ( $module ) ? $module : ipsRegistry::$current_module; $mod_id = $this->_getModuleId( $app, $module ); $return = $this->restricted ? false : true; //----------------------------------------- // Access application? //----------------------------------------- if( ! $this->checkForAppAccess( $app ) ) { return false; } if( is_array($this->restrictions_row) AND count($this->restrictions_row) ) { if( isset($this->restrictions_row['modules']) ) { if( in_array( $mod_id, $this->restrictions_row['modules'] ) ) { $return = TRUE; } } } //----------------------------------------- // I can haz teh permishuns? //----------------------------------------- if ( $this->return ) { return $return; } else { if ( $return === FALSE ) { ipsRegistry::getClass('output')->showError( 'no_permission', 1003 ); } else { return $return; } } } /** * Check Section Access * * Checks the permission for the member * * @access public * @param string [ Application Key ] * @param string [ Module Key ] * @param string [ Section Key ] * @return mixed Boolean has access or not, or outputs HTML error message */ public function checkForSectionAccess( $app='', $module='', $section='' ) { //----------------------------------------- // IN DEV check? //----------------------------------------- if ( $this->in_dev and IN_DEV ) { return TRUE; } $auto_access = array( 'ajax', 'api', 'search', 'palette', 'login' ); if ( in_array( $module, $auto_access ) ) { return TRUE; } //----------------------------------------- // Module access? //----------------------------------------- if ( !$this->checkForModuleAccess( $app, $module ) ) { return FALSE; } //----------------------------------------- // Can we access? //----------------------------------------- $menu = ipsRegistry::cache()->getCache('app_menu_cache'); foreach( $menu[ $app ] as $k => $items ) { if ( preg_match( '/(\d)_' . $module . '/', $k ) ) { foreach( $items['items'] as $i ) { if ( $i['section'] == $section ) { if ( $i['rolekey'] ) { $return = $this->checkPermission( $i['rolekey'], $app, $module ); break 2; } else { $return = TRUE; break 2; } } } } } //----------------------------------------- // I can haz teh permishuns? //----------------------------------------- if ( $this->return ) { return $return; } else { if ( $return === FALSE ) { ipsRegistry::getClass('output')->showError( 'no_permission', 1004 ); } else { return $return; } } } /** * Grab the module id from the modules array * * @access protected * @param string [ Application Key ] * @param string [ Module Key ] * @return integer Module id */ protected function _getModuleId( $app='', $module='' ) { $app = ( $app ) ? $app : ipsRegistry::$current_application; $app_id = ipsRegistry::$applications[ $app ]['app_id']; $module = ( $module ) ? $module : ipsRegistry::$current_module; $modules = ipsRegistry::$modules[ $app ]; $mod_id = 0; if( is_array($modules) AND count($modules) ) { foreach( $modules as $module_id => $module_data ) { if( $module_data['sys_module_key'] == $module AND $module_data['sys_module_admin'] == 1 ) { $mod_id = $module_data['sys_module_id']; break; } } } return $mod_id; } /** * Wrapper for checkPermission to show the error message regardless of current status of $this->return * * Checks the permission for the member * * @access public * @param string Permission Key (from items array) * @param string [ Application Key ] * @param string [ Module Key ] * @return mixed True if has permission or outputs HTML error message if not */ public function checkPermissionAutoMsg( $key, $app='', $module='' ) { $tmp = $this->return; $this->return = false; $this->checkPermission( $key, $app, $module ); $this->return = $tmp; return true; } /** * Check Permission to a given key * * Checks the permission for the member * * @access public * @param string Permission Key (from items array) * @param string [ Application Key ] * @param string [ Module Key ] * @return mixed True if has permission or outputs HTML error message if not */ public function checkPermission( $key, $app='', $module='' ) { //----------------------------------------- // IN DEV check? //----------------------------------------- if ( $this->in_dev and IN_DEV ) { return TRUE; } //----------------------------------------- // INIT //----------------------------------------- $app = ( $app ) ? $app : ipsRegistry::$current_application; $app_id = ipsRegistry::$applications[ $app ]['app_id']; $module = ( $module ) ? $module : ipsRegistry::$current_module; $mod_id = $this->_getModuleId( $app, $module ); $return = $this->restricted ? false : true; //----------------------------------------- // Check module, which will also check app //----------------------------------------- if( ! $this->checkForModuleAccess( $app, $module ) ) { $return = false; } else if( $key ) { //print "
";print $key. ' '.$module . ' ' .$mod_id;
//print_r($this->restrictions_row['modules']);
//print_r($this->restrictions_row['items'][ $mod_id ]);
//-----------------------------------------
// And now for the item..
//-----------------------------------------
if( is_array($this->restrictions_row) AND count($this->restrictions_row) )
{
if( isset($this->restrictions_row['items']) )
{
if( isset($this->restrictions_row['items'][ $mod_id ]) )
{
if( in_array( $key, $this->restrictions_row['items'][ $mod_id ] ) )
{
$return = TRUE;
}
}
}
}
}
//-----------------------------------------
// Returning.. or...
//-----------------------------------------
if ( $this->return )
{
return $return;
}
else
{
if ( $return === FALSE )
{
ipsRegistry::getClass('output')->showError( 'no_permission', 1004 );
}
else
{
return $return;
}
}
}
}