Version 4.0.13.1
This commit is contained in:
1 parent
f9e857d255
commit
c6a86f0d9b
7517 files changed
+597400
-668041
No files matched your search
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Admin Session Handler
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 11 Mar 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Session;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Session Handler
|
||||
*/
|
||||
class _Admin extends \IPS\Session
|
||||
{
|
||||
/**
|
||||
* @brief Unix Timestamp of log in time
|
||||
*/
|
||||
public $logInTime;
|
||||
|
||||
/**
|
||||
* Open Session
|
||||
*
|
||||
* @param string $savePath Save path
|
||||
* @param string $sessionName Session Name
|
||||
* @return void
|
||||
*/
|
||||
public function open( $savePath, $sessionName )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @return string
|
||||
*/
|
||||
public function read( $sessionId )
|
||||
{
|
||||
/* Get user agent info */
|
||||
$this->userAgent = \IPS\Http\Useragent::parse();
|
||||
|
||||
try
|
||||
{
|
||||
/* Load session */
|
||||
$session = \IPS\Db::i()->select( '*', 'core_sys_cp_sessions', array( 'session_id=?', $sessionId ) )->first();
|
||||
$this->logInTime = $session['session_log_in_time'];
|
||||
|
||||
/* Store this so plugins can access */
|
||||
$this->sessionData = $session;
|
||||
|
||||
/* Load member */
|
||||
$this->member = $session['session_member_id'] ? \IPS\Member::load( $session['session_member_id'] ) : new \IPS\Member;
|
||||
if ( $this->member->member_id and !$this->member->isAdmin() )
|
||||
{
|
||||
throw new \DomainException('NO_ACPACCESS');
|
||||
}
|
||||
|
||||
/* Validate adsess */
|
||||
if ( \IPS\Request::i()->adsess !== $session['session_id'] )
|
||||
{
|
||||
throw new \DomainException('NO_ADSESS');
|
||||
}
|
||||
|
||||
/* Check IP address */
|
||||
if ( \IPS\Settings::i()->match_ipaddress and $session['session_ip_address'] !== \IPS\Request::i()->ipAddress() )
|
||||
{
|
||||
throw new \DomainException('BAD_IP');
|
||||
}
|
||||
|
||||
/* Return data */
|
||||
return $session['session_app_data'];
|
||||
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
$this->logInTime = 0;
|
||||
$this->error = $e;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @param string $data Session Data
|
||||
* @return void
|
||||
*/
|
||||
public function write( $sessionId, $data )
|
||||
{
|
||||
\IPS\Db::i()->replace( 'core_sys_cp_sessions', array(
|
||||
'session_id' => $sessionId,
|
||||
'session_ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'session_member_name' => $this->member->name ?: '-',
|
||||
'session_member_id' => $this->member->member_id ?: 0,
|
||||
'session_member_login_key' => $this->member->member_login_key ?: '',
|
||||
'session_location' => 'app=' . ( \IPS\Dispatcher::i()->application ? \IPS\Dispatcher::i()->application->directory : '' ) . '&module=' . ( \IPS\Dispatcher::i()->module ? \IPS\Dispatcher::i()->module->key : '' ) . '&controller=' . \IPS\Dispatcher::i()->controller,
|
||||
'session_log_in_time' => $this->logInTime,
|
||||
'session_running_time' => time(),
|
||||
'session_url' => \IPS\Request::i()->url(),
|
||||
'session_app_data' => $data
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Session
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy( $sessionId )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_sys_cp_sessions', array( 'session_id=?', $sessionId ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Garbage Collection
|
||||
*
|
||||
* @param int $lifetime Unix timestamp of the oldest session to keep
|
||||
* @return bool
|
||||
*/
|
||||
public function gc( $lifetime )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_sys_cp_sessions', array( 'session_running_time<?', ( time() - $lifetime ) ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Log
|
||||
*
|
||||
* @code
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_enable', array( 'enhancements__foo' => TRUE ) );
|
||||
* @endcode
|
||||
* @param string $langKey Language key for log
|
||||
* @param array $params Key/Values - keys are variables to use in sprintf on $langKey, values are booleans indicating if they are language keys themselves (TRUE) or raw data (FALSE)
|
||||
* @param bool $noDupes If TRUE, will check the last log and not log again if it's the same and less than an hour ago
|
||||
* @return void
|
||||
*/
|
||||
public function log( $langKey, $params=array(), $noDupes=FALSE )
|
||||
{
|
||||
if ( $noDupes )
|
||||
{
|
||||
try
|
||||
{
|
||||
$lastLog = \IPS\Db::i()->select( '*', 'core_admin_logs', array( 'member_id=?', $this->member->member_id ), 'ctime DESC', 1 )->first();
|
||||
if ( $lastLog['ctime'] > ( time() - 3600 ) and $lastLog['lang_key'] == $langKey )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_admin_logs', array(
|
||||
'member_id' => $this->member->member_id,
|
||||
'ctime' => time(),
|
||||
'note' => json_encode( $params ),
|
||||
'ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'appcomponent' => \IPS\Dispatcher::i()->application->directory,
|
||||
'module' => \IPS\Dispatcher::i()->module->key,
|
||||
'controller' => \IPS\Dispatcher::i()->controller,
|
||||
'do' => \IPS\Request::i()->do,
|
||||
'lang_key' => $langKey
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,523 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front Session Handler
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 11 Mar 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Session;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Session Handler
|
||||
*/
|
||||
class _Front extends \IPS\Session
|
||||
{
|
||||
const LOGIN_TYPE_MEMBER = 0;
|
||||
const LOGIN_TYPE_ANONYMOUS = 1;
|
||||
const LOGIN_TYPE_GUEST = 2;
|
||||
const LOGIN_TYPE_SPIDER = 3;
|
||||
|
||||
/**
|
||||
* Guess if the user is logged in
|
||||
*
|
||||
* This is a lightweight check that does not rely on other classes. It is only intended
|
||||
* to be used by the guest caching mechanism so that it can check if the user is logged
|
||||
* in before other classes are initiated.
|
||||
*
|
||||
* This method MUST NOT be used for other purposes as it IS NOT COMPLETELY ACCURATE.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function loggedIn()
|
||||
{
|
||||
return isset( \IPS\Request::i()->cookie['member_id'] ) and \IPS\Request::i()->cookie['member_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Session Data
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @brief Needs saving?
|
||||
*/
|
||||
protected $save = TRUE;
|
||||
|
||||
/**
|
||||
* Open Session
|
||||
*
|
||||
* @param string $savePath Save path
|
||||
* @param string $sessionName Session Name
|
||||
* @return void
|
||||
*/
|
||||
public function open( $savePath, $sessionName )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @return string
|
||||
*/
|
||||
public function read( $sessionId )
|
||||
{
|
||||
$session = NULL;
|
||||
|
||||
/* Get user agent info */
|
||||
$this->userAgent = \IPS\Http\Useragent::parse();
|
||||
|
||||
/* Check the cache */
|
||||
$key = "session_{$sessionId}";
|
||||
if ( isset( \IPS\Data\Cache::i()->$key ) )
|
||||
{
|
||||
$session = \IPS\Data\Cache::i()->$key;
|
||||
}
|
||||
/* Not in cache, check the database */
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
/* If it looks like we're logged in, join the member row to save a query later */
|
||||
if ( static::loggedIn() )
|
||||
{
|
||||
$session = \IPS\Db::i()->select( '*', 'core_sessions', array( 'id=?', $sessionId ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_MULTIDIMENSIONAL_JOINS )->join( 'core_members', 'core_members.member_id=core_sessions.member_id' )->first();
|
||||
if ( $session['core_members']['member_id'] )
|
||||
{
|
||||
\IPS\Member::constructFromData( $session['core_members'], FALSE );
|
||||
}
|
||||
$session = $session['core_sessions'];
|
||||
}
|
||||
/* If we're not logged in, just look at the session */
|
||||
else
|
||||
{
|
||||
/* Spiders match by IP and useragent */
|
||||
if ( $this->userAgent->spider )
|
||||
{
|
||||
$session = \IPS\Db::i()->select( '*', 'core_sessions', array( 'id=? OR ( ip_address=? AND browser=? )', $sessionId, \IPS\Request::i()->ipAddress(), $_SERVER['HTTP_USER_AGENT'] ) )->first();
|
||||
$sessionId = $session['id'];
|
||||
}
|
||||
/* Normal users don't */
|
||||
else
|
||||
{
|
||||
$session = \IPS\Db::i()->select( '*', 'core_sessions', array( 'id=?', $sessionId ) )->first();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
/* Only use sessions with matching IP address */
|
||||
if( \IPS\Settings::i()->match_ipaddress and $session['ip_address'] != \IPS\Request::i()->ipAddress() )
|
||||
{
|
||||
$session = NULL;
|
||||
}
|
||||
|
||||
/* Store this so plugins can access */
|
||||
$this->sessionData = $session;
|
||||
|
||||
/* Got one? */
|
||||
if ( $session )
|
||||
{
|
||||
/* If this is a guest and the "running time" on this is less than 30 seconds ago, or if a member and less than 15 seconds ago, we don't need a database write */
|
||||
if ( ( !$session['member_id'] and $session['running_time'] > ( time() - 30 ) ) or ( $session['member_id'] and $session['running_time'] > ( time() - 15 ) ) )
|
||||
{
|
||||
$this->save = FALSE;
|
||||
}
|
||||
|
||||
/* Set member */
|
||||
try
|
||||
{
|
||||
$this->member = \IPS\Member::load( (int) $session['member_id'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
}
|
||||
}
|
||||
/* We might be able to get the member from a cookie */
|
||||
else
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
}
|
||||
|
||||
/* If we don't have a member, check the cookies */
|
||||
if ( !$this->member->member_id and isset( \IPS\Request::i()->cookie['member_id'] ) and isset( \IPS\Request::i()->cookie['pass_hash'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$member = \IPS\Member::load( (int) \IPS\Request::i()->cookie['member_id'] );
|
||||
if ( $member->member_login_key === \IPS\Request::i()->cookie['pass_hash'] )
|
||||
{
|
||||
$this->member = $member;
|
||||
|
||||
/* Renew those cookies */
|
||||
$expire = new \IPS\DateTime;
|
||||
$expire->add( new \DateInterval( 'P7D' ) );
|
||||
\IPS\Request::i()->setCookie( 'member_id', $member->member_id, $expire );
|
||||
\IPS\Request::i()->setCookie( 'pass_hash', $member->member_login_key, $expire );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
\IPS\Request::i()->setCookie( 'member_id', NULL );
|
||||
\IPS\Request::i()->setCookie( 'pass_hash', NULL );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
\IPS\Request::i()->setCookie( 'member_id', NULL );
|
||||
\IPS\Request::i()->setCookie( 'pass_hash', NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/* Work out the type */
|
||||
if ( $this->member->member_id )
|
||||
{
|
||||
if ( ( $session and $session['login_type'] === static::LOGIN_TYPE_ANONYMOUS ) or isset( \IPS\Request::i()->cookie['anon_login'] ) and \IPS\Request::i()->cookie['anon_login'] )
|
||||
{
|
||||
$type = static::LOGIN_TYPE_ANONYMOUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = static::LOGIN_TYPE_MEMBER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $this->userAgent->spider ? static::LOGIN_TYPE_SPIDER : static::LOGIN_TYPE_GUEST;
|
||||
}
|
||||
|
||||
/* Set data */
|
||||
$this->data = array(
|
||||
'id' => $sessionId,
|
||||
'member_name' => $this->member->member_id ? $this->member->name : '',
|
||||
'seo_name' => $this->member->member_id ? ( $this->member->members_seo_name ?: '' ) : '',
|
||||
'member_id' => $this->member->member_id ?: 0,
|
||||
'ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'browser' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
||||
'running_time' => time(),
|
||||
'login_type' => $type,
|
||||
'member_group' => ($this->member->member_id) ? $this->member->member_group_id : \IPS\Settings::i()->guest_group,
|
||||
'current_appcomponent' => '',
|
||||
'current_module' => '',
|
||||
'current_controller' => NULL,
|
||||
'current_id' => intval( \IPS\Request::i()->id ),
|
||||
'uagent_key' => $this->userAgent->useragentKey,
|
||||
'uagent_version' => $this->userAgent->useragentVersion ?: '',
|
||||
'uagent_type' => $this->userAgent->spider ? 'search' : 'browser',
|
||||
'search_thread_id' => $session ? $session['search_thread_id'] : 0,
|
||||
'search_thread_time' => $session ? $session['search_thread_time'] : 0,
|
||||
'data' => $session ? $session['data'] : NULL,
|
||||
'location_url' => $session ? $session['location_url'] : NULL,
|
||||
'location_lang' => $session ? $session['location_lang'] : NULL,
|
||||
'location_data' => $session ? $session['location_data'] : NULL,
|
||||
'location_permissions' => $session ? $session['location_permissions'] : NULL,
|
||||
'theme_id' => $session ? $session['theme_id'] : 0,
|
||||
);
|
||||
|
||||
/* Is this a spider? */
|
||||
if( $this->userAgent->spider )
|
||||
{
|
||||
/* Is this Facebook? Do we need to treat them as a user of a different group? */
|
||||
if( $this->userAgent->useragentKey == 'facebook' )
|
||||
{
|
||||
if( \IPS\core\ShareLinks\Service::load( 'facebook', 'share_key' )->enabled )
|
||||
{
|
||||
if( $this->userAgent->facebookIpVerified( \IPS\Request::i()->ipAddress() ) AND \IPS\Settings::i()->fbc_bot_group != \IPS\Settings::i()->guest_group )
|
||||
{
|
||||
$this->member->member_group_id = \IPS\Settings::i()->fbc_bot_group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->data['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Session Member
|
||||
*
|
||||
* @param \IPS\Member $member Member object
|
||||
* @return void
|
||||
*/
|
||||
public function setMember( $member )
|
||||
{
|
||||
parent::setMember( $member );
|
||||
|
||||
/* Make sure login key has been set */
|
||||
$member->checkLoginKey();
|
||||
|
||||
/* Set the cookies */
|
||||
$expire = new \IPS\DateTime;
|
||||
$expire->add( new \DateInterval( 'P7D' ) );
|
||||
\IPS\Request::i()->setCookie( 'member_id', $member->member_id, $expire );
|
||||
\IPS\Request::i()->setCookie( 'pass_hash', $member->member_login_key, $expire );
|
||||
|
||||
/* Make sure session handler saves during write() */
|
||||
$this->save = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @param string $data Session Data
|
||||
* @return void
|
||||
*/
|
||||
public function write( $sessionId, $data )
|
||||
{
|
||||
if ( $data !== $this->data['data'] or $this->data['member_id'] != $this->member->member_id )
|
||||
{
|
||||
$this->save = TRUE;
|
||||
}
|
||||
|
||||
$this->data['member_name'] = $this->member->member_id ? $this->member->name : '';
|
||||
$this->data['member_id'] = $this->member->member_id ?: NULL;
|
||||
$this->data['data'] = $data;
|
||||
$this->setLocationData();
|
||||
|
||||
$key = "session_{$sessionId}";
|
||||
\IPS\Data\Cache::i()->$key = $this->data;
|
||||
|
||||
if ( $this->save === TRUE and ( !empty( \IPS\Request::i()->cookie ) or $this->userAgent->spider or $this->member->member_id ) ) // If a guest and cookies are disabled we do not write to database to prevent duplicate sessions unless it's a search engine, which we deal with separately
|
||||
{
|
||||
\IPS\Db::i()->replace( 'core_sessions', $this->data, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the search start
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function startSearch()
|
||||
{
|
||||
$this->data['search_thread_id'] = \IPS\Db::i()->thread_id;
|
||||
$this->data['search_thread_time'] = time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the search end
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function endSearch()
|
||||
{
|
||||
$this->data['search_thread_id'] = 0;
|
||||
$this->data['search_thread_time'] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a theme ID
|
||||
*
|
||||
* @param int $themeId The theme id, of course
|
||||
* @return void
|
||||
*/
|
||||
public function setTheme( $themeId )
|
||||
{
|
||||
if( !\IPS\Dispatcher::hasInstance() OR \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['theme_id'] = $themeId;
|
||||
|
||||
$this->save = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the theme ID
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTheme()
|
||||
{
|
||||
if ( isset( $this->data['theme_id'] ) and $this->data['theme_id'] )
|
||||
{
|
||||
return $this->data['theme_id'];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set basic location data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLocationData()
|
||||
{
|
||||
if( !\IPS\Dispatcher::hasInstance() OR \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['current_appcomponent'] = \IPS\Dispatcher::i()->application ? \IPS\Dispatcher::i()->application->directory : '';
|
||||
$this->data['current_module'] = \IPS\Dispatcher::i()->module ? \IPS\Dispatcher::i()->module->key : '';
|
||||
$this->data['current_controller'] = \IPS\Dispatcher::i()->controller;
|
||||
$this->data['current_id'] = intval( \IPS\Request::i()->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the session location
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL
|
||||
* @param array $groupIds Permission data
|
||||
* @param string $lang Language string
|
||||
* @param array $data Language data. Keys are the words, value is a boolean indicating if it's a language key (TRUE) or should be displayed as-is (FALSE)
|
||||
* @return void
|
||||
*/
|
||||
public function setLocation( \IPS\Http\Url $url, $groupIds, $lang, $data=array() )
|
||||
{
|
||||
if( !\IPS\Dispatcher::hasInstance() OR \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->data['location_url'] = (string) $url;
|
||||
$this->data['location_lang'] = $lang;
|
||||
$this->data['location_data'] = json_encode( $data );
|
||||
$this->data['current_id'] = intval( \IPS\Request::i()->id );
|
||||
|
||||
if ( !$this->data['current_appcomponent'] )
|
||||
{
|
||||
$this->setLocationData();
|
||||
}
|
||||
|
||||
$groupIds = is_string( $groupIds ) ? explode( ',', $groupIds ) : ( $groupIds ?: NULL );
|
||||
|
||||
$app = \IPS\Application::load( $this->data['current_appcomponent'] );
|
||||
if ( !$app->enabled )
|
||||
{
|
||||
$groupIds = $groupIds ? array_intersect( $groupIds, explode( ',', $app->disabled_groups ) ) : explode( ',', $app->disabled_groups );
|
||||
}
|
||||
|
||||
$modulePermissions = \IPS\Application\Module::get( $this->data['current_appcomponent'], $this->data['current_module'], 'front' )->permissions();
|
||||
if ( $modulePermissions['perm_view'] !== '*' )
|
||||
{
|
||||
$groupIds = $groupIds ? array_intersect( $groupIds, explode( ',', $modulePermissions['perm_view'] ) ) : explode( ',', $modulePermissions['perm_view'] );
|
||||
}
|
||||
|
||||
$this->data['location_permissions'] = ( $groupIds !== NULL ) ? ( is_string( $groupIds ) ? $groupIds : implode( ',', $groupIds ) ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the session location
|
||||
*
|
||||
* @param array $row Row from sessions
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getLocation( $row )
|
||||
{
|
||||
$location = NULL;
|
||||
|
||||
if( !$row['location_lang'] )
|
||||
{
|
||||
return $location;
|
||||
}
|
||||
|
||||
if ( $row['location_permissions'] === NULL or $row['location_permissions'] === '*' or \IPS\Member::loggedIn()->inGroup( explode( ',', $row['location_permissions'] ), TRUE ) )
|
||||
{
|
||||
$sprintf = array();
|
||||
$data = json_decode( $row['location_data'], TRUE );
|
||||
|
||||
if ( !empty( $data ) )
|
||||
{
|
||||
foreach ( $data as $key => $parse )
|
||||
{
|
||||
$value = htmlspecialchars( $parse ? \IPS\Member::loggedIn()->language()->get( $key ) : $key, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
|
||||
$sprintf[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$location = \IPS\Member::loggedIn()->language()->addToStack( htmlspecialchars( $row['location_lang'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ), FALSE, array( 'htmlsprintf' => $sprintf ) );
|
||||
|
||||
$location = "<a href='" . htmlspecialchars( $row['location_url'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "'>" . $location . "</a>";
|
||||
}
|
||||
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the session as anonymous
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAnon()
|
||||
{
|
||||
$this->data['login_type'] = static::LOGIN_TYPE_ANONYMOUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the session as anonymous
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getAnon()
|
||||
{
|
||||
return (bool) $this->data['login_type'] == static::LOGIN_TYPE_ANONYMOUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Session
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy Session
|
||||
*
|
||||
* @param string $sessionId Session ID
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy( $sessionId )
|
||||
{
|
||||
$key = "session_{$sessionId}";
|
||||
unset( \IPS\Data\Cache::i()->$key );
|
||||
|
||||
if ( isset( $_SESSION['wizardKey'] ) )
|
||||
{
|
||||
$dataKey = $_SESSION['wizardKey'];
|
||||
unset( \IPS\Data\Store::i()->$dataKey );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_sessions', array( 'id=?', $sessionId ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Garbage Collection
|
||||
*
|
||||
* @param int $lifetime Unix timestamp of the oldest session to keep
|
||||
* @return bool
|
||||
*/
|
||||
public function gc( $lifetime )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_sessions', array( 'running_time<?', ( time() - $lifetime ) ) ) as $row )
|
||||
{
|
||||
$key = "session_{$row['id']}";
|
||||
unset( \IPS\Data\Cache::i()->$key );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_sessions', array( 'running_time<?', ( time() - $lifetime ) ) );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Session Handler
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 11 Mar 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session Handler
|
||||
*/
|
||||
abstract class _Session
|
||||
{
|
||||
/**
|
||||
* @brief Singleton Instance
|
||||
*/
|
||||
protected static $instance = NULL;
|
||||
|
||||
/**
|
||||
* @brief User agent information
|
||||
* @see \IPS\Http\Useragent::parse()
|
||||
*/
|
||||
public $userAgent = NULL;
|
||||
|
||||
/**
|
||||
* @brief Session record - stored so plugins can access
|
||||
*/
|
||||
protected $sessionData = NULL;
|
||||
|
||||
/**
|
||||
* Get instance
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function i()
|
||||
{
|
||||
if( self::$instance === NULL )
|
||||
{
|
||||
$classname = get_called_class();
|
||||
if ( get_called_class() === 'IPS\Session' )
|
||||
{
|
||||
if( class_exists( 'IPS\Dispatcher', FALSE ) )
|
||||
{
|
||||
$location = ( \IPS\Dispatcher::hasInstance() ) ? ucfirst( \IPS\Dispatcher::i()->controllerLocation ) : 'Front';
|
||||
$classname = 'IPS\Session\\' . $location;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \RuntimeException('LOCATION_UNKNOWN');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$location = \substr( $classname, 12 );
|
||||
}
|
||||
|
||||
if ( class_exists( $classname ) )
|
||||
{
|
||||
/* Create class */
|
||||
self::$instance = new $classname;
|
||||
|
||||
/* Name the session */
|
||||
$name = session_name( ( \IPS\COOKIE_PREFIX !== NULL ) ? \IPS\COOKIE_PREFIX . 'IPSSession' . $location : 'IPSSession' . $location );
|
||||
|
||||
/* Set the handler */
|
||||
session_write_close();
|
||||
session_set_save_handler( array( self::$instance, 'open' ), array( self::$instance, 'close' ), array( self::$instance, 'read' ), array( self::$instance, 'write' ), array( self::$instance, 'destroy' ), array( self::$instance, 'gc' ) );
|
||||
|
||||
/* Make sure we use HTTP-Only cookies */
|
||||
session_set_cookie_params(
|
||||
'0',
|
||||
( \IPS\COOKIE_PATH !== NULL ) ? \IPS\COOKIE_PATH : '/',
|
||||
( \IPS\COOKIE_DOMAIN !== NULL ) ? \IPS\COOKIE_DOMAIN : '',
|
||||
( \IPS\COOKIE_BYPASS_SSLONLY !== NULL ) ? ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' ) : FALSE,
|
||||
TRUE
|
||||
);
|
||||
|
||||
/* Start */
|
||||
session_start();
|
||||
|
||||
/* Init */
|
||||
self::$instance->init();
|
||||
|
||||
/* Register shutdown */
|
||||
register_shutdown_function('session_write_close');
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$instance = new \StdClass;
|
||||
self::$instance->member = new \IPS\Member;
|
||||
self::$instance->csrfKey = '';
|
||||
|
||||
/* Upgrader starts session already */
|
||||
if ( !\IPS\Dispatcher::hasInstance() or !\IPS\Dispatcher::i() instanceof \IPS\Dispatcher\Setup )
|
||||
{
|
||||
if ( version_compare( phpversion(), '5.4.0', '>=' ) )
|
||||
{
|
||||
if( session_status() !== PHP_SESSION_ACTIVE )
|
||||
{
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( session_id() === '' )
|
||||
{
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Session ID
|
||||
*/
|
||||
public $id = NULL;
|
||||
|
||||
/**
|
||||
* @brief Currently logged in member
|
||||
*/
|
||||
public $member = NULL;
|
||||
|
||||
/**
|
||||
* @brief CSRF Key
|
||||
*/
|
||||
public $csrfKey = '';
|
||||
|
||||
/**
|
||||
* @brief Validation Error
|
||||
*/
|
||||
public $error = NULL;
|
||||
|
||||
/**
|
||||
* Set Session Member
|
||||
*
|
||||
* @param \IPS\Member $member Member object
|
||||
* @return void
|
||||
*/
|
||||
public function setMember( $member )
|
||||
{
|
||||
$_SESSION['forcedWrite'] = time();
|
||||
$this->member = $member;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Set ID */
|
||||
$this->id = session_id();
|
||||
|
||||
/* Crate csrf key */
|
||||
$this->csrfKey = md5( "{$this->member->email}&{$this->member->member_login_key}& " . ( $this->member->member_id ? $this->member->joined->getTimestamp() : 0 ) . '&' . $this->id );
|
||||
|
||||
/* Update member */
|
||||
if ( $this->member->member_id )
|
||||
{
|
||||
$save = FALSE;
|
||||
|
||||
/* Set the last activity */
|
||||
if ( isset( $this->data ) and $this->data['login_type'] != static::LOGIN_TYPE_ANONYMOUS )
|
||||
{
|
||||
if ( time() - $this->member->last_activity > 3600 )
|
||||
{
|
||||
$save = TRUE;
|
||||
$this->member->last_visit = $this->member->last_activity;
|
||||
}
|
||||
if ( time() - $this->member->last_activity > 180 )
|
||||
{
|
||||
$save = TRUE;
|
||||
$this->member->last_activity = time();
|
||||
}
|
||||
}
|
||||
|
||||
/* Set timezone */
|
||||
if ( !$this->member->members_bitoptions['timezone_override'] and isset( \IPS\Request::i()->cookie['ipsTimezone'] ) and \IPS\Request::i()->cookie['ipsTimezone'] !== $this->member->timezone )
|
||||
{
|
||||
$save = TRUE;
|
||||
$this->member->timezone = \IPS\Request::i()->cookie['ipsTimezone'];
|
||||
}
|
||||
|
||||
/* Save */
|
||||
if ( $save )
|
||||
{
|
||||
$this->member->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF Check
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function csrfCheck()
|
||||
{
|
||||
if ( \IPS\Request::i()->csrfKey !== $this->csrfKey )
|
||||
{
|
||||
\IPS\Output::i()->error( 'generic_error', '2S119/1', 403, 'admin_csrf_error' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moderator Log
|
||||
* @code
|
||||
\IPS\Session::i()->modLog( 'modlog__spammer_flagged', array( $this->name => FALSE ) );
|
||||
* @endcode
|
||||
* @param string $langKey Language key for log
|
||||
* @param array $params Key/Values - keys are variables to use in sprintf on $langKey, values are booleans indicating if they are language keys themselves (TRUE) or raw data (FALSE)
|
||||
* @param \IPS\Content\Item|NULL If moderation action is specific to an item
|
||||
* @return void
|
||||
*/
|
||||
public function modLog( $langKey, $params=array(), $item=null )
|
||||
{
|
||||
$class = NULL;
|
||||
|
||||
if ( $item instanceof \IPS\Content\Item )
|
||||
{
|
||||
$class = get_class( $item );
|
||||
$idColumn = $class::$databaseColumnId;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_moderator_logs', array(
|
||||
'member_id' => \IPS\Member::loggedIn()->member_id,
|
||||
'ctime' => time(),
|
||||
'note' => json_encode( $params ),
|
||||
'ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'appcomponent' => \IPS\Dispatcher::i()->application->directory,
|
||||
'module' => \IPS\Dispatcher::i()->module->key,
|
||||
'controller' => \IPS\Dispatcher::i()->controller,
|
||||
'do' => \IPS\Request::i()->do,
|
||||
'lang_key' => $langKey,
|
||||
'class' => $class,
|
||||
'item_id' => $item ? $item->$idColumn : NULL,
|
||||
) );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Reference in new issue
Block a user