summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrédéric Guillot <fred@kanboard.net>2017-12-06 16:19:11 -0800
committerFrédéric Guillot <fguillot@apple.com>2017-12-12 15:04:28 -0800
commitccd177ada6823c27a6408427f19c238fd701c39e (patch)
tree9846c792bd4c4f9318768f00db0e8f00cc25954b /app
parent421531bd4f0af6a26e0b7971e23d5af1d5cf7d05 (diff)
Store PHP sessions in the database
Diffstat (limited to 'app')
-rw-r--r--app/Api/Middleware/AuthenticationMiddleware.php2
-rw-r--r--app/Api/Procedure/MeProcedure.php2
-rw-r--r--app/Auth/ApiAccessTokenAuth.php3
-rw-r--r--app/Controller/AuthController.php8
-rw-r--r--app/Controller/CaptchaController.php2
-rw-r--r--app/Controller/TaskListController.php4
-rw-r--r--app/Controller/TwoFactorController.php22
-rw-r--r--app/Core/Base.php1
-rw-r--r--app/Core/Http/OAuth2.php9
-rw-r--r--app/Core/Queue/JobHandler.php3
-rw-r--r--app/Core/Security/AuthenticationManager.php2
-rw-r--r--app/Core/Security/Token.php12
-rw-r--r--app/Core/Session/FlashMessage.php19
-rw-r--r--app/Core/Session/SessionHandler.php70
-rw-r--r--app/Core/Session/SessionManager.php6
-rw-r--r--app/Core/Session/SessionStorage.php92
-rw-r--r--app/Core/User/UserSession.php88
-rw-r--r--app/Helper/SubtaskHelper.php2
-rw-r--r--app/Middleware/AuthenticationMiddleware.php2
-rw-r--r--app/Model/LanguageModel.php6
-rw-r--r--app/Model/TimezoneModel.php6
-rw-r--r--app/Schema/Mysql.php12
-rw-r--r--app/Schema/Postgres.php11
-rw-r--r--app/Schema/Sqlite.php11
-rw-r--r--app/ServiceProvider/SessionProvider.php5
-rw-r--r--app/Subscriber/AuthSubscriber.php2
-rw-r--r--app/Subscriber/BootstrapSubscriber.php2
-rw-r--r--app/Validator/AuthValidator.php4
-rw-r--r--app/Validator/PasswordResetValidator.php6
-rw-r--r--app/functions.php45
30 files changed, 274 insertions, 185 deletions
diff --git a/app/Api/Middleware/AuthenticationMiddleware.php b/app/Api/Middleware/AuthenticationMiddleware.php
index d2910589..22a3558b 100644
--- a/app/Api/Middleware/AuthenticationMiddleware.php
+++ b/app/Api/Middleware/AuthenticationMiddleware.php
@@ -28,7 +28,7 @@ class AuthenticationMiddleware extends Base implements MiddlewareInterface
public function execute($username, $password, $procedureName)
{
$this->dispatcher->dispatch('app.bootstrap');
- $this->sessionStorage->scope = 'API';
+ session_set('scope', 'API');
if ($this->isUserAuthenticated($username, $password)) {
$this->userSession->initialize($this->userCacheDecorator->getByUsername($username));
diff --git a/app/Api/Procedure/MeProcedure.php b/app/Api/Procedure/MeProcedure.php
index 5a64cdb3..3ccba0e1 100644
--- a/app/Api/Procedure/MeProcedure.php
+++ b/app/Api/Procedure/MeProcedure.php
@@ -12,7 +12,7 @@ class MeProcedure extends BaseProcedure
{
public function getMe()
{
- return $this->sessionStorage->user;
+ return session_get('user');
}
public function getMyDashboard()
diff --git a/app/Auth/ApiAccessTokenAuth.php b/app/Auth/ApiAccessTokenAuth.php
index 12ab21a7..88e16866 100644
--- a/app/Auth/ApiAccessTokenAuth.php
+++ b/app/Auth/ApiAccessTokenAuth.php
@@ -58,8 +58,7 @@ class ApiAccessTokenAuth extends Base implements PasswordAuthenticationProviderI
*/
public function authenticate()
{
- if (! isset($this->sessionStorage->scope) || $this->sessionStorage->scope !== 'API') {
- $this->logger->debug(__METHOD__.': Authentication provider skipped because invalid scope');
+ if (session_get('scope') !== 'API') {
return false;
}
diff --git a/app/Controller/AuthController.php b/app/Controller/AuthController.php
index d1fba92c..06bcd913 100644
--- a/app/Controller/AuthController.php
+++ b/app/Controller/AuthController.php
@@ -40,7 +40,7 @@ class AuthController extends BaseController
public function check()
{
$values = $this->request->getValues();
- $this->sessionStorage->hasRememberMe = ! empty($values['remember_me']);
+ session_set('hasRememberMe', ! empty($values['remember_me']));
list($valid, $errors) = $this->authValidator->validateForm($values);
if ($valid) {
@@ -72,9 +72,9 @@ class AuthController extends BaseController
*/
private function redirectAfterLogin()
{
- if (isset($this->sessionStorage->redirectAfterLogin) && ! empty($this->sessionStorage->redirectAfterLogin) && ! filter_var($this->sessionStorage->redirectAfterLogin, FILTER_VALIDATE_URL)) {
- $redirect = $this->sessionStorage->redirectAfterLogin;
- unset($this->sessionStorage->redirectAfterLogin);
+ if (session_exists('redirectAfterLogin') && ! filter_var(session_get('redirectAfterLogin'), FILTER_VALIDATE_URL)) {
+ $redirect = session_get('redirectAfterLogin');
+ session_remove('redirectAfterLogin');
$this->response->redirect($redirect);
} else {
$this->response->redirect($this->helper->url->to('DashboardController', 'show'));
diff --git a/app/Controller/CaptchaController.php b/app/Controller/CaptchaController.php
index 43b2f823..5b4ea61b 100644
--- a/app/Controller/CaptchaController.php
+++ b/app/Controller/CaptchaController.php
@@ -23,7 +23,7 @@ class CaptchaController extends BaseController
$builder = new CaptchaBuilder;
$builder->build();
- $this->sessionStorage->captcha = $builder->getPhrase();
+ session_set('captcha', $builder->getPhrase());
$builder->output();
}
}
diff --git a/app/Controller/TaskListController.php b/app/Controller/TaskListController.php
index f2f2f6e5..f2482f22 100644
--- a/app/Controller/TaskListController.php
+++ b/app/Controller/TaskListController.php
@@ -24,9 +24,9 @@ class TaskListController extends BaseController
$search = $this->helper->projectHeader->getSearchQuery($project);
if ($this->request->getIntegerParam('show_subtasks')) {
- $this->sessionStorage->subtaskListToggle = true;
+ session_set('subtaskListToggle', true);
} elseif ($this->request->getIntegerParam('hide_subtasks')) {
- $this->sessionStorage->subtaskListToggle = false;
+ session_set('subtaskListToggle', false);
}
if ($this->userSession->hasSubtaskListActivated()) {
diff --git a/app/Controller/TwoFactorController.php b/app/Controller/TwoFactorController.php
index 80f89fbd..5f60e946 100644
--- a/app/Controller/TwoFactorController.php
+++ b/app/Controller/TwoFactorController.php
@@ -36,7 +36,7 @@ class TwoFactorController extends UserViewController
{
$user = $this->getUser();
$this->checkCurrentUser($user);
- unset($this->sessionStorage->twoFactorSecret);
+ session_remove('twoFactorSecret');
$this->response->html($this->helper->layout->user('twofactor/index', array(
'user' => $user,
@@ -57,17 +57,17 @@ class TwoFactorController extends UserViewController
$label = $user['email'] ?: $user['username'];
$provider = $this->authenticationManager->getPostAuthenticationProvider();
- if (! isset($this->sessionStorage->twoFactorSecret)) {
+ if (! session_exists('twoFactorSecret')) {
$provider->generateSecret();
$provider->beforeCode();
- $this->sessionStorage->twoFactorSecret = $provider->getSecret();
+ session_set('twoFactorSecret', $provider->getSecret());
} else {
- $provider->setSecret($this->sessionStorage->twoFactorSecret);
+ $provider->setSecret(session_get('twoFactorSecret'));
}
$this->response->html($this->helper->layout->user('twofactor/show', array(
'user' => $user,
- 'secret' => $this->sessionStorage->twoFactorSecret,
+ 'secret' => session_get('twoFactorSecret'),
'key_url' => $provider->getKeyUrl($label),
)));
}
@@ -86,7 +86,7 @@ class TwoFactorController extends UserViewController
$provider = $this->authenticationManager->getPostAuthenticationProvider();
$provider->setCode(empty($values['code']) ? '' : $values['code']);
- $provider->setSecret($this->sessionStorage->twoFactorSecret);
+ $provider->setSecret(session_get('twoFactorSecret'));
if ($provider->authenticate()) {
$this->flash->success(t('The two factor authentication code is valid.'));
@@ -97,7 +97,7 @@ class TwoFactorController extends UserViewController
'twofactor_secret' => $this->authenticationManager->getPostAuthenticationProvider()->getSecret(),
));
- unset($this->sessionStorage->twoFactorSecret);
+ session_remove('twoFactorSecret');
$this->userSession->disablePostAuthentication();
$this->response->redirect($this->helper->url->to('TwoFactorController', 'index', array('user_id' => $user['id'])), true);
@@ -168,10 +168,10 @@ class TwoFactorController extends UserViewController
*/
public function code()
{
- if (! isset($this->sessionStorage->twoFactorBeforeCodeCalled)) {
+ if (! session_exists('twoFactorBeforeCodeCalled')) {
$provider = $this->authenticationManager->getPostAuthenticationProvider();
$provider->beforeCode();
- $this->sessionStorage->twoFactorBeforeCodeCalled = true;
+ session_set('twoFactorBeforeCodeCalled', true);
}
$this->response->html($this->helper->layout->app('twofactor/check', array(
@@ -210,10 +210,10 @@ class TwoFactorController extends UserViewController
*/
public function qrcode()
{
- if (isset($this->sessionStorage->twoFactorSecret)) {
+ if (session_exists('twoFactorSecret')) {
$user = $this->getUser();
$provider = $this->authenticationManager->getPostAuthenticationProvider();
- $provider->setSecret($this->sessionStorage->twoFactorSecret);
+ $provider->setSecret(session_get('twoFactorSecret'));
$url = $provider->getKeyUrl($user['email'] ?: $user['username']);
if (! empty($url)) {
diff --git a/app/Core/Base.php b/app/Core/Base.php
index a36828c4..709327a7 100644
--- a/app/Core/Base.php
+++ b/app/Core/Base.php
@@ -48,7 +48,6 @@ use Pimple\Container;
* @property \Kanboard\Core\Security\Token $token
* @property \Kanboard\Core\Session\FlashMessage $flash
* @property \Kanboard\Core\Session\SessionManager $sessionManager
- * @property \Kanboard\Core\Session\SessionStorage $sessionStorage
* @property \Kanboard\Core\User\Avatar\AvatarManager $avatarManager
* @property \Kanboard\Core\User\GroupSync $groupSync
* @property \Kanboard\Core\User\UserProfile $userProfile
diff --git a/app/Core/Http/OAuth2.php b/app/Core/Http/OAuth2.php
index 211ca5b4..f47927e1 100644
--- a/app/Core/Http/OAuth2.php
+++ b/app/Core/Http/OAuth2.php
@@ -53,11 +53,11 @@ class OAuth2 extends Base
*/
public function getState()
{
- if (! isset($this->sessionStorage->oauthState) || empty($this->sessionStorage->oauthState)) {
- $this->sessionStorage->oauthState = $this->token->getToken();
+ if (! session_exists('oauthState')) {
+ session_set('oauthState', $this->token->getToken());
}
- return $this->sessionStorage->oauthState;
+ return session_get('oauthState');
}
/**
@@ -140,11 +140,12 @@ class OAuth2 extends Base
* @access public
* @param string $token
* @param string $type
- * @return string
+ * @return $this
*/
public function setAccessToken($token, $type = 'bearer')
{
$this->accessToken = $token;
$this->tokenType = $type;
+ return $this;
}
}
diff --git a/app/Core/Queue/JobHandler.php b/app/Core/Queue/JobHandler.php
index 11c1fb69..d7e7d099 100644
--- a/app/Core/Queue/JobHandler.php
+++ b/app/Core/Queue/JobHandler.php
@@ -67,8 +67,7 @@ class JobHandler extends Base
*/
protected function prepareJobSession($user_id)
{
- $session = array();
- $this->sessionStorage->setStorage($session);
+ session_flush();
if ($user_id > 0) {
$user = $this->userModel->getById($user_id);
diff --git a/app/Core/Security/AuthenticationManager.php b/app/Core/Security/AuthenticationManager.php
index b1ba76cf..e7a3c8d4 100644
--- a/app/Core/Security/AuthenticationManager.php
+++ b/app/Core/Security/AuthenticationManager.php
@@ -72,7 +72,7 @@ class AuthenticationManager extends Base
foreach ($this->filterProviders('SessionCheckProviderInterface') as $provider) {
if (! $provider->isValidSession()) {
$this->logger->debug('Invalidate session for '.$this->userSession->getUsername());
- $this->sessionStorage->flush();
+ session_flush();
$this->preAuthentication();
return false;
}
diff --git a/app/Core/Security/Token.php b/app/Core/Security/Token.php
index cbd784a8..9b0c5769 100644
--- a/app/Core/Security/Token.php
+++ b/app/Core/Security/Token.php
@@ -32,12 +32,12 @@ class Token extends Base
*/
public function getCSRFToken()
{
- if (! isset($this->sessionStorage->csrf)) {
- $this->sessionStorage->csrf = array();
+ if (! session_exists('csrf')) {
+ session_set('csrf', []);
}
$nonce = self::getToken();
- $this->sessionStorage->csrf[$nonce] = true;
+ session_merge('csrf', [$nonce => true]);
return $nonce;
}
@@ -51,8 +51,10 @@ class Token extends Base
*/
public function validateCSRFToken($token)
{
- if (isset($this->sessionStorage->csrf[$token])) {
- unset($this->sessionStorage->csrf[$token]);
+ $tokens = session_get('csrf');
+ if (isset($tokens[$token])) {
+ unset($tokens[$token]);
+ session_set('csrf', $tokens);
return true;
}
diff --git a/app/Core/Session/FlashMessage.php b/app/Core/Session/FlashMessage.php
index e02d056d..037717c2 100644
--- a/app/Core/Session/FlashMessage.php
+++ b/app/Core/Session/FlashMessage.php
@@ -7,7 +7,7 @@ use Kanboard\Core\Base;
/**
* Session Flash Message
*
- * @package session
+ * @package Kanboard\Core\Session
* @author Frederic Guillot
*/
class FlashMessage extends Base
@@ -43,11 +43,11 @@ class FlashMessage extends Base
*/
public function setMessage($key, $message)
{
- if (! isset($this->sessionStorage->flash)) {
- $this->sessionStorage->flash = array();
+ if (! session_exists('flash')) {
+ session_set('flash', []);
}
- $this->sessionStorage->flash[$key] = $message;
+ session_merge('flash', [$key => $message]);
}
/**
@@ -61,9 +61,14 @@ class FlashMessage extends Base
{
$message = '';
- if (isset($this->sessionStorage->flash[$key])) {
- $message = $this->sessionStorage->flash[$key];
- unset($this->sessionStorage->flash[$key]);
+ if (session_exists('flash')) {
+ $messages = session_get('flash');
+
+ if (isset($messages[$key])) {
+ $message = $messages[$key];
+ unset($messages[$key]);
+ session_set('flash', $messages);
+ }
}
return $message;
diff --git a/app/Core/Session/SessionHandler.php b/app/Core/Session/SessionHandler.php
new file mode 100644
index 00000000..135e0ab0
--- /dev/null
+++ b/app/Core/Session/SessionHandler.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Kanboard\Core\Session;
+
+use PicoDb\Database;
+use SessionHandlerInterface;
+
+/**
+ * Class SessionHandler
+ *
+ * @package Kanboard\Core\Session
+ */
+class SessionHandler implements SessionHandlerInterface
+{
+ const TABLE = 'sessions';
+
+ /**
+ * @var Database
+ */
+ private $db;
+
+ public function __construct(Database $db)
+ {
+ $this->db = $db;
+ }
+
+ public function close()
+ {
+ return true;
+ }
+
+ public function destroy($sessionID)
+ {
+ return $this->db->table(self::TABLE)->eq('id', $sessionID)->remove();
+ }
+
+ public function gc($maxlifetime)
+ {
+ return $this->db->table(self::TABLE)->lt('expire_at', time())->remove();
+ }
+
+ public function open($savePath, $name)
+ {
+ return true;
+ }
+
+ public function read($sessionID)
+ {
+ $result = $this->db->table(self::TABLE)->eq('id', $sessionID)->findOneColumn('data');
+ return $result ?: '';
+ }
+
+ public function write($sessionID, $data)
+ {
+ $lifetime = time() + (ini_get('session.gc_maxlifetime') ?: 1440);
+
+ if ($this->db->table(self::TABLE)->eq('id', $sessionID)->exists()) {
+ return $this->db->table(self::TABLE)->eq('id', $sessionID)->update(array(
+ 'expire_at' => $lifetime,
+ 'data' => $data,
+ ));
+ }
+
+ return $this->db->table(self::TABLE)->insert(array(
+ 'id' => $sessionID,
+ 'expire_at' => $lifetime,
+ 'data' => $data,
+ ));
+ }
+}
diff --git a/app/Core/Session/SessionManager.php b/app/Core/Session/SessionManager.php
index 4f9f2c0a..e3d5cf15 100644
--- a/app/Core/Session/SessionManager.php
+++ b/app/Core/Session/SessionManager.php
@@ -7,7 +7,7 @@ use Kanboard\Core\Base;
/**
* Session Manager
*
- * @package session
+ * @package Kanboard\Core\Session
* @author Frederic Guillot
*/
class SessionManager extends Base
@@ -38,6 +38,8 @@ class SessionManager extends Base
*/
public function open()
{
+ session_set_save_handler(new SessionHandler($this->db), true);
+
$this->configure();
if (ini_get('session.auto_start') == 1) {
@@ -46,8 +48,6 @@ class SessionManager extends Base
session_name('KB_SID');
session_start();
-
- $this->sessionStorage->setStorage($_SESSION);
}
/**
diff --git a/app/Core/Session/SessionStorage.php b/app/Core/Session/SessionStorage.php
deleted file mode 100644
index bb6771f1..00000000
--- a/app/Core/Session/SessionStorage.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-namespace Kanboard\Core\Session;
-
-/**
- * Session Storage
- *
- * @package session
- * @author Frederic Guillot
- *
- * @property array $user
- * @property array $flash
- * @property array $csrf
- * @property array $postAuthenticationValidated
- * @property array $filters
- * @property string $redirectAfterLogin
- * @property string $captcha
- * @property string $commentSorting
- * @property bool $hasSubtaskInProgress
- * @property bool $hasRememberMe
- * @property bool $subtaskListToggle
- * @property string $scope
- * @property bool $twoFactorBeforeCodeCalled
- * @property string $twoFactorSecret
- * @property string $oauthState
- * @property int $smsTwoFactorSecret
- */
-class SessionStorage
-{
- /**
- * Pointer to external storage
- *
- * @access private
- * @var array
- */
- private $storage = array();
-
- /**
- * Set external storage
- *
- * @access public
- * @param array $storage External session storage (example: $_SESSION)
- */
- public function setStorage(array &$storage)
- {
- $this->storage =& $storage;
-
- // Load dynamically existing session variables into object properties
- foreach ($storage as $key => $value) {
- $this->$key = $value;
- }
- }
-
- /**
- * Get all session variables
- *
- * @access public
- * @return array
- */
- public function getAll()
- {
- $session = get_object_vars($this);
- unset($session['storage']);
-
- return $session;
- }
-
- /**
- * Flush session data
- *
- * @access public
- */
- public function flush()
- {
- $session = get_object_vars($this);
- unset($session['storage']);
-
- foreach (array_keys($session) as $property) {
- unset($this->$property);
- }
- }
-
- /**
- * Copy class properties to external storage
- *
- * @access public
- */
- public function __destruct()
- {
- $this->storage = $this->getAll();
- }
-}
diff --git a/app/Core/User/UserSession.php b/app/Core/User/UserSession.php
index f3f7359a..0206be80 100644
--- a/app/Core/User/UserSession.php
+++ b/app/Core/User/UserSession.php
@@ -44,8 +44,8 @@ class UserSession extends Base
$user['is_ldap_user'] = isset($user['is_ldap_user']) ? (bool) $user['is_ldap_user'] : false;
$user['twofactor_activated'] = isset($user['twofactor_activated']) ? (bool) $user['twofactor_activated'] : false;
- $this->sessionStorage->user = $user;
- $this->sessionStorage->postAuthenticationValidated = false;
+ session_set('user', $user);
+ session_set('postAuthenticationValidated', false);
}
/**
@@ -56,7 +56,7 @@ class UserSession extends Base
*/
public function getAll()
{
- return $this->sessionStorage->user;
+ return session_get('user');
}
/**
@@ -67,7 +67,11 @@ class UserSession extends Base
*/
public function getRole()
{
- return $this->sessionStorage->user['role'];
+ if (! $this->isLogged()) {
+ return '';
+ }
+
+ return session_get('user')['role'];
}
/**
@@ -78,7 +82,7 @@ class UserSession extends Base
*/
public function isPostAuthenticationValidated()
{
- return isset($this->sessionStorage->postAuthenticationValidated) && $this->sessionStorage->postAuthenticationValidated === true;
+ return session_is_true('postAuthenticationValidated');
}
/**
@@ -88,7 +92,7 @@ class UserSession extends Base
*/
public function validatePostAuthentication()
{
- $this->sessionStorage->postAuthenticationValidated = true;
+ session_set('postAuthenticationValidated', true);
}
/**
@@ -99,7 +103,11 @@ class UserSession extends Base
*/
public function hasPostAuthentication()
{
- return isset($this->sessionStorage->user['twofactor_activated']) && $this->sessionStorage->user['twofactor_activated'] === true;
+ if (! $this->isLogged()) {
+ return false;
+ }
+
+ return session_get('user')['twofactor_activated'] === true;
}
/**
@@ -109,7 +117,7 @@ class UserSession extends Base
*/
public function disablePostAuthentication()
{
- $this->sessionStorage->user['twofactor_activated'] = false;
+ session_merge('user', ['twofactor_activated' => false]);
}
/**
@@ -120,7 +128,7 @@ class UserSession extends Base
*/
public function isAdmin()
{
- return isset($this->sessionStorage->user['role']) && $this->sessionStorage->user['role'] === Role::APP_ADMIN;
+ return $this->getRole() === Role::APP_ADMIN;
}
/**
@@ -131,7 +139,11 @@ class UserSession extends Base
*/
public function getId()
{
- return isset($this->sessionStorage->user['id']) ? (int) $this->sessionStorage->user['id'] : 0;
+ if (! $this->isLogged()) {
+ return 0;
+ }
+
+ return session_get('user')['id'];
}
/**
@@ -142,7 +154,41 @@ class UserSession extends Base
*/
public function getUsername()
{
- return isset($this->sessionStorage->user['username']) ? $this->sessionStorage->user['username'] : '';
+ if (! $this->isLogged()) {
+ return '';
+ }
+
+ return session_get('user')['username'];
+ }
+
+ /**
+ * Get user language
+ *
+ * @access public
+ * @return string
+ */
+ public function getLanguage()
+ {
+ if (! $this->isLogged()) {
+ return '';
+ }
+
+ return session_get('user')['language'];
+ }
+
+ /**
+ * Get user timezone
+ *
+ * @access public
+ * @return string
+ */
+ public function getTimezone()
+ {
+ if (! $this->isLogged()) {
+ return '';
+ }
+
+ return session_get('user')['timezone'];
}
/**
@@ -153,7 +199,7 @@ class UserSession extends Base
*/
public function hasSubtaskListActivated()
{
- return isset($this->sessionStorage->subtaskListToggle) && ! empty($this->sessionStorage->subtaskListToggle);
+ return session_is_true('subtaskListToggle');
}
/**
@@ -164,30 +210,34 @@ class UserSession extends Base
*/
public function isLogged()
{
- return isset($this->sessionStorage->user) && ! empty($this->sessionStorage->user);
+ return session_exists('user') && session_get('user') !== [];
}
/**
* Get project filters from the session
*
* @access public
- * @param integer $project_id
+ * @param integer $projectID
* @return string
*/
- public function getFilters($project_id)
+ public function getFilters($projectID)
{
- return ! empty($this->sessionStorage->filters[$project_id]) ? $this->sessionStorage->filters[$project_id] : 'status:open';
+ if (! session_exists('filters:'.$projectID)) {
+ return 'status:open';
+ }
+
+ return session_get('filters:'.$projectID);
}
/**
* Save project filters in the session
*
* @access public
- * @param integer $project_id
+ * @param integer $projectID
* @param string $filters
*/
- public function setFilters($project_id, $filters)
+ public function setFilters($projectID, $filters)
{
- $this->sessionStorage->filters[$project_id] = $filters;
+ session_set('filters:'.$projectID, $filters);
}
}
diff --git a/app/Helper/SubtaskHelper.php b/app/Helper/SubtaskHelper.php
index 67875a63..19cdf97a 100644
--- a/app/Helper/SubtaskHelper.php
+++ b/app/Helper/SubtaskHelper.php
@@ -20,7 +20,7 @@ class SubtaskHelper extends Base
*/
public function hasSubtaskInProgress()
{
- return isset($this->sessionStorage->hasSubtaskInProgress) && $this->sessionStorage->hasSubtaskInProgress;
+ return session_is_true('hasSubtaskInProgress');
}
/**
diff --git a/app/Middleware/AuthenticationMiddleware.php b/app/Middleware/AuthenticationMiddleware.php
index 499843fd..54652e57 100644
--- a/app/Middleware/AuthenticationMiddleware.php
+++ b/app/Middleware/AuthenticationMiddleware.php
@@ -38,7 +38,7 @@ class AuthenticationMiddleware extends BaseMiddleware
if ($this->request->isAjax()) {
$this->response->text('Not Authorized', 401);
} else {
- $this->sessionStorage->redirectAfterLogin = $this->request->getUri();
+ session_set('redirectAfterLogin', $this->request->getUri());
$this->response->redirect($this->helper->url->to('AuthController', 'login'));
}
}
diff --git a/app/Model/LanguageModel.php b/app/Model/LanguageModel.php
index 6d46a2fa..09893690 100644
--- a/app/Model/LanguageModel.php
+++ b/app/Model/LanguageModel.php
@@ -174,11 +174,7 @@ class LanguageModel extends Base
*/
public function getCurrentLanguage()
{
- if ($this->userSession->isLogged() && ! empty($this->sessionStorage->user['language'])) {
- return $this->sessionStorage->user['language'];
- }
-
- return $this->configModel->get('application_language', 'en_US');
+ return $this->userSession->getLanguage() ?: $this->configModel->get('application_language', 'en_US');
}
/**
diff --git a/app/Model/TimezoneModel.php b/app/Model/TimezoneModel.php
index 8b3e895a..ef6afc6a 100644
--- a/app/Model/TimezoneModel.php
+++ b/app/Model/TimezoneModel.php
@@ -39,11 +39,7 @@ class TimezoneModel extends Base
*/
public function getCurrentTimezone()
{
- if ($this->userSession->isLogged() && ! empty($this->sessionStorage->user['timezone'])) {
- return $this->sessionStorage->user['timezone'];
- }
-
- return $this->configModel->get('application_timezone', 'UTC');
+ return $this->userSession->getTimezone() ?: $this->configModel->get('application_timezone', 'UTC');
}
/**
diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php
index 5709b86d..32171d17 100644
--- a/app/Schema/Mysql.php
+++ b/app/Schema/Mysql.php
@@ -8,7 +8,17 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 126;
+const VERSION = 127;
+
+function version_127(PDO $pdo)
+{
+ $pdo->exec("CREATE TABLE sessions (
+ id VARCHAR(255) NOT NULL,
+ expire_at INT NOT NULL,
+ data LONGTEXT,
+ PRIMARY KEY(id)
+ ) ENGINE=InnoDB CHARSET=utf8");
+}
function version_126(PDO $pdo)
{
diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php
index bf9acaa7..8d5a68e5 100644
--- a/app/Schema/Postgres.php
+++ b/app/Schema/Postgres.php
@@ -8,7 +8,16 @@ use PDO;
use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
-const VERSION = 105;
+const VERSION = 106;
+
+function version_106(PDO $pdo)
+{
+ $pdo->exec("CREATE TABLE sessions (
+ id TEXT PRIMARY KEY,
+ expire_at INTEGER NOT NULL,
+ data TEXT DEFAULT ''
+ )");
+}
function version_105(PDO $pdo)
{
diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php
index 70d13b98..e40b2aeb 100644
--- a/app/Schema/Sqlite.php
+++ b/app/Schema/Sqlite.php
@@ -8,7 +8,16 @@ use Kanboard\Core\Security\Token;
use Kanboard\Core\Security\Role;
use PDO;
-const VERSION = 116;
+const VERSION = 117;
+
+function version_117(PDO $pdo)
+{
+ $pdo->exec("CREATE TABLE sessions (
+ id TEXT PRIMARY KEY,
+ expire_at INTEGER NOT NULL,
+ data TEXT DEFAULT ''
+ )");
+}
function version_116(PDO $pdo)
{
diff --git a/app/ServiceProvider/SessionProvider.php b/app/ServiceProvider/SessionProvider.php
index 96dcac2e..82d0c4f3 100644
--- a/app/ServiceProvider/SessionProvider.php
+++ b/app/ServiceProvider/SessionProvider.php
@@ -5,7 +5,6 @@ namespace Kanboard\ServiceProvider;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Kanboard\Core\Session\SessionManager;
-use Kanboard\Core\Session\SessionStorage;
use Kanboard\Core\Session\FlashMessage;
/**
@@ -25,10 +24,6 @@ class SessionProvider implements ServiceProviderInterface
*/
public function register(Container $container)
{
- $container['sessionStorage'] = function() {
- return new SessionStorage;
- };
-
$container['sessionManager'] = function($c) {
return new SessionManager($c);
};
diff --git a/app/Subscriber/AuthSubscriber.php b/app/Subscriber/AuthSubscriber.php
index 0097c407..5f22edab 100644
--- a/app/Subscriber/AuthSubscriber.php
+++ b/app/Subscriber/AuthSubscriber.php
@@ -58,7 +58,7 @@ class AuthSubscriber extends BaseSubscriber implements EventSubscriberInterface
$this->userSession->validatePostAuthentication();
}
- if (isset($this->sessionStorage->hasRememberMe) && $this->sessionStorage->hasRememberMe) {
+ if (session_is_true('hasRememberMe')) {
$session = $this->rememberMeSessionModel->create($this->userSession->getId(), $ipAddress, $userAgent);
$this->rememberMeCookie->write($session['token'], $session['sequence'], $session['expiration']);
}
diff --git a/app/Subscriber/BootstrapSubscriber.php b/app/Subscriber/BootstrapSubscriber.php
index 3618f30f..432f8378 100644
--- a/app/Subscriber/BootstrapSubscriber.php
+++ b/app/Subscriber/BootstrapSubscriber.php
@@ -21,7 +21,7 @@ class BootstrapSubscriber extends BaseSubscriber implements EventSubscriberInter
$this->actionManager->attachEvents();
if ($this->userSession->isLogged()) {
- $this->sessionStorage->hasSubtaskInProgress = $this->subtaskStatusModel->hasSubtaskInProgress($this->userSession->getId());
+ session_set('hasSubtaskInProgress', $this->subtaskStatusModel->hasSubtaskInProgress($this->userSession->getId()));
}
}
diff --git a/app/Validator/AuthValidator.php b/app/Validator/AuthValidator.php
index 25dab430..9abe69f0 100644
--- a/app/Validator/AuthValidator.php
+++ b/app/Validator/AuthValidator.php
@@ -101,11 +101,11 @@ class AuthValidator extends BaseValidator
$errors = array();
if ($this->userLockingModel->hasCaptcha($values['username'])) {
- if (! isset($this->sessionStorage->captcha)) {
+ if (! session_exists('captcha')) {
$result = false;
} else {
$builder = new CaptchaBuilder;
- $builder->setPhrase($this->sessionStorage->captcha);
+ $builder->setPhrase(session_get('captcha'));
$result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : '');
if (! $result) {
diff --git a/app/Validator/PasswordResetValidator.php b/app/Validator/PasswordResetValidator.php
index e44e5206..0a2a3cd6 100644
--- a/app/Validator/PasswordResetValidator.php
+++ b/app/Validator/PasswordResetValidator.php
@@ -69,17 +69,17 @@ class PasswordResetValidator extends BaseValidator
*
* @access protected
* @param array $values Form values
- * @return boolean
+ * @return array
*/
protected function validateCaptcha(array $values)
{
$errors = array();
- if (! isset($this->sessionStorage->captcha)) {
+ if (! session_exists('captcha')) {
$result = false;
} else {
$builder = new CaptchaBuilder;
- $builder->setPhrase($this->sessionStorage->captcha);
+ $builder->setPhrase(session_get('captcha'));
$result = $builder->testPhrase(isset($values['captcha']) ? $values['captcha'] : '');
if (! $result) {
diff --git a/app/functions.php b/app/functions.php
index 94530af8..bb739d0f 100644
--- a/app/functions.php
+++ b/app/functions.php
@@ -2,9 +2,50 @@
use Kanboard\Core\Translator;
-function explode_csv_field($field)
+function session_get($key)
{
- $fields = explode(',', $field);
+ return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
+}
+
+function session_set($key, $value)
+{
+ $_SESSION[$key] = $value;
+}
+
+function session_remove($key)
+{
+ unset($_SESSION[$key]);
+}
+
+function session_exists($key)
+{
+ return isset($_SESSION[$key]);
+}
+
+function session_is_true($key)
+{
+ return isset($_SESSION[$key]) && $_SESSION[$key] === true;
+}
+
+function session_merge($key, array $value)
+{
+ $_SESSION[$key] = array_merge($_SESSION[$key], $value);
+}
+
+function session_flush()
+{
+ $_SESSION = [];
+}
+
+/**
+ * Split CSV string
+ *
+ * @param string $str
+ * @return string[]
+ */
+function explode_csv_field($str)
+{
+ $fields = explode(',', $str);
array_walk($fields, function (&$value) { $value = trim($value); });
return array_filter($fields);
}