Skip to content

Commit

Permalink
Store PHP sessions in the database
Browse files Browse the repository at this point in the history
  • Loading branch information
fguillot authored and Frédéric Guillot committed Dec 12, 2017
1 parent 421531b commit ccd177a
Show file tree
Hide file tree
Showing 58 changed files with 405 additions and 382 deletions.
2 changes: 1 addition & 1 deletion app/Api/Middleware/AuthenticationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion app/Api/Procedure/MeProcedure.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class MeProcedure extends BaseProcedure
{
public function getMe()
{
return $this->sessionStorage->user;
return session_get('user');
}

public function getMyDashboard()
Expand Down
3 changes: 1 addition & 2 deletions app/Auth/ApiAccessTokenAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ public function getName()
*/
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;
}

Expand Down
8 changes: 4 additions & 4 deletions app/Controller/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function login(array $values = array(), array $errors = array())
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) {
Expand Down Expand Up @@ -72,9 +72,9 @@ public function logout()
*/
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'));
Expand Down
2 changes: 1 addition & 1 deletion app/Controller/CaptchaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function image()

$builder = new CaptchaBuilder;
$builder->build();
$this->sessionStorage->captcha = $builder->getPhrase();
session_set('captcha', $builder->getPhrase());
$builder->output();
}
}
4 changes: 2 additions & 2 deletions app/Controller/TaskListController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public function show()
$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()) {
Expand Down
22 changes: 11 additions & 11 deletions app/Controller/TwoFactorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function index()
{
$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,
Expand All @@ -57,17 +57,17 @@ public function show()
$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),
)));
}
Expand All @@ -86,7 +86,7 @@ public function test()

$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.'));
Expand All @@ -97,7 +97,7 @@ public function test()
'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);
Expand Down Expand Up @@ -168,10 +168,10 @@ public function check()
*/
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(
Expand Down Expand Up @@ -210,10 +210,10 @@ public function disable()
*/
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)) {
Expand Down
1 change: 0 additions & 1 deletion app/Core/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
* @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
Expand Down
9 changes: 5 additions & 4 deletions app/Core/Http/OAuth2.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ public function createService($clientId, $secret, $callbackUrl, $authUrl, $token
*/
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');
}

/**
Expand Down Expand Up @@ -140,11 +140,12 @@ public function getAccessToken($code)
* @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;
}
}
3 changes: 1 addition & 2 deletions app/Core/Queue/JobHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ public function executeJob(Job $job)
*/
protected function prepareJobSession($user_id)
{
$session = array();
$this->sessionStorage->setStorage($session);
session_flush();

if ($user_id > 0) {
$user = $this->userModel->getById($user_id);
Expand Down
2 changes: 1 addition & 1 deletion app/Core/Security/AuthenticationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function checkCurrentSession()
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;
}
Expand Down
12 changes: 7 additions & 5 deletions app/Core/Security/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public static function getToken()
*/
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;
}
Expand All @@ -51,8 +51,10 @@ public function getCSRFToken()
*/
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;
}

Expand Down
19 changes: 12 additions & 7 deletions app/Core/Session/FlashMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Session Flash Message
*
* @package session
* @package Kanboard\Core\Session
* @author Frederic Guillot
*/
class FlashMessage extends Base
Expand Down Expand Up @@ -43,11 +43,11 @@ public function failure($message)
*/
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]);
}

/**
Expand All @@ -61,9 +61,14 @@ public function getMessage($key)
{
$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;
Expand Down
70 changes: 70 additions & 0 deletions app/Core/Session/SessionHandler.php
Original file line number Diff line number Diff line change
@@ -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,
));
}
}
6 changes: 3 additions & 3 deletions app/Core/Session/SessionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Session Manager
*
* @package session
* @package Kanboard\Core\Session
* @author Frederic Guillot
*/
class SessionManager extends Base
Expand Down Expand Up @@ -38,6 +38,8 @@ public static function isOpen()
*/
public function open()
{
session_set_save_handler(new SessionHandler($this->db), true);

$this->configure();

if (ini_get('session.auto_start') == 1) {
Expand All @@ -46,8 +48,6 @@ public function open()

session_name('KB_SID');
session_start();

$this->sessionStorage->setStorage($_SESSION);
}

/**
Expand Down
Loading

0 comments on commit ccd177a

Please sign in to comment.