-
Ben Johnson authored
For Redis instances that require authentication, the current Redis store does not work. So, this commit adds optional support for utilizing the Predis password option. It will pick up the password from the config file and pass it along when it instantiates the Predis client. The test simply checks that adding the password option doesn't break the constructor. Since Predis parameters end up as protected, we can't verify that the instance contains the password.
Ben Johnson authoredFor Redis instances that require authentication, the current Redis store does not work. So, this commit adds optional support for utilizing the Predis password option. It will pick up the password from the config file and pass it along when it instantiates the Predis client. The test simply checks that adding the password option doesn't break the constructor. Since Predis parameters end up as protected, we can't verify that the instance contains the password.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Redis.php 3.19 KiB
<?php
namespace SimpleSAML\Store;
use \SimpleSAML\Configuration;
use \SimpleSAML\Store;
/**
* A data store using Redis to keep the data.
*
* @package SimpleSAMLphp
*/
class Redis extends Store
{
public $redis;
/**
* Initialize the Redis data store.
*/
public function __construct($redis = null)
{
assert($redis === null || is_subclass_of($redis, 'Predis\\Client'));
if (!class_exists('\Predis\Client')) {
throw new \SimpleSAML\Error\CriticalConfigurationError('predis/predis is not available.');
}
if ($redis === null) {
$config = Configuration::getInstance();
$host = $config->getString('store.redis.host', 'localhost');
$port = $config->getInteger('store.redis.port', 6379);
$prefix = $config->getString('store.redis.prefix', 'SimpleSAMLphp');
$password = $config->getString('store.redis.password', '');
$redis = new \Predis\Client(
[
'scheme' => 'tcp',
'host' => $host,
'port' => $port,
] + (!empty($password) ? ['password' => $password] : []),
[
'prefix' => $prefix,
]
);
}
$this->redis = $redis;
}
/**
* Deconstruct the Redis data store.
*/
public function __destruct()
{
if (method_exists($this->redis, 'disconnect')) {
$this->redis->disconnect();
}
}
/**
* Retrieve a value from the data store.
*
* @param string $type The type of the data.
* @param string $key The key to retrieve.
*
* @return mixed|null The value associated with that key, or null if there's no such key.
*/
public function get($type, $key)
{
assert(is_string($type));
assert(is_string($key));
$result = $this->redis->get("{$type}.{$key}");
if ($result === false || $result === null) {
return null;
}
return unserialize($result);
}
/**
* Save a value in the data store.
*
* @param string $type The type of the data.
* @param string $key The key to insert.
* @param mixed $value The value itself.
* @param int|null $expire The expiration time (unix timestamp), or null if it never expires.
*/
public function set($type, $key, $value, $expire = null)
{
assert(is_string($type));
assert(is_string($key));
assert($expire === null || (is_int($expire) && $expire > 2592000));
$serialized = serialize($value);
if ($expire === null) {
$this->redis->set("{$type}.{$key}", $serialized);
} else {
// setex expire time is in seconds (not unix timestamp)
$this->redis->setex("{$type}.{$key}", $expire - time(), $serialized);
}
}
/**
* Delete an entry from the data store.
*
* @param string $type The type of the data
* @param string $key The key to delete.
*/
public function delete($type, $key)
{
assert(is_string($type));
assert(is_string($key));
$this->redis->del("{$type}.{$key}");
}
}