Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
+149
-15
@@ -11,7 +11,7 @@
|
||||
namespace IPS\Session;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -41,7 +41,20 @@ class _Front extends \IPS\Session
|
||||
*/
|
||||
public static function loggedIn()
|
||||
{
|
||||
return isset( \IPS\Request::i()->cookie['member_id'] ) and \IPS\Request::i()->cookie['member_id'];
|
||||
/* If we have a "member_id" cookie, we're probably logged in... */
|
||||
if ( isset( \IPS\Request::i()->cookie['member_id'] ) and \IPS\Request::i()->cookie['member_id'] )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If the request sent an access token which has GraphQL acceess we'll need to check that */
|
||||
if ( isset( $_SERVER['HTTP_X_IPS_ACCESSTOKENMEMBER'] ) or isset( \IPS\Request::i()->access_token_member ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Still here: assume not logged in */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,6 +67,11 @@ class _Front extends \IPS\Session
|
||||
*/
|
||||
protected $save = TRUE;
|
||||
|
||||
/**
|
||||
* @brief No write guest session?
|
||||
*/
|
||||
protected $noWriteGuestSession = FALSE;
|
||||
|
||||
/**
|
||||
* Open Session
|
||||
*
|
||||
@@ -78,11 +96,17 @@ class _Front extends \IPS\Session
|
||||
|
||||
/* Get user agent info */
|
||||
$this->userAgent = \IPS\Http\Useragent::parse();
|
||||
|
||||
|
||||
if ( ! static::loggedIn() and isset( \IPS\Request::i()->cookie['guestTime'] ) and ( !isset( \IPS\Request::i()->cookie['noCache'] ) or !\IPS\Request::i()->cookie['noCache'] ) and time() < ( \IPS\Request::i()->cookie['guestTime'] + \IPS\CACHE_PAGE_TIMEOUT ) and \IPS\Request::i()->requestMethod() == 'GET' )
|
||||
{
|
||||
$this->sessionData = $this->setNoWriteGuestSession();
|
||||
return (string) $this->sessionData['data'];
|
||||
}
|
||||
|
||||
$session = \IPS\Session\Store::i()->loadSession( $this->sessionId );
|
||||
|
||||
/* Only use sessions with matching IP address */
|
||||
if( \IPS\Settings::i()->match_ipaddress and $session['ip_address'] != \IPS\Request::i()->ipAddress() )
|
||||
if( $session and \IPS\Settings::i()->match_ipaddress and $session['ip_address'] != \IPS\Request::i()->ipAddress() )
|
||||
{
|
||||
$session = NULL;
|
||||
}
|
||||
@@ -99,11 +123,15 @@ class _Front extends \IPS\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 ) ) )
|
||||
/* If this is a guest and the "running time" on this is less than the guest page cache, 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() - \IPS\CACHE_PAGE_TIMEOUT ) ) or ( $session['member_id'] and $session['running_time'] < ( time() - 15 ) ) )
|
||||
{
|
||||
$this->save = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->save = FALSE;
|
||||
}
|
||||
|
||||
/* Set member */
|
||||
try
|
||||
@@ -120,8 +148,59 @@ class _Front extends \IPS\Session
|
||||
{
|
||||
$this->member = new \IPS\Member;
|
||||
}
|
||||
|
||||
/* If we don't have a member, but the request *did* send an access token which has GraphQL acceess (i.e. unfettered access to act as the user), then use that */
|
||||
if ( !$this->member->member_id and ( isset( $_SERVER['HTTP_X_IPS_ACCESSTOKENMEMBER'] ) or isset( \IPS\Request::i()->access_token_member ) ) and $authorizationHeader = \IPS\Request::i()->authorizationHeader() and mb_substr( $authorizationHeader, 0, 7 ) === 'Bearer ' and ( !\IPS\OAUTH_REQUIRES_HTTPS or \IPS\Request::i()->isSecure() ) )
|
||||
{
|
||||
$expectedMember = \IPS\Member::load( isset( $_SERVER['HTTP_X_IPS_ACCESSTOKENMEMBER'] ) ? $_SERVER['HTTP_X_IPS_ACCESSTOKENMEMBER'] : \IPS\Request::i()->access_token_member );
|
||||
if ( $expectedMember->member_id )
|
||||
{
|
||||
/* Start by checking the access token is valid and for this member */
|
||||
try
|
||||
{
|
||||
$accessToken = \IPS\Api\OAuthClient::accessTokenDetails( mb_substr( $authorizationHeader, 7 ) );
|
||||
$client = \IPS\Api\OAuthClient::load( $accessToken['client_id'] );
|
||||
if ( $client->graphql and $accessToken['member_id'] === $expectedMember->member_id )
|
||||
{
|
||||
$success = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$success = FALSE;
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$success = FALSE;
|
||||
}
|
||||
|
||||
/* Because this is effectively a log in attempt, we need to make sure the account is not locked */
|
||||
try
|
||||
{
|
||||
\IPS\Login::checkIfAccountIsLocked( $expectedMember, $success );
|
||||
|
||||
/* If it isn't, we can either set that we are that member... */
|
||||
if ( $success )
|
||||
{
|
||||
$this->member = $expectedMember;
|
||||
}
|
||||
/* Or if the access token wasn't valid, log it as a fail so that it can't be bruteforced */
|
||||
else
|
||||
{
|
||||
$failedLogins = \is_array( $expectedMember->failed_logins ) ? $expectedMember->failed_logins : array();
|
||||
$failedLogins[ \IPS\Request::i()->ipAddress() ][] = time();
|
||||
$expectedMember->failed_logins = $failedLogins;
|
||||
$expectedMember->save();
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
// Account is locked. Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have a member, check the cookies */
|
||||
/* If we still don't have a member, check the cookies */
|
||||
$device = NULL;
|
||||
if ( !$this->member->member_id and isset( \IPS\Request::i()->cookie['device_key'] ) and isset( \IPS\Request::i()->cookie['member_id'] ) and isset( \IPS\Request::i()->cookie['login_key'] ) )
|
||||
{
|
||||
@@ -148,7 +227,7 @@ class _Front extends \IPS\Session
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
/* ... so log it as a failed login */
|
||||
$failedLogins = is_array( $member->failed_logins ) ? $member->failed_logins : array();
|
||||
$failedLogins = \is_array( $member->failed_logins ) ? $member->failed_logins : array();
|
||||
$failedLogins[ \IPS\Request::i()->ipAddress() ][] = time();
|
||||
$member->failed_logins = $failedLogins;
|
||||
$member->save();
|
||||
@@ -169,7 +248,7 @@ class _Front extends \IPS\Session
|
||||
/* Work out the type */
|
||||
if ( $this->member->member_id )
|
||||
{
|
||||
if ( ( $session and $session['login_type'] === static::LOGIN_TYPE_ANONYMOUS ) or ( $device and $device->anonymous ) OR $this->member->group['g_hide_online_list'] )
|
||||
if ( $this->member->group['g_hide_online_list'] != 2 AND ( ( $session and $session['login_type'] === static::LOGIN_TYPE_ANONYMOUS ) or ( $device and $device->anonymous ) OR $this->member->group['g_hide_online_list'] == 1 ) )
|
||||
{
|
||||
$type = static::LOGIN_TYPE_ANONYMOUS;
|
||||
}
|
||||
@@ -184,6 +263,8 @@ class _Front extends \IPS\Session
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'guestTime', time() );
|
||||
|
||||
$type = $this->userAgent->spider ? static::LOGIN_TYPE_SPIDER : static::LOGIN_TYPE_GUEST;
|
||||
}
|
||||
|
||||
@@ -203,11 +284,11 @@ class _Front extends \IPS\Session
|
||||
'current_appcomponent' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_appcomponent'] : '' ) : '',
|
||||
'current_module' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_module'] : '' ) : '',
|
||||
'current_controller' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_controller'] : NULL ) : NULL,
|
||||
'current_id' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_id'] : NULL ) : intval( \IPS\Request::i()->id ),
|
||||
'current_id' => ( \IPS\Request::i()->isAjax() ) ? ( $session ? $session['current_id'] : NULL ) : \intval( \IPS\Request::i()->id ),
|
||||
'uagent_key' => $this->userAgent->browser ?: '',
|
||||
'uagent_version' => $this->userAgent->browserVersion ?: '',
|
||||
'uagent_type' => $this->userAgent->spider ? 'search' : 'browser',
|
||||
'search_thread_id' => $session ? intval( $session['search_thread_id'] ) : 0,
|
||||
'search_thread_id' => $session ? \intval( $session['search_thread_id'] ) : 0,
|
||||
'search_thread_time' => $session ? $session['search_thread_time'] : 0,
|
||||
'data' => $session ? $session['data'] : '',
|
||||
'location_url' => $session ? $session['location_url'] : NULL,
|
||||
@@ -262,6 +343,11 @@ class _Front extends \IPS\Session
|
||||
*/
|
||||
public function write( $sessionId, $data )
|
||||
{
|
||||
if ( $this->noWriteGuestSession and empty( $_SESSION['forcedWrite'] ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( !isset( $this->data['data'] ) or $data !== $this->data['data'] or $this->data['member_id'] != $this->member->member_id )
|
||||
{
|
||||
$this->save = TRUE;
|
||||
@@ -383,7 +469,7 @@ class _Front extends \IPS\Session
|
||||
$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 );
|
||||
$this->data['current_id'] = \intval( \IPS\Request::i()->id );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,7 +501,7 @@ class _Front extends \IPS\Session
|
||||
$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 );
|
||||
$this->data['current_id'] = \intval( \IPS\Request::i()->id );
|
||||
|
||||
if ( !$this->data['current_appcomponent'] )
|
||||
{
|
||||
@@ -428,7 +514,7 @@ class _Front extends \IPS\Session
|
||||
$groupIds = (string) $groupIds;
|
||||
}
|
||||
|
||||
$groupIds = is_string( $groupIds ) ? explode( ',', $groupIds ) : ( $groupIds ?: NULL );
|
||||
$groupIds = \is_string( $groupIds ) ? explode( ',', $groupIds ) : ( $groupIds ?: NULL );
|
||||
|
||||
$app = \IPS\Application::load( $this->data['current_appcomponent'] );
|
||||
if ( !$app->enabled )
|
||||
@@ -442,7 +528,7 @@ class _Front extends \IPS\Session
|
||||
$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;
|
||||
$this->data['location_permissions'] = ( $groupIds !== NULL ) ? ( \is_string( $groupIds ) ? $groupIds : implode( ',', $groupIds ) ) : NULL;
|
||||
|
||||
$this->save = TRUE;
|
||||
}
|
||||
@@ -496,6 +582,11 @@ class _Front extends \IPS\Session
|
||||
*/
|
||||
public function setType( $type )
|
||||
{
|
||||
if ( $this->data['login_type'] !== $type )
|
||||
{
|
||||
$this->save = TRUE;
|
||||
}
|
||||
|
||||
switch ( $type )
|
||||
{
|
||||
case static::LOGIN_TYPE_MEMBER:
|
||||
@@ -570,4 +661,47 @@ class _Front extends \IPS\Session
|
||||
static::clearSessions( $lifetime );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a session that doesn't require a DB read or write
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function setNoWriteGuestSession()
|
||||
{
|
||||
$this->noWriteGuestSession = TRUE;
|
||||
|
||||
$this->member = new \IPS\Member;
|
||||
|
||||
/* Set data */
|
||||
$this->data = array(
|
||||
'id' => $this->sessionId,
|
||||
'member_name' => '',
|
||||
'seo_name' => '',
|
||||
'member_id' => 0,
|
||||
'ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'browser' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
||||
'running_time' => time(),
|
||||
'login_type' => $this->userAgent->spider ? static::LOGIN_TYPE_SPIDER : static::LOGIN_TYPE_GUEST,
|
||||
'member_group' => \IPS\Settings::i()->guest_group,
|
||||
'current_appcomponent' => '',
|
||||
'current_module' => '',
|
||||
'current_controller' => NULL,
|
||||
'current_id' => \intval( \IPS\Request::i()->id ),
|
||||
'uagent_key' => $this->userAgent->browser ?: '',
|
||||
'uagent_version' => $this->userAgent->browserVersion ?: '',
|
||||
'uagent_type' => $this->userAgent->spider ? 'search' : 'browser',
|
||||
'search_thread_id' => 0,
|
||||
'search_thread_time' => 0,
|
||||
'data' => '',
|
||||
'location_url' => NULL,
|
||||
'location_lang' => NULL,
|
||||
'location_data' => NULL,
|
||||
'location_permissions' => NULL,
|
||||
'theme_id' => isset( \IPS\Request::i()->cookie['theme'] ) ? \IPS\Request::i()->cookie['theme'] : 0,
|
||||
'in_editor' => 0,
|
||||
);
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user