Make session cleanup more robust and tests explicit

This commit is contained in:
Igor Scheller 2023-04-08 14:14:57 +02:00
parent 9f35ebc482
commit bf4a818e01
2 changed files with 41 additions and 35 deletions

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Http\SessionHandlers; namespace Engelsystem\Http\SessionHandlers;
use Engelsystem\Database\Database; use Engelsystem\Database\Database;
use Engelsystem\Helpers\Carbon;
use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\Builder as QueryBuilder;
class DatabaseHandler extends AbstractHandler class DatabaseHandler extends AbstractHandler
@ -32,7 +33,7 @@ class DatabaseHandler extends AbstractHandler
{ {
$values = [ $values = [
'payload' => $data, 'payload' => $data,
'last_activity' => $this->getCurrentTimestamp(), 'last_activity' => Carbon::now(),
]; ];
$session = $this->getQuery() $session = $this->getQuery()
@ -71,11 +72,11 @@ class DatabaseHandler extends AbstractHandler
*/ */
public function gc(int $max_lifetime): int|false public function gc(int $max_lifetime): int|false
{ {
$max_lifetime = config('session.lifetime') * 24 * 60 * 60; $sessionDays = config('session')['lifetime'];
$timestamp = $this->getCurrentTimestamp(-$max_lifetime); $deleteBefore = Carbon::now()->subDays($sessionDays);
return $this->getQuery() return $this->getQuery()
->where('last_activity', '<', $timestamp) ->where('last_activity', '<', $deleteBefore)
->delete(); ->delete();
} }
@ -85,12 +86,4 @@ class DatabaseHandler extends AbstractHandler
->getConnection() ->getConnection()
->table('sessions'); ->table('sessions');
} }
/**
* Format the SQL timestamp
*/
protected function getCurrentTimestamp(int $diff = 0): string
{
return date('Y-m-d H:i:s', strtotime(sprintf('%+d seconds', $diff)));
}
} }

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Http\SessionHandlers; namespace Engelsystem\Test\Unit\Http\SessionHandlers;
use Engelsystem\Config\Config; use Engelsystem\Config\Config;
use Engelsystem\Helpers\Carbon;
use Engelsystem\Http\SessionHandlers\DatabaseHandler; use Engelsystem\Http\SessionHandlers\DatabaseHandler;
use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\HasDatabase;
use Engelsystem\Test\Unit\TestCase; use Engelsystem\Test\Unit\TestCase;
@ -23,12 +24,15 @@ class DatabaseHandlerTest extends TestCase
$handler = new DatabaseHandler($this->database); $handler = new DatabaseHandler($this->database);
$this->assertEquals('', $handler->read('foo')); $this->assertEquals('', $handler->read('foo'));
$this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', CURRENT_TIMESTAMP)"); $this->database->getConnection()
$this->assertEquals('Lorem Ipsum', $handler->read('foo')); ->table('sessions')
->insert([
['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()],
]);
$this->assertEquals('Lorem Ipsum', $handler->read('id-foo'));
} }
/** /**
* @covers \Engelsystem\Http\SessionHandlers\DatabaseHandler::getCurrentTimestamp
* @covers \Engelsystem\Http\SessionHandlers\DatabaseHandler::write * @covers \Engelsystem\Http\SessionHandlers\DatabaseHandler::write
*/ */
public function testWrite(): void public function testWrite(): void
@ -36,12 +40,14 @@ class DatabaseHandlerTest extends TestCase
$handler = new DatabaseHandler($this->database); $handler = new DatabaseHandler($this->database);
foreach (['Lorem Ipsum', 'Dolor Sit!'] as $data) { foreach (['Lorem Ipsum', 'Dolor Sit!'] as $data) {
$this->assertTrue($handler->write('foo', $data)); $this->assertTrue($handler->write('id-foo', $data));
$return = $this->database->select('SELECT * FROM sessions WHERE id = :id', ['id' => 'foo']); $return = $this->database->getConnection()->table('sessions')
->where('id', 'id-foo')
->get();
$this->assertCount(1, $return); $this->assertCount(1, $return);
$return = array_shift($return); $return = $return->first();
$this->assertEquals($data, $return->payload); $this->assertEquals($data, $return->payload);
} }
} }
@ -51,22 +57,26 @@ class DatabaseHandlerTest extends TestCase
*/ */
public function testDestroy(): void public function testDestroy(): void
{ {
$this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', CURRENT_TIMESTAMP)"); $table = $this->database->getConnection()->table('sessions');
$this->database->insert("INSERT INTO sessions VALUES ('bar', 'Dolor Sit', CURRENT_TIMESTAMP)"); $table
->insert([
['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()->subHours(25)],
['id' => 'id-bar', 'payload' => 'Dolor Sit', 'last_activity' => Carbon::now()],
]);
$handler = new DatabaseHandler($this->database); $handler = new DatabaseHandler($this->database);
$this->assertTrue($handler->destroy('batz')); $this->assertTrue($handler->destroy('id-baz'));
$return = $this->database->select('SELECT * FROM sessions'); $return = $table->get();
$this->assertCount(2, $return); $this->assertCount(2, $return);
$this->assertTrue($handler->destroy('bar')); $this->assertTrue($handler->destroy('id-bar'));
$return = $this->database->select('SELECT * FROM sessions'); $return = $table->get();
$this->assertCount(1, $return); $this->assertCount(1, $return);
$return = array_shift($return); $return = $return->first();
$this->assertEquals('foo', $return->id); $this->assertEquals('id-foo', $return->id);
} }
/** /**
@ -74,22 +84,25 @@ class DatabaseHandlerTest extends TestCase
*/ */
public function testGc(): void public function testGc(): void
{ {
$this->app->instance('config', new Config()); $this->app->instance('config', new Config(['session' => ['lifetime' => 2]])); // 2 days
$this->database->insert("INSERT INTO sessions VALUES ('foo', 'Lorem Ipsum', '2000-01-01 01:00')"); $table = $this->database->getConnection()->table('sessions');
$this->database->insert("INSERT INTO sessions VALUES ('bar', 'Dolor Sit', '3000-01-01 01:00')"); $table
config(['session.lifetime' => 1]); // 1 day ->insert([
['id' => 'id-foo', 'payload' => 'Lorem Ipsum', 'last_activity' => Carbon::now()->subHours(48 + 1)],
['id' => 'id-bar', 'payload' => 'Dolor Sit', 'last_activity' => Carbon::now()],
]);
$handler = new DatabaseHandler($this->database); $handler = new DatabaseHandler($this->database);
// Max lifetime gets overwritten by settings // Max lifetime gets overwritten by settings anyway
$this->assertEquals(1, $handler->gc(0)); $this->assertEquals(1, $handler->gc(42));
$return = $this->database->select('SELECT * FROM sessions'); $return = $table->get();
$this->assertCount(1, $return); $this->assertCount(1, $return);
$return = array_shift($return); $return = $return->first();
$this->assertEquals('bar', $return->id); $this->assertEquals('id-bar', $return->id);
} }
/** /**