Skip to content

Commit

Permalink
FIX AWS SDK PHP DynamoDb StandardSessionConnection handles serialized…
Browse files Browse the repository at this point in the history
… sessions as strings, which is not binary safe

fixes silverstripe#32
  • Loading branch information
dnsl48 committed Jun 27, 2019
1 parent 785c697 commit 38b706f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
50 changes: 50 additions & 0 deletions code/DynamoDbClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace SilverStripe\DynamoDb;

/**
* DynamoDbClient extension that handles sessions as binary strings
*
* @see https://github.com/silverstripe/silverstripe-dynamodb/issues/32
*/
class DynamoDbClient extends \Aws\DynamoDb\DynamoDbClient
{
private $sessionTable;

private $dataAttribute;

public function __construct($sessionTable, ...$args)
{
$this->sessionTable = $sessionTable;
parent::__construct(...$args);
}

public function updateItem($attributes, ...$extra)
{
$this->patchSessionUpdate($attributes);
return parent::updateItem($attributes, ...$extra);
}

/**
* Update the session data type from 'S' to 'B' (from string to binary)
*
* @param mixed &$data Data to be updated in-place
*/
private function patchSessionUpdate(&$data) {
if (!isset($data['TableName']) || $data['TableName'] !== $this->sessionTable) {
return;
}

if (!isset($data['AttributeUpdates'][$this->dataAttribute]['Value']['S'])) {
return;
}

$data['AttributeUpdates'][$this->dataAttribute]['Value']['B'] = $data['AttributeUpdates'][$this->dataAttribute]['Value']['S'];
unset($data['AttributeUpdates'][$this->dataAttribute]['Value']['S']);
}

public function setSessionTableDataAttribute($dataAttribute)
{
$this->dataAttribute = $dataAttribute;
}
}
7 changes: 4 additions & 3 deletions code/Model/DynamoDbSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

namespace SilverStripe\DynamoDb\Model;

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\SessionHandler;
use SilverStripe\DynamoDb\DynamoDbClient;
use SilverStripe\DynamoDb\SessionHandler;
use Aws\DoctrineCacheAdapter;
use Doctrine\Common\Cache\ApcuCache;
use SilverStripe\Core\Config\Config;
Expand Down Expand Up @@ -78,7 +78,8 @@ public static function get()

public function __construct($options, $table)
{
$this->client = new DynamoDbClient(array_merge(['version' => '2012-08-10'], $options));
$this->client = new DynamoDbClient($table, array_merge(['version' => '2012-08-10'], $options));

$this->table = $table;
$this->handler = SessionHandler::fromClient(
$this->client,
Expand Down
32 changes: 32 additions & 0 deletions code/SessionHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace SilverStripe\DynamoDb;

use Aws\DynamoDb\SessionConnectionInterface;
use Aws\DynamoDb\DynamoDbClient;

/**
* The only purpose of this class is to pass session data attribute from SessionConnection to DynamoDbClient
* so that the latter may intercept session table updates intelligently
*
* @see \SilverStripe\DynamoDb\DynamoDbClient
*/
class SessionHandler extends \Aws\DynamoDb\SessionHandler
{
private $connection;

public static function fromClient(DynamoDbClient $client, array $config = [])
{
$handler = parent::fromClient($client, $config);

$client->setSessionTableDataAttribute($handler->connection->getDataAttribute());

return $handler;
}

public function __construct(SessionConnectionInterface $connection)
{
$this->connection = $connection;
parent::__construct($connection);
}
}

0 comments on commit 38b706f

Please sign in to comment.