299 lines
6.2 KiB
PHP
299 lines
6.2 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @defgroup session Session
|
|
* Implements session concerns such as the session manager, session objects, etc.
|
|
*/
|
|
|
|
/**
|
|
* @file classes/session/Session.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class Session
|
|
*
|
|
* @ingroup session
|
|
*
|
|
* @see SessionDAO
|
|
*
|
|
* @brief Maintains user state information from one request to the next.
|
|
*/
|
|
|
|
namespace PKP\session;
|
|
|
|
use APP\facades\Repo;
|
|
use PKP\config\Config;
|
|
use PKP\user\User;
|
|
|
|
class Session extends \PKP\core\DataObject
|
|
{
|
|
/** @var User User object associated with this session */
|
|
public $user;
|
|
|
|
|
|
/**
|
|
* Get a session variable's value.
|
|
*
|
|
* @param string $key
|
|
*/
|
|
public function getSessionVar($key)
|
|
{
|
|
return $_SESSION[$key] ?? null;
|
|
}
|
|
|
|
/**
|
|
* Get a session variable's value.
|
|
*
|
|
* @param string $key
|
|
*/
|
|
public function setSessionVar($key, $value)
|
|
{
|
|
$_SESSION[$key] = $value;
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Unset (delete) a session variable.
|
|
*
|
|
* @param string $key
|
|
*/
|
|
public function unsetSessionVar($key)
|
|
{
|
|
if (isset($_SESSION[$key])) {
|
|
unset($_SESSION[$key]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get/set methods
|
|
//
|
|
|
|
/**
|
|
* Get user ID (0 if anonymous user).
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getUserId()
|
|
{
|
|
return $this->getData('userId');
|
|
}
|
|
|
|
/**
|
|
* Set user ID.
|
|
*
|
|
* @param ?int $userId
|
|
*/
|
|
public function setUserId($userId)
|
|
{
|
|
if (!isset($userId) || empty($userId)) {
|
|
$this->user = null;
|
|
$userId = null;
|
|
} elseif ($userId != $this->getData('userId')) {
|
|
$this->user = Repo::user()->get($userId);
|
|
if (!isset($this->user)) {
|
|
$userId = null;
|
|
}
|
|
}
|
|
$this->setData('userId', $userId);
|
|
}
|
|
|
|
/**
|
|
* Get IP address.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getIpAddress()
|
|
{
|
|
return $this->getData('ipAddress');
|
|
}
|
|
|
|
/**
|
|
* Set IP address.
|
|
*
|
|
* @param string $ipAddress
|
|
*/
|
|
public function setIpAddress($ipAddress)
|
|
{
|
|
$this->setData('ipAddress', $ipAddress);
|
|
}
|
|
|
|
/**
|
|
* Get user agent.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getUserAgent()
|
|
{
|
|
return $this->getData('userAgent');
|
|
}
|
|
|
|
/**
|
|
* Set user agent.
|
|
*
|
|
* @param string $userAgent
|
|
*/
|
|
public function setUserAgent($userAgent)
|
|
{
|
|
$this->setData('userAgent', $userAgent);
|
|
}
|
|
|
|
/**
|
|
* Get time (in seconds) since session was created.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getSecondsCreated()
|
|
{
|
|
return $this->getData('created');
|
|
}
|
|
|
|
/**
|
|
* Set time (in seconds) since session was created.
|
|
*
|
|
* @param int $created
|
|
*/
|
|
public function setSecondsCreated($created)
|
|
{
|
|
$this->setData('created', $created);
|
|
}
|
|
|
|
/**
|
|
* Get time (in seconds) since session was last used.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getSecondsLastUsed()
|
|
{
|
|
return $this->getData('lastUsed');
|
|
}
|
|
|
|
/**
|
|
* Set time (in seconds) since session was last used.
|
|
*
|
|
* @param int $lastUsed
|
|
*/
|
|
public function setSecondsLastUsed($lastUsed)
|
|
{
|
|
$this->setData('lastUsed', $lastUsed);
|
|
}
|
|
|
|
/**
|
|
* Check if session is to be saved across browser sessions.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function getRemember()
|
|
{
|
|
return $this->getData('remember');
|
|
}
|
|
|
|
/**
|
|
* Set whether session is to be saved across browser sessions.
|
|
*
|
|
* @param bool $remember
|
|
*/
|
|
public function setRemember($remember)
|
|
{
|
|
$this->setData('remember', $remember);
|
|
}
|
|
|
|
/**
|
|
* Get all session parameters.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getSessionData()
|
|
{
|
|
return $this->getData('data');
|
|
}
|
|
|
|
/**
|
|
* Set session parameters.
|
|
*
|
|
* @param string $data
|
|
*/
|
|
public function setSessionData($data)
|
|
{
|
|
$this->setData('data', $data);
|
|
}
|
|
|
|
/**
|
|
* Get the domain with which the session is registered
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDomain()
|
|
{
|
|
return $this->getData('domain');
|
|
}
|
|
|
|
/**
|
|
* Set the domain with which the session is registered
|
|
*
|
|
* @param string $data
|
|
*/
|
|
public function setDomain($data)
|
|
{
|
|
$this->setData('domain', $data);
|
|
}
|
|
|
|
/**
|
|
* Get user associated with this session (null if anonymous user).
|
|
*
|
|
* @return User
|
|
*/
|
|
public function &getUser()
|
|
{
|
|
return $this->user;
|
|
}
|
|
|
|
/**
|
|
* Get a usable CSRF token (generating if necessary).
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCSRFToken()
|
|
{
|
|
$csrf = $this->getSessionVar('csrf');
|
|
if (!is_array($csrf) || time() > $csrf['timestamp'] + (60 * 60)) { // 1 hour token expiry
|
|
// Generate random data
|
|
if (function_exists('openssl_random_pseudo_bytes')) {
|
|
$data = openssl_random_pseudo_bytes(128);
|
|
} elseif (function_exists('random_bytes')) {
|
|
$data = random_bytes(128);
|
|
} else {
|
|
$data = sha1(random_int(0, PHP_INT_MAX));
|
|
}
|
|
|
|
// Hash the data
|
|
$token = null;
|
|
$salt = Config::getVar('security', 'salt');
|
|
$algos = hash_algos();
|
|
foreach (['sha256', 'sha1', 'md5'] as $algo) {
|
|
if (in_array($algo, $algos)) {
|
|
$token = hash_hmac($algo, $data, $salt);
|
|
}
|
|
}
|
|
if (!$token) {
|
|
$token = md5($data . $salt);
|
|
}
|
|
|
|
$csrf = $this->setSessionVar('csrf', [
|
|
'timestamp' => time(),
|
|
'token' => $token,
|
|
]);
|
|
} else {
|
|
// Extend timeout of CSRF token
|
|
$csrf['timestamp'] = time();
|
|
$this->setSessionVar('csrf', $csrf);
|
|
}
|
|
return $csrf['token'];
|
|
}
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\session\Session', '\Session');
|
|
}
|