diff options
author | Frédéric Guillot <fred@kanboard.net> | 2017-12-06 16:19:11 -0800 |
---|---|---|
committer | Frédéric Guillot <fguillot@apple.com> | 2017-12-12 15:04:28 -0800 |
commit | ccd177ada6823c27a6408427f19c238fd701c39e (patch) | |
tree | 9846c792bd4c4f9318768f00db0e8f00cc25954b /app | |
parent | 421531bd4f0af6a26e0b7971e23d5af1d5cf7d05 (diff) |
Store PHP sessions in the database
Diffstat (limited to 'app')
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); } |